From abbd3502e813b577619dc25bbd939394640c6125 Mon Sep 17 00:00:00 2001 From: "Hanson.xyz Dev" Date: Fri, 28 Nov 2025 17:19:54 -0600 Subject: [PATCH] Phase 6: AIOS security plugin with conservative login lockdown config (10 attempts) --- .../site_analysis/IMPLEMENTATION-PLAN.md | 24 +- db-snapshots/db-snapshot.sql | 266 +- wp-content/aiowps_backups/index.html | 0 .../SECURITY.md | 19 + .../general/wp-security-ajax-data-table.php | 1486 ++++ .../admin/general/wp-security-list-table.php | 1451 +++ .../admin/index.html | 0 .../admin/index.php | 4 + .../admin/wp-security-admin-init.php | 626 ++ .../admin/wp-security-admin-menu.php | 280 + .../admin/wp-security-brute-force-menu.php | 176 + .../admin/wp-security-dashboard-menu.php | 653 ++ .../admin/wp-security-database-menu.php | 408 + .../admin/wp-security-filescan-menu.php | 75 + .../admin/wp-security-filesystem-menu.php | 144 + .../admin/wp-security-firewall-menu.php | 188 + .../wp-security-firewall-setup-notice.php | 646 ++ .../admin/wp-security-list-404.php | 362 + .../admin/wp-security-list-audit.php | 527 ++ .../wp-security-list-comment-spammer-ip.php | 221 + .../admin/wp-security-list-debug.php | 149 + .../admin/wp-security-list-locked-ip.php | 318 + .../wp-security-list-logged-in-users.php | 260 + .../wp-security-list-permanent-blocked-ip.php | 238 + .../wp-security-list-registered-users.php | 355 + .../admin/wp-security-reset-settings.php | 90 + .../admin/wp-security-settings-menu.php | 157 + .../admin/wp-security-spam-menu.php | 93 + .../admin/wp-security-tools-menu.php | 98 + .../admin/wp-security-user-security-menu.php | 296 + .../backups/index.html | 0 .../commands/wp-brute-force-commands.php | 561 ++ .../commands/wp-security-comment-commands.php | 221 + .../wp-security-file-scan-commands.php | 280 + .../commands/wp-security-files-commands.php | 224 + .../wp-security-firewall-commands.php | 787 ++ .../commands/wp-security-ip-commands.php | 133 + .../commands/wp-security-log-commands.php | 345 + .../wp-security-settings-commands.php | 562 ++ .../commands/wp-security-tfa-commands.php | 216 + .../commands/wp-security-tools-commands.php | 253 + .../wp-security-user-security-commands.php | 716 ++ .../family/wp-security-firewall-families.php | 13 + .../wp-security-firewall-family-builder.php | 33 + ...wp-security-firewall-family-collection.php | 49 + .../family/wp-security-firewall-family.php | 86 + .../libs/traits/file-prefix-trait.php | 30 + .../libs/wp-security-firewall-allow-list.php | 84 + .../libs/wp-security-firewall-config.php | 163 + .../libs/wp-security-firewall-constants.php | 213 + .../libs/wp-security-firewall-debug.php | 59 + .../libs/wp-security-firewall-event.php | 51 + .../wp-security-firewall-exit-exception.php | 8 + .../wp-security-firewall-message-store.php | 209 + .../wp-security-firewall-singleton-trait.php | 36 + .../rule/actions/action-exit-trait.php | 18 + .../actions/action-forbid-and-exit-trait.php | 23 + .../rule/actions/action-forbid-trait.php | 17 + .../action-permblock-and-exit-trait.php | 88 + .../action-redirect-and-exit-trait.php | 23 + .../rule/actions/action-redirect-trait.php | 24 + .../rules/6g/rule-block-query-strings-6g.php | 62 + .../rule/rules/6g/rule-block-refs-6g.php | 52 + .../6g/rule-block-request-strings-6g.php | 67 + .../rules/6g/rule-block-user-agents-6g.php | 53 + .../rule/rules/6g/rule-request-method-6g.php | 53 + .../rules/blacklist/rule-ips-blacklist.php | 65 + .../blacklist/rule-user-agent-blacklist.php | 57 + .../bots/rule-ban-post-blank-headers.php | 44 + .../rules/bots/rule-block-fake-googlebots.php | 101 + .../rule-cookie-prevent-bruteforce.php | 98 + .../rule-advanced-character-filter.php | 156 + .../rules/general/rule-bad-query-strings.php | 56 + .../rule/rules/general/rule-block-xmlrpc.php | 44 + .../general/rule-proxy-comment-posting.php | 69 + .../wp-security-firewall-rule-builder.php | 46 + .../rule/wp-security-firewall-rule-utils.php | 31 + .../rule/wp-security-firewall-rule.php | 91 + .../firewall/wp-security-firewall-context.php | 104 + .../firewall/wp-security-firewall-loader.php | 214 + .../firewall/wp-security-firewall-utility.php | 218 + .../classes/firewall/wp-security-firewall.php | 21 + .../wp-security-feature-item-manager.php | 800 ++ .../grade-system/wp-security-feature-item.php | 78 + .../classes/index.html | 0 .../classes/index.php | 4 + .../updraftcentral-wp-security-commands.php | 38 + .../classes/updraftcentral.php | 43 + .../classes/wp-security-abstract-ids.php | 121 + .../classes/wp-security-ajax.php | 253 + .../wp-security-audit-event-handler.php | 159 + .../classes/wp-security-audit-events.php | 641 ++ .../wp-security-audit-text-handler.php | 238 + .../classes/wp-security-base-tasks.php | 43 + .../classes/wp-security-block-bootstrap.php | 207 + .../classes/wp-security-block-file.php | 202 + .../classes/wp-security-block-htaccess.php | 91 + .../classes/wp-security-block-litespeed.php | 29 + .../classes/wp-security-block-muplugin.php | 93 + .../classes/wp-security-block-userini.php | 98 + .../classes/wp-security-block-wpconfig.php | 103 + .../classes/wp-security-blocking.php | 135 + .../classes/wp-security-captcha.php | 941 ++ .../classes/wp-security-cleanup.php | 48 + .../classes/wp-security-commands.php | 423 + .../classes/wp-security-comment.php | 216 + .../classes/wp-security-config.php | 109 + .../wp-security-configure-settings.php | 739 ++ .../classes/wp-security-cronjob-handler.php | 157 + .../wp-security-deactivation-tasks.php | 47 + .../classes/wp-security-debug-logger.php | 100 + .../classes/wp-security-debug.php | 588 ++ .../classes/wp-security-file-scan.php | 381 + ...security-firewall-resource-unavailable.php | 74 + .../classes/wp-security-firewall-resource.php | 53 + .../wp-security-general-init-tasks.php | 1025 +++ .../classes/wp-security-helper.php | 345 + .../classes/wp-security-hibp.php | 83 + .../classes/wp-security-installer.php | 498 ++ .../classes/wp-security-notices.php | 739 ++ ...wp-security-process-renamed-login-page.php | 293 + .../classes/wp-security-reporting.php | 60 + .../classes/wp-security-sender-service.php | 29 + .../classes/wp-security-settings-tasks.php | 126 + .../classes/wp-security-two-factor-login.php | 201 + .../wp-security-uninstallation-tasks.php | 83 + .../classes/wp-security-user-login.php | 1022 +++ .../classes/wp-security-user-registration.php | 100 + .../classes/wp-security-utility-api.php | 121 + .../classes/wp-security-utility-file.php | 522 ++ .../classes/wp-security-utility-firewall.php | 238 + .../classes/wp-security-utility-htaccess.php | 726 ++ .../wp-security-utility-ip-address.php | 220 + .../wp-security-utility-permissions.php | 65 + .../classes/wp-security-utility-ui.php | 129 + .../classes/wp-security-utility.php | 1578 ++++ .../classes/wp-security-wp-footer-content.php | 57 + .../classes/wp-security-wp-loaded-tasks.php | 109 + .../css/index.html | 0 .../css/wp-security-admin-styles.css | 1211 +++ .../css/wp-security-notices.css | 121 + .../css/wp-security-premium-upgrade.css | 241 + .../css/wp-security-site-lockout-page.css | 20 + .../images/aios-plugin-icon.svg | 8 + .../images/error.png | Bin 0 -> 786 bytes .../images/index.html | 0 .../images/info-icon.png | Bin 0 -> 797 bytes .../images/loading.gif | Bin 0 -> 1849 bytes .../images/notices/black_friday.png | Bin 0 -> 4678 bytes .../images/notices/new_year.png | Bin 0 -> 5480 bytes .../images/notices/sale_20.png | Bin 0 -> 5563 bytes .../images/notices/sale_blackfriday.png | Bin 0 -> 53288 bytes .../images/notices/sale_collection.png | Bin 0 -> 57920 bytes .../images/notices/sale_newyear.png | Bin 0 -> 54345 bytes .../images/notices/sale_spring.png | Bin 0 -> 54751 bytes .../images/notices/sale_summer.png | Bin 0 -> 53479 bytes .../images/notices/spring.png | Bin 0 -> 5459 bytes .../images/notices/summer.png | Bin 0 -> 2437 bytes .../images/plugin-icon.png | Bin 0 -> 1704 bytes .../images/plugin-icon2.png | Bin 0 -> 1760 bytes .../images/plugin-logos/aios-icon.png | Bin 0 -> 2605 bytes .../images/plugin-logos/aios-logo.png | Bin 0 -> 5559 bytes .../images/plugin-logos/aios-premium.png | Bin 0 -> 16535 bytes .../images/plugin-logos/aios_logo_wide.svg | 1 + .../easy-updates-manager-logo.png | Bin 0 -> 43451 bytes .../easy-updates-manager-logo.svg | 1 + .../images/plugin-logos/icon-aios-rgb.svg | 1 + .../internal-link-juicer-logo-sm.png | Bin 0 -> 6665 bytes .../internal-link-juicer-logo-sm.svg | 1 + .../images/plugin-logos/updraft-central.png | Bin 0 -> 5139 bytes .../images/plugin-logos/updraft_logo.png | Bin 0 -> 2707 bytes .../plugin-logos/updraftcentral-logo.svg | 1 + .../images/plugin-logos/updraftplus-icon.png | Bin 0 -> 5228 bytes .../images/plugin-logos/updraftplus_logo.png | Bin 0 -> 2177 bytes .../images/plugin-logos/updraftplus_logo.svg | 1 + .../images/plugin-logos/wp-optimize-icon.png | Bin 0 -> 6094 bytes .../images/plugin-logos/wp-optimize.png | Bin 0 -> 7693 bytes .../images/plugin-logos/wp-optimize.svg | 1 + .../images/plugin-logos/wp-overnight-sm.png | Bin 0 -> 8494 bytes .../images/plugin-logos/wpgetapi-sm.png | Bin 0 -> 13620 bytes .../images/shield-info-icon-36.png | Bin 0 -> 4873 bytes .../images/shield-security-icon-36.png | Bin 0 -> 5196 bytes .../images/success.png | Bin 0 -> 3315 bytes .../images/ud_smile.png | Bin 0 -> 2373 bytes .../includes/blockui/jquery.blockUI.js | 620 ++ .../includes/chartjs/Chart.bundle.min.js | 7 + .../includes/chartjs/chartjs-gauge.min.js | 7 + .../simba-tfa/includes/frontend-settings.js | 122 + .../simba-tfa/includes/gutenberg-blocks.js | 19 + .../includes/jquery-qrcode/README.md | 40 + .../includes/jquery-qrcode/jquery-qrcode.js | 2332 +++++ .../jquery-qrcode/jquery-qrcode.min.js | 2 + .../simba-tfa/includes/jquery.blockUI.js | 619 ++ .../simba-tfa/includes/jquery.blockUI.min.js | 14 + .../includes/login-form-integrations.php | 146 + .../includes/simba-tfa/includes/select2.css | 481 + .../includes/simba-tfa/includes/select2.js | 6108 +++++++++++++ .../simba-tfa/includes/select2.min.js | 2 + .../includes/tfa-encryption-muplugin.php | 113 + .../includes/simba-tfa/includes/tfa.js | 361 + .../includes/tfa_admin_icon_16x16.png | Bin 0 -> 3829 bytes .../includes/tfa_admin_icon_32x32.png | Bin 0 -> 6917 bytes .../simba-tfa/includes/tfa_frontend.php | 216 + .../includes/simba-tfa/includes/totp.js | 101 + .../includes/simba-tfa/includes/users.css | 13 + .../providers/totp/Base32/Base32.php | 225 + .../providers/totp/hotp-php-master/LICENSE | 24 + .../totp/hotp-php-master/README.markdown | 27 + .../totp/hotp-php-master/example.php | 160 + .../providers/totp/hotp-php-master/hotp.php | 174 + .../simba-tfa/providers/totp/loader.php | 1034 +++ .../includes/simba-tfa/simba-tfa.php | 1722 ++++ .../simba-tfa/templates/admin-settings.php | 214 + .../templates/settings-intro-notices.php | 30 + .../templates/shortcode-tfa-user-settings.php | 29 + .../templates/trusted-devices-inner-box.php | 29 + .../simba-tfa/templates/user-settings.php | 62 + .../index.html | 0 .../js/index.html | 0 .../js/password-strength-tool.js | 137 + .../js/remove-weak-pw.js | 4 + .../js/wp-security-admin-script.js | 1846 ++++ .../js/wp-security-front-script.js | 32 + ...l-in-one-wp-security-and-firewall-fr_FR.mo | Bin 0 -> 119574 bytes ...l-in-one-wp-security-and-firewall-fr_FR.po | 5991 +++++++++++++ ...l-in-one-wp-security-and-firewall-hu_HU.mo | Bin 0 -> 1933 bytes ...l-in-one-wp-security-and-firewall-hu_HU.po | 5991 +++++++++++++ ...l-in-one-wp-security-and-firewall-ko_KR.mo | Bin 0 -> 69308 bytes ...l-in-one-wp-security-and-firewall-ko_KR.po | 6253 +++++++++++++ ...l-in-one-wp-security-and-firewall-pl_PL.mo | Bin 0 -> 1380 bytes ...l-in-one-wp-security-and-firewall-pl_PL.po | 6015 +++++++++++++ ...l-in-one-wp-security-and-firewall-pt_BR.mo | Bin 0 -> 136583 bytes ...l-in-one-wp-security-and-firewall-pt_BR.po | 5994 +++++++++++++ ...l-in-one-wp-security-and-firewall-sv_SE.mo | Bin 0 -> 3388 bytes ...l-in-one-wp-security-and-firewall-sv_SE.po | 5992 +++++++++++++ ...l-in-one-wp-security-and-firewall-zh_CN.mo | Bin 0 -> 27377 bytes ...l-in-one-wp-security-and-firewall-zh_CN.po | 6152 +++++++++++++ .../all-in-one-wp-security-and-firewall.pot | 7895 +++++++++++++++++ .../languages/index.html | 0 .../lib/index.html | 0 .../license.txt | 674 ++ .../logs/index.html | 0 .../logs/wp-security-log-cron-job.txt | 0 .../logs/wp-security-log.txt | 0 .../other-includes/index.html | 0 ...-security-rename-login-feature-pre-5-2.php | 1138 +++ ...-security-rename-login-feature-pre-5-7.php | 1545 ++++ ...-security-rename-login-feature-pre-6-6.php | 1537 ++++ .../wp-security-rename-login-feature.php | 1674 ++++ .../wp-security-stop-users-enumeration.php | 10 + .../wp-security-unlock-request.php | 114 + .../wp-security-visitor-lockout-page.php | 31 + .../readme.txt | 1649 ++++ .../templates/admin/incompatible-plugin.php | 20 + .../info/ip-address-ip-range-info.php | 16 + ...-based-brute-force-prevention-disabled.php | 9 + .../templates/notices/custom-notice.php | 39 + .../notices/disable-login-whitelist.php | 8 + .../notices/firewall-installed-notice.php | 9 + .../notices/firewall-setup-notice.php | 33 + .../templates/notices/horizontal-notice.php | 104 + .../htaccess-to-php-feature-notice.php | 43 + .../notices/thanks-for-using-main-dash.php | 84 + .../partials/non-apache-feature-notice.php | 16 + .../wp-admin/brute-force/404-detection.php | 130 + .../wp-admin/brute-force/captcha-provider.php | 93 + .../wp-admin/brute-force/captcha-settings.php | 64 + .../cookie-based-brute-force-prevention.php | 165 + .../wp-admin/brute-force/honeypot.php | 51 + .../wp-admin/brute-force/login-whitelist.php | 66 + .../partials/cookie-test-container.php | 11 + .../brute-force/partials/other-plugins.php | 74 + .../partials/rename-login-notice.php | 10 + .../brute-force/partials/woo-captcha.php | 85 + .../brute-force/partials/wordpress-forms.php | 114 + .../wp-admin/brute-force/rename-login.php | 55 + .../wp-admin/dashboard/audit-logs.php | 18 + .../wp-admin/dashboard/debug-logs.php | 44 + .../wp-admin/dashboard/locked-ip.php | 28 + .../wp-admin/dashboard/may-also-like.php | 398 + .../wp-admin/dashboard/permanent-block.php | 27 + .../wp-admin/dashboard/widget-bar-chart.php | 47 + .../wp-admin/dashboard/widget-summary.php | 29 + .../database-security/database-backup.php | 41 + .../database-security/database-prefix.php | 58 + .../filesystem-security/copy-protection.php | 33 + .../filesystem-security/file-permissions.php | 37 + .../filesystem-security/file-protection.php | 62 + .../filesystem-log-result.php | 21 + .../wp-admin/filesystem-security/frames.php | 34 + .../filesystem-security/host-system-logs.php | 29 + .../partials/file-permissions-table.php | 27 + .../partials/php-file-editing.php | 31 + .../partials/prevent-hotlinks.php | 29 + .../partials/wp-file-access.php | 34 + .../templates/wp-admin/firewall/5g.php | 35 + .../wp-admin/firewall/advanced-settings.php | 5 + .../firewall/block-and-allow-lists.php | 87 + .../firewall/htaccess-firewall-rules.php | 58 + .../partials/advanced-character-filter.php | 31 + .../partials/advanced-settings-6g.php | 70 + .../wp-admin/firewall/partials/allowlist.php | 19 + .../firewall/partials/bad-query-strings.php | 30 + .../partials/basic-firewall-settings.php | 42 + .../partials/blank-ref-and-useragent.php | 27 + .../firewall/partials/block-debug-log.php | 30 + .../firewall/partials/disable-rss-atom.php | 30 + .../firewall/partials/disable-trace.php | 34 + .../firewall/partials/fake-googlebots.php | 44 + .../partials/firewall-downgrade-button.php | 5 + .../partials/firewall-set-up-button.php | 5 + .../firewall/partials/firewall-setup.php | 30 + .../firewall/partials/internet-bots.php | 23 + .../partials/listing-directory-contents.php | 34 + .../wp-admin/firewall/partials/ng.php | 56 + .../firewall/partials/proxy-comment.php | 30 + .../partials/rest-route-whitelist.php | 21 + .../partials/upgrade-unsafe-http-calls.php | 48 + .../firewall/partials/wp-rest-api.php | 59 + .../partials/xmlrpc-pingback-protection.php | 52 + .../partials/xmlrpc-warning-notice.php | 11 + .../wp-admin/firewall/php-firewall-rules.php | 81 + .../templates/wp-admin/general/moved.php | 28 + .../wp-admin/scanner/file-change-detect.php | 148 + .../wp-admin/scanner/malware-scan.php | 25 + .../wp-admin/scanner/scan-result.php | 42 + .../wp-admin/settings/advanced-settings.php | 223 + .../settings/delete-plugin-settings.php | 41 + .../wp-admin/settings/general-settings.php | 116 + .../settings/htaccess-file-operations.php | 37 + .../settings/settings-file-operations.php | 45 + .../settings/wp-config-file-operations.php | 47 + .../wp-admin/settings/wp-version-info.php | 38 + .../comment-spam-ip-monitoring.php | 116 + .../wp-admin/spam-prevention/comment-spam.php | 99 + .../wp-admin/tools/custom-htaccess.php | 58 + .../tools/partials/who-is-lookup-result.php | 13 + .../wp-admin/tools/password-tool.php | 30 + .../wp-admin/tools/visitor-lockout.php | 43 + .../templates/wp-admin/tools/whois-lookup.php | 24 + .../wp-admin/user-security/additional.php | 32 + .../wp-admin/user-security/force-logout.php | 40 + .../templates/wp-admin/user-security/hibp.php | 35 + .../user-security/http-authentication.php | 104 + .../user-security/logged-in-users.php | 31 + .../wp-admin/user-security/login-lockout.php | 188 + .../user-security/manual-approval.php | 57 + .../user-security/partials/display-name.php | 41 + .../partials/enforce-strong-password.php | 28 + .../partials/user-enumeration.php | 29 + .../partials/wp-username-content.php | 26 + .../user-security/partials/wp-username.php | 38 + .../templates/wp-admin/user-security/salt.php | 53 + .../wp-admin/user-security/user-accounts.php | 16 + .../vendor/autoload.php | 25 + .../vendor/composer/ClassLoader.php | 579 ++ .../vendor/composer/InstalledVersions.php | 378 + .../vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 10 + .../vendor/composer/autoload_namespaces.php | 9 + .../vendor/composer/autoload_psr4.php | 10 + .../vendor/composer/autoload_real.php | 36 + .../vendor/composer/autoload_static.php | 36 + .../vendor/composer/installed.json | 135 + .../vendor/composer/installed.php | 50 + .../vendor/mlocati/ip-lib/LICENSE.txt | 20 + .../vendor/mlocati/ip-lib/README.md | 823 ++ .../vendor/mlocati/ip-lib/composer.json | 60 + .../vendor/mlocati/ip-lib/ip-lib.php | 13 + .../ip-lib/src/Address/AddressInterface.php | 185 + .../ip-lib/src/Address/AssignedRange.php | 140 + .../mlocati/ip-lib/src/Address/IPv4.php | 582 ++ .../mlocati/ip-lib/src/Address/IPv6.php | 679 ++ .../mlocati/ip-lib/src/Address/Type.php | 44 + .../vendor/mlocati/ip-lib/src/Factory.php | 342 + .../mlocati/ip-lib/src/ParseStringFlag.php | 79 + .../ip-lib/src/Range/AbstractRange.php | 188 + .../mlocati/ip-lib/src/Range/Pattern.php | 354 + .../ip-lib/src/Range/RangeInterface.php | 198 + .../mlocati/ip-lib/src/Range/Single.php | 266 + .../mlocati/ip-lib/src/Range/Subnet.php | 373 + .../vendor/mlocati/ip-lib/src/Range/Type.php | 152 + .../mlocati/ip-lib/src/Service/BinaryMath.php | 246 + .../ip-lib/src/Service/NumberInChunks.php | 254 + .../Service/RangesFromBoundaryCalculator.php | 175 + .../src/Service/UnsignedIntegerMath.php | 173 + .../common-libs/CI/php-compatibility.xml | 17 + .../common-libs/CI/php-syntax-check.xml | 12 + .../vendor/team-updraft/common-libs/README.md | 10 + .../team-updraft/common-libs/composer.json | 21 + .../src/updraft-notices/updraft-notices.php | 220 + .../src/updraft-rpc/class-udrpc.php | 1127 +++ .../class-updraft-semaphore.php | 213 + .../src/updraft-semaphore/test.php | 56 + .../class-updraft-task-manager-commands.php | 188 + .../class-updraft-task-manager.php | 349 + .../updraft-tasks/class-updraft-task-meta.php | 96 + .../class-updraft-task-options.php | 127 + .../src/updraft-tasks/class-updraft-task.php | 746 ++ .../class-updraft-tasks-activation.php | 303 + .../vendor/team-updraft/lib-central/README.md | 93 + .../lib-central/central/bootstrap.php | 851 ++ .../automatic-upgrader-skin-compatibility.php | 10 + .../classes/class-automatic-upgrader-skin.php | 126 + .../class-updraftcentral-wp-upgrader.php | 49 + .../lib-central/central/commands.php | 366 + .../lib-central/central/css/central.css | 57 + .../lib-central/central/factory.php | 81 + .../team-updraft/lib-central/central/host.php | 311 + .../lib-central/central/images/ud-logo.png | Bin 0 -> 6789 bytes .../central/images/udlogo-rotating.gif | Bin 0 -> 7113 bytes .../lib-central/central/js/central.js | 436 + .../lib-central/central/listener.php | 372 + .../lib-central/central/modules/analytics.php | 440 + .../lib-central/central/modules/backups.php | 391 + .../lib-central/central/modules/comments.php | 842 ++ .../lib-central/central/modules/core.php | 508 ++ .../lib-central/central/modules/media.php | 601 ++ .../lib-central/central/modules/pages.php | 15 + .../lib-central/central/modules/plugin.php | 700 ++ .../lib-central/central/modules/posts.php | 2034 +++++ .../lib-central/central/modules/theme.php | 721 ++ .../lib-central/central/modules/updates.php | 1028 +++ .../lib-central/central/modules/users.php | 632 ++ .../central/translations-central.php | 99 + .../lib-central/central/updraftplus.php | 282 + .../lib-central/central/wp-optimize.php | 156 + .../team-updraft/lib-central/composer.json | 4 + .../wp-security-core.php | 699 ++ .../wp-security.php | 87 + 430 files changed, 137111 insertions(+), 7 deletions(-) create mode 100644 wp-content/aiowps_backups/index.html create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/SECURITY.md create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/general/wp-security-ajax-data-table.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/general/wp-security-list-table.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/index.html create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/index.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-admin-init.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-admin-menu.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-brute-force-menu.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-dashboard-menu.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-database-menu.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-filescan-menu.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-filesystem-menu.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-firewall-menu.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-firewall-setup-notice.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-404.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-audit.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-comment-spammer-ip.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-debug.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-locked-ip.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-logged-in-users.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-permanent-blocked-ip.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-registered-users.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-reset-settings.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-settings-menu.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-spam-menu.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-tools-menu.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-user-security-menu.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/backups/index.html create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-brute-force-commands.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-comment-commands.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-file-scan-commands.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-files-commands.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-firewall-commands.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-ip-commands.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-log-commands.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-settings-commands.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-tfa-commands.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-tools-commands.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-user-security-commands.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/family/wp-security-firewall-families.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/family/wp-security-firewall-family-builder.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/family/wp-security-firewall-family-collection.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/family/wp-security-firewall-family.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/traits/file-prefix-trait.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-allow-list.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-config.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-constants.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-debug.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-event.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-exit-exception.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-message-store.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-singleton-trait.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/actions/action-exit-trait.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/actions/action-forbid-and-exit-trait.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/actions/action-forbid-trait.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/actions/action-permblock-and-exit-trait.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/actions/action-redirect-and-exit-trait.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/actions/action-redirect-trait.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-block-query-strings-6g.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-block-refs-6g.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-block-request-strings-6g.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-block-user-agents-6g.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-request-method-6g.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/blacklist/rule-ips-blacklist.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/blacklist/rule-user-agent-blacklist.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/bots/rule-ban-post-blank-headers.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/bots/rule-block-fake-googlebots.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/bruteforce/rule-cookie-prevent-bruteforce.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/general/rule-advanced-character-filter.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/general/rule-bad-query-strings.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/general/rule-block-xmlrpc.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/general/rule-proxy-comment-posting.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/wp-security-firewall-rule-builder.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/wp-security-firewall-rule-utils.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/wp-security-firewall-rule.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/wp-security-firewall-context.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/wp-security-firewall-loader.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/wp-security-firewall-utility.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/wp-security-firewall.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/grade-system/wp-security-feature-item-manager.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/grade-system/wp-security-feature-item.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/index.html create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/index.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/updraftcentral-wp-security-commands.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/updraftcentral.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-abstract-ids.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-ajax.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-audit-event-handler.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-audit-events.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-audit-text-handler.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-base-tasks.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-bootstrap.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-file.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-htaccess.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-litespeed.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-muplugin.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-userini.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-wpconfig.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-blocking.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-captcha.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-cleanup.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-commands.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-comment.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-config.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-configure-settings.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-cronjob-handler.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-deactivation-tasks.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-debug-logger.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-debug.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-file-scan.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-firewall-resource-unavailable.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-firewall-resource.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-general-init-tasks.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-helper.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-hibp.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-installer.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-notices.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-process-renamed-login-page.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-reporting.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-sender-service.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-settings-tasks.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-two-factor-login.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-uninstallation-tasks.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-user-login.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-user-registration.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-api.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-file.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-firewall.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-htaccess.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-ip-address.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-permissions.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-ui.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-wp-footer-content.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-wp-loaded-tasks.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/css/index.html create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/css/wp-security-admin-styles.css create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/css/wp-security-notices.css create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/css/wp-security-premium-upgrade.css create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/css/wp-security-site-lockout-page.css create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/aios-plugin-icon.svg create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/error.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/index.html create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/info-icon.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/loading.gif create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/black_friday.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/new_year.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/sale_20.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/sale_blackfriday.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/sale_collection.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/sale_newyear.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/sale_spring.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/sale_summer.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/spring.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/summer.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-icon.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-icon2.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/aios-icon.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/aios-logo.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/aios-premium.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/aios_logo_wide.svg create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/easy-updates-manager-logo.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/easy-updates-manager-logo.svg create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/icon-aios-rgb.svg create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/internal-link-juicer-logo-sm.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/internal-link-juicer-logo-sm.svg create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/updraft-central.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/updraft_logo.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/updraftcentral-logo.svg create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/updraftplus-icon.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/updraftplus_logo.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/updraftplus_logo.svg create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/wp-optimize-icon.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/wp-optimize.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/wp-optimize.svg create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/wp-overnight-sm.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/wpgetapi-sm.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/shield-info-icon-36.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/shield-security-icon-36.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/success.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/images/ud_smile.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/blockui/jquery.blockUI.js create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/chartjs/Chart.bundle.min.js create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/chartjs/chartjs-gauge.min.js create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/frontend-settings.js create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/gutenberg-blocks.js create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery-qrcode/README.md create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery-qrcode/jquery-qrcode.js create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery-qrcode/jquery-qrcode.min.js create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery.blockUI.js create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery.blockUI.min.js create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/login-form-integrations.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/select2.css create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/select2.js create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/select2.min.js create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/tfa-encryption-muplugin.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/tfa.js create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/tfa_admin_icon_16x16.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/tfa_admin_icon_32x32.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/tfa_frontend.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/totp.js create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/users.css create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/Base32/Base32.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/hotp-php-master/LICENSE create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/hotp-php-master/README.markdown create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/hotp-php-master/example.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/hotp-php-master/hotp.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/loader.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/simba-tfa.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/templates/admin-settings.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/templates/settings-intro-notices.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/templates/shortcode-tfa-user-settings.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/templates/trusted-devices-inner-box.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/templates/user-settings.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/index.html create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/js/index.html create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/js/password-strength-tool.js create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/js/remove-weak-pw.js create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/js/wp-security-admin-script.js create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/js/wp-security-front-script.js create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-fr_FR.mo create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-fr_FR.po create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-hu_HU.mo create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-hu_HU.po create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-ko_KR.mo create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-ko_KR.po create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-pl_PL.mo create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-pl_PL.po create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-pt_BR.mo create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-pt_BR.po create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-sv_SE.mo create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-sv_SE.po create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-zh_CN.mo create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-zh_CN.po create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall.pot create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/languages/index.html create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/lib/index.html create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/license.txt create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/logs/index.html create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/logs/wp-security-log-cron-job.txt create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/logs/wp-security-log.txt create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/other-includes/index.html create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/other-includes/wp-security-rename-login-feature-pre-5-2.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/other-includes/wp-security-rename-login-feature-pre-5-7.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/other-includes/wp-security-rename-login-feature-pre-6-6.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/other-includes/wp-security-rename-login-feature.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/other-includes/wp-security-stop-users-enumeration.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/other-includes/wp-security-unlock-request.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/other-includes/wp-security-visitor-lockout-page.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/readme.txt create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/admin/incompatible-plugin.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/info/ip-address-ip-range-info.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/notices/cookie-based-brute-force-prevention-disabled.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/notices/custom-notice.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/notices/disable-login-whitelist.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/notices/firewall-installed-notice.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/notices/firewall-setup-notice.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/notices/horizontal-notice.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/notices/htaccess-to-php-feature-notice.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/notices/thanks-for-using-main-dash.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/partials/non-apache-feature-notice.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/404-detection.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/captcha-provider.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/captcha-settings.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/honeypot.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/login-whitelist.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/partials/cookie-test-container.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/partials/other-plugins.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/partials/rename-login-notice.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/partials/woo-captcha.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/partials/wordpress-forms.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/rename-login.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/audit-logs.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/debug-logs.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/locked-ip.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/may-also-like.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/permanent-block.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/widget-bar-chart.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/widget-summary.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/database-security/database-backup.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/database-security/database-prefix.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/copy-protection.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/file-permissions.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/file-protection.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/filesystem-log-result.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/frames.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/host-system-logs.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/partials/file-permissions-table.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/partials/php-file-editing.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/partials/prevent-hotlinks.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/partials/wp-file-access.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/5g.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/advanced-settings.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/block-and-allow-lists.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/htaccess-firewall-rules.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/advanced-character-filter.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/advanced-settings-6g.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/allowlist.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/bad-query-strings.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/basic-firewall-settings.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/blank-ref-and-useragent.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/block-debug-log.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/disable-rss-atom.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/disable-trace.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/fake-googlebots.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/firewall-downgrade-button.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/firewall-set-up-button.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/firewall-setup.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/internet-bots.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/listing-directory-contents.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/ng.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/proxy-comment.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/rest-route-whitelist.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/upgrade-unsafe-http-calls.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/wp-rest-api.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/xmlrpc-warning-notice.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/php-firewall-rules.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/general/moved.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/scanner/file-change-detect.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/scanner/malware-scan.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/scanner/scan-result.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/advanced-settings.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/delete-plugin-settings.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/general-settings.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/htaccess-file-operations.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/settings-file-operations.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/wp-config-file-operations.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/wp-version-info.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/spam-prevention/comment-spam.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/custom-htaccess.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/partials/who-is-lookup-result.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/password-tool.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/visitor-lockout.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/whois-lookup.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/additional.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/force-logout.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/hibp.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/http-authentication.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/logged-in-users.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/login-lockout.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/manual-approval.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/display-name.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/enforce-strong-password.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/user-enumeration.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/wp-username-content.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/wp-username.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/salt.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/user-accounts.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/autoload.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/ClassLoader.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/InstalledVersions.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/LICENSE create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/autoload_classmap.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/autoload_namespaces.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/autoload_psr4.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/autoload_real.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/autoload_static.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/installed.json create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/installed.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/LICENSE.txt create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/README.md create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/composer.json create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/ip-lib.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Address/AddressInterface.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Address/AssignedRange.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Address/IPv4.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Address/IPv6.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Address/Type.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Factory.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/ParseStringFlag.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/AbstractRange.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/Pattern.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/RangeInterface.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/Single.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/Subnet.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/Type.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Service/BinaryMath.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Service/NumberInChunks.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Service/RangesFromBoundaryCalculator.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Service/UnsignedIntegerMath.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/CI/php-compatibility.xml create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/CI/php-syntax-check.xml create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/README.md create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/composer.json create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-notices/updraft-notices.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-rpc/class-udrpc.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-semaphore/class-updraft-semaphore.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-semaphore/test.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-manager-commands.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-manager.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-meta.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-options.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-tasks-activation.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/README.md create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/bootstrap.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/classes/automatic-upgrader-skin-compatibility.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/classes/class-automatic-upgrader-skin.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/classes/class-updraftcentral-wp-upgrader.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/commands.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/css/central.css create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/factory.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/host.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/images/ud-logo.png create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/images/udlogo-rotating.gif create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/js/central.js create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/listener.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/analytics.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/backups.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/comments.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/core.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/media.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/pages.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/plugin.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/posts.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/theme.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/updates.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/users.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/translations-central.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/updraftplus.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/wp-optimize.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/composer.json create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/wp-security-core.php create mode 100755 wp-content/plugins/all-in-one-wp-security-and-firewall/wp-security.php diff --git a/contract/Contracts/WordPress-Website/_scratch/site_analysis/IMPLEMENTATION-PLAN.md b/contract/Contracts/WordPress-Website/_scratch/site_analysis/IMPLEMENTATION-PLAN.md index 05c2d079..dd03a4cb 100644 --- a/contract/Contracts/WordPress-Website/_scratch/site_analysis/IMPLEMENTATION-PLAN.md +++ b/contract/Contracts/WordPress-Website/_scratch/site_analysis/IMPLEMENTATION-PLAN.md @@ -808,11 +808,31 @@ This implementation plan is a draft for review. Please confirm: - Site icon/favicon managed via WordPress Customizer (Appearance > Customize > Site Identity) - Theme color set to #0A0A0A (background dark) for mobile browser chrome -### Phase 6: Performance & Security - PENDING +### Phase 6: Performance & Security - COMPLETED (Partial) +- [x] WebP image conversion via "Converter for Media" plugin +- [x] Nginx rewrite rules for serving WebP to supported browsers +- [x] Server dependencies documented in DEPENDENCIES.md +- [ ] Caching plugin - SKIPPED (not requested) +- [ ] Security plugin - SKIPPED (not requested) +- [ ] Backups plugin - SKIPPED (not requested) + +**Technical Details:** +- Plugin: Converter for Media v6.3.2 +- Conversion method: PHP GD/Imagick (both available, WebP supported) +- WebP files stored in: `/wp-content/uploads-webpc/` +- Nginx serves WebP when browser sends `Accept: image/webp` header +- No external APIs or services used (fully local processing) + +**Files Created:** +- /var/www/html/DEPENDENCIES.md (server dependency documentation) + +**Files Modified:** +- /etc/nginx/sites-available/default (WebP rewrite rules added) + ### Phase 7: Testing & Launch - PENDING --- -*Document Version: 1.4* +*Document Version: 1.5* *Last Updated: November 28, 2025* *Prepared by: Hanson.xyz Development Team* diff --git a/db-snapshots/db-snapshot.sql b/db-snapshots/db-snapshot.sql index 869c10b0..afbe73f5 100644 --- a/db-snapshots/db-snapshot.sql +++ b/db-snapshots/db-snapshot.sql @@ -15,6 +15,261 @@ /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +-- +-- Table structure for table `wp_aiowps_audit_log` +-- + +DROP TABLE IF EXISTS `wp_aiowps_audit_log`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `wp_aiowps_audit_log` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `network_id` bigint NOT NULL DEFAULT '0', + `site_id` bigint NOT NULL DEFAULT '0', + `username` varchar(60) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `ip` varchar(45) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `level` varchar(25) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `event_type` varchar(25) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `details` text COLLATE utf8mb4_unicode_520_ci NOT NULL, + `stacktrace` text COLLATE utf8mb4_unicode_520_ci NOT NULL, + `created` int unsigned DEFAULT NULL, + `country_code` varchar(50) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `username` (`username`), + KEY `ip` (`ip`), + KEY `level` (`level`), + KEY `event_type` (`event_type`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_aiowps_audit_log` +-- + +LOCK TABLES `wp_aiowps_audit_log` WRITE; +/*!40000 ALTER TABLE `wp_aiowps_audit_log` DISABLE KEYS */; +/*!40000 ALTER TABLE `wp_aiowps_audit_log` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_aiowps_debug_log` +-- + +DROP TABLE IF EXISTS `wp_aiowps_debug_log`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `wp_aiowps_debug_log` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `created` datetime NOT NULL DEFAULT '1000-10-10 10:00:00', + `logtime` int unsigned DEFAULT NULL, + `level` varchar(25) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `network_id` bigint NOT NULL DEFAULT '0', + `site_id` bigint NOT NULL DEFAULT '0', + `message` text COLLATE utf8mb4_unicode_520_ci NOT NULL, + `type` varchar(25) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_aiowps_debug_log` +-- + +LOCK TABLES `wp_aiowps_debug_log` WRITE; +/*!40000 ALTER TABLE `wp_aiowps_debug_log` DISABLE KEYS */; +/*!40000 ALTER TABLE `wp_aiowps_debug_log` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_aiowps_events` +-- + +DROP TABLE IF EXISTS `wp_aiowps_events`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `wp_aiowps_events` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `event_type` varchar(150) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `username` varchar(150) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + `user_id` bigint DEFAULT NULL, + `event_date` datetime NOT NULL DEFAULT '1000-10-10 10:00:00', + `created` int unsigned DEFAULT NULL, + `ip_or_host` varchar(100) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + `referer_info` varchar(255) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + `url` varchar(255) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + `country_code` varchar(50) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + `event_data` longtext COLLATE utf8mb4_unicode_520_ci, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_aiowps_events` +-- + +LOCK TABLES `wp_aiowps_events` WRITE; +/*!40000 ALTER TABLE `wp_aiowps_events` DISABLE KEYS */; +/*!40000 ALTER TABLE `wp_aiowps_events` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_aiowps_global_meta` +-- + +DROP TABLE IF EXISTS `wp_aiowps_global_meta`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `wp_aiowps_global_meta` ( + `meta_id` bigint NOT NULL AUTO_INCREMENT, + `date_time` datetime NOT NULL DEFAULT '1000-10-10 10:00:00', + `created` int unsigned DEFAULT NULL, + `meta_key1` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL, + `meta_key2` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL, + `meta_key3` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL, + `meta_key4` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL, + `meta_key5` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL, + `meta_value1` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL, + `meta_value2` text COLLATE utf8mb4_unicode_520_ci NOT NULL, + `meta_value3` text COLLATE utf8mb4_unicode_520_ci NOT NULL, + `meta_value4` longtext COLLATE utf8mb4_unicode_520_ci NOT NULL, + `meta_value5` longtext COLLATE utf8mb4_unicode_520_ci NOT NULL, + PRIMARY KEY (`meta_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_aiowps_global_meta` +-- + +LOCK TABLES `wp_aiowps_global_meta` WRITE; +/*!40000 ALTER TABLE `wp_aiowps_global_meta` DISABLE KEYS */; +/*!40000 ALTER TABLE `wp_aiowps_global_meta` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_aiowps_logged_in_users` +-- + +DROP TABLE IF EXISTS `wp_aiowps_logged_in_users`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `wp_aiowps_logged_in_users` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `user_id` bigint NOT NULL, + `username` varchar(60) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `ip_address` varchar(45) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `site_id` bigint NOT NULL, + `created` int unsigned DEFAULT NULL, + `expires` int unsigned DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `unique_user_id` (`user_id`), + KEY `created` (`created`), + KEY `expires` (`expires`), + KEY `user_id` (`user_id`), + KEY `site_id` (`site_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_aiowps_logged_in_users` +-- + +LOCK TABLES `wp_aiowps_logged_in_users` WRITE; +/*!40000 ALTER TABLE `wp_aiowps_logged_in_users` DISABLE KEYS */; +/*!40000 ALTER TABLE `wp_aiowps_logged_in_users` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_aiowps_login_lockdown` +-- + +DROP TABLE IF EXISTS `wp_aiowps_login_lockdown`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `wp_aiowps_login_lockdown` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `user_id` bigint NOT NULL, + `user_login` varchar(150) COLLATE utf8mb4_unicode_520_ci NOT NULL, + `lockdown_date` datetime NOT NULL DEFAULT '1000-10-10 10:00:00', + `created` int unsigned DEFAULT NULL, + `release_date` datetime NOT NULL DEFAULT '1000-10-10 10:00:00', + `released` int unsigned DEFAULT NULL, + `failed_login_ip` varchar(100) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `lock_reason` varchar(128) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `unlock_key` varchar(128) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `is_lockout_email_sent` tinyint(1) NOT NULL DEFAULT '1', + `backtrace_log` text COLLATE utf8mb4_unicode_520_ci NOT NULL, + `ip_lookup_result` longtext COLLATE utf8mb4_unicode_520_ci, + PRIMARY KEY (`id`), + KEY `failed_login_ip` (`failed_login_ip`), + KEY `is_lockout_email_sent` (`is_lockout_email_sent`), + KEY `unlock_key` (`unlock_key`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_aiowps_login_lockdown` +-- + +LOCK TABLES `wp_aiowps_login_lockdown` WRITE; +/*!40000 ALTER TABLE `wp_aiowps_login_lockdown` DISABLE KEYS */; +/*!40000 ALTER TABLE `wp_aiowps_login_lockdown` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_aiowps_message_store` +-- + +DROP TABLE IF EXISTS `wp_aiowps_message_store`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `wp_aiowps_message_store` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `message_key` text COLLATE utf8mb4_unicode_520_ci NOT NULL, + `message_value` text COLLATE utf8mb4_unicode_520_ci NOT NULL, + `created` int unsigned DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_aiowps_message_store` +-- + +LOCK TABLES `wp_aiowps_message_store` WRITE; +/*!40000 ALTER TABLE `wp_aiowps_message_store` DISABLE KEYS */; +/*!40000 ALTER TABLE `wp_aiowps_message_store` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_aiowps_permanent_block` +-- + +DROP TABLE IF EXISTS `wp_aiowps_permanent_block`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `wp_aiowps_permanent_block` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `blocked_ip` varchar(100) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `block_reason` varchar(128) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `country_origin` varchar(50) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `blocked_date` datetime NOT NULL DEFAULT '1000-10-10 10:00:00', + `created` int unsigned DEFAULT NULL, + `unblock` tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + KEY `blocked_ip` (`blocked_ip`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_aiowps_permanent_block` +-- + +LOCK TABLES `wp_aiowps_permanent_block` WRITE; +/*!40000 ALTER TABLE `wp_aiowps_permanent_block` DISABLE KEYS */; +/*!40000 ALTER TABLE `wp_aiowps_permanent_block` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `wp_commentmeta` -- @@ -134,7 +389,7 @@ CREATE TABLE `wp_options` ( PRIMARY KEY (`option_id`), UNIQUE KEY `option_name` (`option_name`), KEY `autoload` (`autoload`) -) ENGINE=InnoDB AUTO_INCREMENT=179 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +) ENGINE=InnoDB AUTO_INCREMENT=185 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -143,7 +398,7 @@ CREATE TABLE `wp_options` ( LOCK TABLES `wp_options` WRITE; /*!40000 ALTER TABLE `wp_options` DISABLE KEYS */; -INSERT INTO `wp_options` VALUES (1,'cron','a:10:{i:1764363747;a:1:{s:32:\"recovery_mode_clean_expired_keys\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:5:\"daily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:86400;}}}i:1764363748;a:1:{s:34:\"wp_privacy_delete_old_export_files\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:6:\"hourly\";s:4:\"args\";a:0:{}s:8:\"interval\";i:3600;}}}i:1764367344;a:1:{s:16:\"wp_version_check\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:10:\"twicedaily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:43200;}}}i:1764369115;a:1:{s:30:\"wp_delete_temp_updater_backups\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:6:\"weekly\";s:4:\"args\";a:0:{}s:8:\"interval\";i:604800;}}}i:1764369116;a:1:{s:27:\"acf_update_site_health_data\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:6:\"weekly\";s:4:\"args\";a:0:{}s:8:\"interval\";i:604800;}}}i:1764369144;a:1:{s:17:\"wp_update_plugins\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:10:\"twicedaily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:43200;}}}i:1764370944;a:1:{s:16:\"wp_update_themes\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:10:\"twicedaily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:43200;}}}i:1764371307;a:1:{s:31:\"wpseo_permalink_structure_check\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:5:\"daily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:86400;}}}i:1764450148;a:1:{s:30:\"wp_site_health_scheduled_check\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:6:\"weekly\";s:4:\"args\";a:0:{}s:8:\"interval\";i:604800;}}}s:7:\"version\";i:2;}','on'),(2,'siteurl','https://homeproz.dev.hanson.xyz','on'),(3,'home','https://homeproz.dev.hanson.xyz','on'),(4,'blogname','HomeProz','on'),(5,'blogdescription','','on'),(6,'users_can_register','0','on'),(7,'admin_email','brian@hanson.xyz','on'),(8,'start_of_week','1','on'),(9,'use_balanceTags','0','on'),(10,'use_smilies','1','on'),(11,'require_name_email','1','on'),(12,'comments_notify','1','on'),(13,'posts_per_rss','10','on'),(14,'rss_use_excerpt','0','on'),(15,'mailserver_url','mail.example.com','on'),(16,'mailserver_login','login@example.com','on'),(17,'mailserver_pass','','on'),(18,'mailserver_port','110','on'),(19,'default_category','1','on'),(20,'default_comment_status','open','on'),(21,'default_ping_status','open','on'),(22,'default_pingback_flag','1','on'),(23,'posts_per_page','10','on'),(24,'date_format','F j, Y','on'),(25,'time_format','g:i a','on'),(26,'links_updated_date_format','F j, Y g:i a','on'),(27,'comment_moderation','0','on'),(28,'moderation_notify','1','on'),(29,'permalink_structure','/%postname%/','on'),(30,'rewrite_rules','a:133:{s:11:\"^wp-json/?$\";s:22:\"index.php?rest_route=/\";s:14:\"^wp-json/(.*)?\";s:33:\"index.php?rest_route=/$matches[1]\";s:21:\"^index.php/wp-json/?$\";s:22:\"index.php?rest_route=/\";s:24:\"^index.php/wp-json/(.*)?\";s:33:\"index.php?rest_route=/$matches[1]\";s:17:\"^wp-sitemap\\.xml$\";s:23:\"index.php?sitemap=index\";s:17:\"^wp-sitemap\\.xsl$\";s:36:\"index.php?sitemap-stylesheet=sitemap\";s:23:\"^wp-sitemap-index\\.xsl$\";s:34:\"index.php?sitemap-stylesheet=index\";s:48:\"^wp-sitemap-([a-z]+?)-([a-z\\d_-]+?)-(\\d+?)\\.xml$\";s:75:\"index.php?sitemap=$matches[1]&sitemap-subtype=$matches[2]&paged=$matches[3]\";s:34:\"^wp-sitemap-([a-z]+?)-(\\d+?)\\.xml$\";s:47:\"index.php?sitemap=$matches[1]&paged=$matches[2]\";s:13:\"properties/?$\";s:28:\"index.php?post_type=property\";s:43:\"properties/feed/(feed|rdf|rss|rss2|atom)/?$\";s:45:\"index.php?post_type=property&feed=$matches[1]\";s:38:\"properties/(feed|rdf|rss|rss2|atom)/?$\";s:45:\"index.php?post_type=property&feed=$matches[1]\";s:30:\"properties/page/([0-9]{1,})/?$\";s:46:\"index.php?post_type=property&paged=$matches[1]\";s:47:\"category/(.+?)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:52:\"index.php?category_name=$matches[1]&feed=$matches[2]\";s:42:\"category/(.+?)/(feed|rdf|rss|rss2|atom)/?$\";s:52:\"index.php?category_name=$matches[1]&feed=$matches[2]\";s:23:\"category/(.+?)/embed/?$\";s:46:\"index.php?category_name=$matches[1]&embed=true\";s:35:\"category/(.+?)/page/?([0-9]{1,})/?$\";s:53:\"index.php?category_name=$matches[1]&paged=$matches[2]\";s:17:\"category/(.+?)/?$\";s:35:\"index.php?category_name=$matches[1]\";s:44:\"tag/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:42:\"index.php?tag=$matches[1]&feed=$matches[2]\";s:39:\"tag/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:42:\"index.php?tag=$matches[1]&feed=$matches[2]\";s:20:\"tag/([^/]+)/embed/?$\";s:36:\"index.php?tag=$matches[1]&embed=true\";s:32:\"tag/([^/]+)/page/?([0-9]{1,})/?$\";s:43:\"index.php?tag=$matches[1]&paged=$matches[2]\";s:14:\"tag/([^/]+)/?$\";s:25:\"index.php?tag=$matches[1]\";s:45:\"type/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:50:\"index.php?post_format=$matches[1]&feed=$matches[2]\";s:40:\"type/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:50:\"index.php?post_format=$matches[1]&feed=$matches[2]\";s:21:\"type/([^/]+)/embed/?$\";s:44:\"index.php?post_format=$matches[1]&embed=true\";s:33:\"type/([^/]+)/page/?([0-9]{1,})/?$\";s:51:\"index.php?post_format=$matches[1]&paged=$matches[2]\";s:15:\"type/([^/]+)/?$\";s:33:\"index.php?post_format=$matches[1]\";s:38:\"properties/[^/]+/attachment/([^/]+)/?$\";s:32:\"index.php?attachment=$matches[1]\";s:48:\"properties/[^/]+/attachment/([^/]+)/trackback/?$\";s:37:\"index.php?attachment=$matches[1]&tb=1\";s:68:\"properties/[^/]+/attachment/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:63:\"properties/[^/]+/attachment/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:63:\"properties/[^/]+/attachment/([^/]+)/comment-page-([0-9]{1,})/?$\";s:50:\"index.php?attachment=$matches[1]&cpage=$matches[2]\";s:44:\"properties/[^/]+/attachment/([^/]+)/embed/?$\";s:43:\"index.php?attachment=$matches[1]&embed=true\";s:27:\"properties/([^/]+)/embed/?$\";s:41:\"index.php?property=$matches[1]&embed=true\";s:31:\"properties/([^/]+)/trackback/?$\";s:35:\"index.php?property=$matches[1]&tb=1\";s:51:\"properties/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:47:\"index.php?property=$matches[1]&feed=$matches[2]\";s:46:\"properties/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:47:\"index.php?property=$matches[1]&feed=$matches[2]\";s:39:\"properties/([^/]+)/page/?([0-9]{1,})/?$\";s:48:\"index.php?property=$matches[1]&paged=$matches[2]\";s:46:\"properties/([^/]+)/comment-page-([0-9]{1,})/?$\";s:48:\"index.php?property=$matches[1]&cpage=$matches[2]\";s:35:\"properties/([^/]+)(?:/([0-9]+))?/?$\";s:47:\"index.php?property=$matches[1]&page=$matches[2]\";s:27:\"properties/[^/]+/([^/]+)/?$\";s:32:\"index.php?attachment=$matches[1]\";s:37:\"properties/[^/]+/([^/]+)/trackback/?$\";s:37:\"index.php?attachment=$matches[1]&tb=1\";s:57:\"properties/[^/]+/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:52:\"properties/[^/]+/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:52:\"properties/[^/]+/([^/]+)/comment-page-([0-9]{1,})/?$\";s:50:\"index.php?attachment=$matches[1]&cpage=$matches[2]\";s:33:\"properties/[^/]+/([^/]+)/embed/?$\";s:43:\"index.php?attachment=$matches[1]&embed=true\";s:54:\"property-type/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:52:\"index.php?property_type=$matches[1]&feed=$matches[2]\";s:49:\"property-type/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:52:\"index.php?property_type=$matches[1]&feed=$matches[2]\";s:30:\"property-type/([^/]+)/embed/?$\";s:46:\"index.php?property_type=$matches[1]&embed=true\";s:42:\"property-type/([^/]+)/page/?([0-9]{1,})/?$\";s:53:\"index.php?property_type=$matches[1]&paged=$matches[2]\";s:24:\"property-type/([^/]+)/?$\";s:35:\"index.php?property_type=$matches[1]\";s:56:\"property-status/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:54:\"index.php?property_status=$matches[1]&feed=$matches[2]\";s:51:\"property-status/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:54:\"index.php?property_status=$matches[1]&feed=$matches[2]\";s:32:\"property-status/([^/]+)/embed/?$\";s:48:\"index.php?property_status=$matches[1]&embed=true\";s:44:\"property-status/([^/]+)/page/?([0-9]{1,})/?$\";s:55:\"index.php?property_status=$matches[1]&paged=$matches[2]\";s:26:\"property-status/([^/]+)/?$\";s:37:\"index.php?property_status=$matches[1]\";s:49:\"location/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:56:\"index.php?property_location=$matches[1]&feed=$matches[2]\";s:44:\"location/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:56:\"index.php?property_location=$matches[1]&feed=$matches[2]\";s:25:\"location/([^/]+)/embed/?$\";s:50:\"index.php?property_location=$matches[1]&embed=true\";s:37:\"location/([^/]+)/page/?([0-9]{1,})/?$\";s:57:\"index.php?property_location=$matches[1]&paged=$matches[2]\";s:19:\"location/([^/]+)/?$\";s:39:\"index.php?property_location=$matches[1]\";s:12:\"robots\\.txt$\";s:18:\"index.php?robots=1\";s:13:\"favicon\\.ico$\";s:19:\"index.php?favicon=1\";s:12:\"sitemap\\.xml\";s:24:\"index.php??sitemap=index\";s:48:\".*wp-(atom|rdf|rss|rss2|feed|commentsrss2)\\.php$\";s:18:\"index.php?feed=old\";s:20:\".*wp-app\\.php(/.*)?$\";s:19:\"index.php?error=403\";s:18:\".*wp-register.php$\";s:23:\"index.php?register=true\";s:32:\"feed/(feed|rdf|rss|rss2|atom)/?$\";s:27:\"index.php?&feed=$matches[1]\";s:27:\"(feed|rdf|rss|rss2|atom)/?$\";s:27:\"index.php?&feed=$matches[1]\";s:8:\"embed/?$\";s:21:\"index.php?&embed=true\";s:20:\"page/?([0-9]{1,})/?$\";s:28:\"index.php?&paged=$matches[1]\";s:27:\"comment-page-([0-9]{1,})/?$\";s:39:\"index.php?&page_id=10&cpage=$matches[1]\";s:41:\"comments/feed/(feed|rdf|rss|rss2|atom)/?$\";s:42:\"index.php?&feed=$matches[1]&withcomments=1\";s:36:\"comments/(feed|rdf|rss|rss2|atom)/?$\";s:42:\"index.php?&feed=$matches[1]&withcomments=1\";s:17:\"comments/embed/?$\";s:21:\"index.php?&embed=true\";s:44:\"search/(.+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:40:\"index.php?s=$matches[1]&feed=$matches[2]\";s:39:\"search/(.+)/(feed|rdf|rss|rss2|atom)/?$\";s:40:\"index.php?s=$matches[1]&feed=$matches[2]\";s:20:\"search/(.+)/embed/?$\";s:34:\"index.php?s=$matches[1]&embed=true\";s:32:\"search/(.+)/page/?([0-9]{1,})/?$\";s:41:\"index.php?s=$matches[1]&paged=$matches[2]\";s:14:\"search/(.+)/?$\";s:23:\"index.php?s=$matches[1]\";s:47:\"author/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:50:\"index.php?author_name=$matches[1]&feed=$matches[2]\";s:42:\"author/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:50:\"index.php?author_name=$matches[1]&feed=$matches[2]\";s:23:\"author/([^/]+)/embed/?$\";s:44:\"index.php?author_name=$matches[1]&embed=true\";s:35:\"author/([^/]+)/page/?([0-9]{1,})/?$\";s:51:\"index.php?author_name=$matches[1]&paged=$matches[2]\";s:17:\"author/([^/]+)/?$\";s:33:\"index.php?author_name=$matches[1]\";s:69:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/feed/(feed|rdf|rss|rss2|atom)/?$\";s:80:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&feed=$matches[4]\";s:64:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/(feed|rdf|rss|rss2|atom)/?$\";s:80:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&feed=$matches[4]\";s:45:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/embed/?$\";s:74:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&embed=true\";s:57:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/page/?([0-9]{1,})/?$\";s:81:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&paged=$matches[4]\";s:39:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/?$\";s:63:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]\";s:56:\"([0-9]{4})/([0-9]{1,2})/feed/(feed|rdf|rss|rss2|atom)/?$\";s:64:\"index.php?year=$matches[1]&monthnum=$matches[2]&feed=$matches[3]\";s:51:\"([0-9]{4})/([0-9]{1,2})/(feed|rdf|rss|rss2|atom)/?$\";s:64:\"index.php?year=$matches[1]&monthnum=$matches[2]&feed=$matches[3]\";s:32:\"([0-9]{4})/([0-9]{1,2})/embed/?$\";s:58:\"index.php?year=$matches[1]&monthnum=$matches[2]&embed=true\";s:44:\"([0-9]{4})/([0-9]{1,2})/page/?([0-9]{1,})/?$\";s:65:\"index.php?year=$matches[1]&monthnum=$matches[2]&paged=$matches[3]\";s:26:\"([0-9]{4})/([0-9]{1,2})/?$\";s:47:\"index.php?year=$matches[1]&monthnum=$matches[2]\";s:43:\"([0-9]{4})/feed/(feed|rdf|rss|rss2|atom)/?$\";s:43:\"index.php?year=$matches[1]&feed=$matches[2]\";s:38:\"([0-9]{4})/(feed|rdf|rss|rss2|atom)/?$\";s:43:\"index.php?year=$matches[1]&feed=$matches[2]\";s:19:\"([0-9]{4})/embed/?$\";s:37:\"index.php?year=$matches[1]&embed=true\";s:31:\"([0-9]{4})/page/?([0-9]{1,})/?$\";s:44:\"index.php?year=$matches[1]&paged=$matches[2]\";s:13:\"([0-9]{4})/?$\";s:26:\"index.php?year=$matches[1]\";s:27:\".?.+?/attachment/([^/]+)/?$\";s:32:\"index.php?attachment=$matches[1]\";s:37:\".?.+?/attachment/([^/]+)/trackback/?$\";s:37:\"index.php?attachment=$matches[1]&tb=1\";s:57:\".?.+?/attachment/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:52:\".?.+?/attachment/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:52:\".?.+?/attachment/([^/]+)/comment-page-([0-9]{1,})/?$\";s:50:\"index.php?attachment=$matches[1]&cpage=$matches[2]\";s:33:\".?.+?/attachment/([^/]+)/embed/?$\";s:43:\"index.php?attachment=$matches[1]&embed=true\";s:16:\"(.?.+?)/embed/?$\";s:41:\"index.php?pagename=$matches[1]&embed=true\";s:20:\"(.?.+?)/trackback/?$\";s:35:\"index.php?pagename=$matches[1]&tb=1\";s:40:\"(.?.+?)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:47:\"index.php?pagename=$matches[1]&feed=$matches[2]\";s:35:\"(.?.+?)/(feed|rdf|rss|rss2|atom)/?$\";s:47:\"index.php?pagename=$matches[1]&feed=$matches[2]\";s:28:\"(.?.+?)/page/?([0-9]{1,})/?$\";s:48:\"index.php?pagename=$matches[1]&paged=$matches[2]\";s:35:\"(.?.+?)/comment-page-([0-9]{1,})/?$\";s:48:\"index.php?pagename=$matches[1]&cpage=$matches[2]\";s:24:\"(.?.+?)(?:/([0-9]+))?/?$\";s:47:\"index.php?pagename=$matches[1]&page=$matches[2]\";s:27:\"[^/]+/attachment/([^/]+)/?$\";s:32:\"index.php?attachment=$matches[1]\";s:37:\"[^/]+/attachment/([^/]+)/trackback/?$\";s:37:\"index.php?attachment=$matches[1]&tb=1\";s:57:\"[^/]+/attachment/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:52:\"[^/]+/attachment/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:52:\"[^/]+/attachment/([^/]+)/comment-page-([0-9]{1,})/?$\";s:50:\"index.php?attachment=$matches[1]&cpage=$matches[2]\";s:33:\"[^/]+/attachment/([^/]+)/embed/?$\";s:43:\"index.php?attachment=$matches[1]&embed=true\";s:16:\"([^/]+)/embed/?$\";s:37:\"index.php?name=$matches[1]&embed=true\";s:20:\"([^/]+)/trackback/?$\";s:31:\"index.php?name=$matches[1]&tb=1\";s:40:\"([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:43:\"index.php?name=$matches[1]&feed=$matches[2]\";s:35:\"([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:43:\"index.php?name=$matches[1]&feed=$matches[2]\";s:28:\"([^/]+)/page/?([0-9]{1,})/?$\";s:44:\"index.php?name=$matches[1]&paged=$matches[2]\";s:35:\"([^/]+)/comment-page-([0-9]{1,})/?$\";s:44:\"index.php?name=$matches[1]&cpage=$matches[2]\";s:24:\"([^/]+)(?:/([0-9]+))?/?$\";s:43:\"index.php?name=$matches[1]&page=$matches[2]\";s:16:\"[^/]+/([^/]+)/?$\";s:32:\"index.php?attachment=$matches[1]\";s:26:\"[^/]+/([^/]+)/trackback/?$\";s:37:\"index.php?attachment=$matches[1]&tb=1\";s:46:\"[^/]+/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:41:\"[^/]+/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:41:\"[^/]+/([^/]+)/comment-page-([0-9]{1,})/?$\";s:50:\"index.php?attachment=$matches[1]&cpage=$matches[2]\";s:22:\"[^/]+/([^/]+)/embed/?$\";s:43:\"index.php?attachment=$matches[1]&embed=true\";}','on'),(31,'hack_file','0','on'),(32,'blog_charset','UTF-8','on'),(33,'moderation_keys','','off'),(34,'active_plugins','a:4:{i:0;s:30:\"advanced-custom-fields/acf.php\";i:1;s:36:\"contact-form-7/wp-contact-form-7.php\";i:2;s:53:\"webp-converter-for-media/webp-converter-for-media.php\";i:3;s:24:\"wordpress-seo/wp-seo.php\";}','on'),(35,'category_base','','on'),(36,'ping_sites','https://rpc.pingomatic.com/','on'),(37,'comment_max_links','2','on'),(38,'gmt_offset','0','on'),(39,'default_email_category','1','on'),(40,'recently_edited','','off'),(41,'template','homeproz','on'),(42,'stylesheet','homeproz','on'),(43,'comment_registration','0','on'),(44,'html_type','text/html','on'),(45,'use_trackback','0','on'),(46,'default_role','subscriber','on'),(47,'db_version','60421','on'),(48,'uploads_use_yearmonth_folders','1','on'),(49,'upload_path','','on'),(50,'blog_public','1','on'),(51,'default_link_category','2','on'),(52,'show_on_front','page','on'),(53,'tag_base','','on'),(54,'show_avatars','1','on'),(55,'avatar_rating','G','on'),(56,'upload_url_path','','on'),(57,'thumbnail_size_w','150','on'),(58,'thumbnail_size_h','150','on'),(59,'thumbnail_crop','1','on'),(60,'medium_size_w','300','on'),(61,'medium_size_h','300','on'),(62,'avatar_default','mystery','on'),(63,'large_size_w','1024','on'),(64,'large_size_h','1024','on'),(65,'image_default_link_type','none','on'),(66,'image_default_size','','on'),(67,'image_default_align','','on'),(68,'close_comments_for_old_posts','0','on'),(69,'close_comments_days_old','14','on'),(70,'thread_comments','1','on'),(71,'thread_comments_depth','5','on'),(72,'page_comments','0','on'),(73,'comments_per_page','50','on'),(74,'default_comments_page','newest','on'),(75,'comment_order','asc','on'),(76,'sticky_posts','a:0:{}','on'),(77,'widget_categories','a:0:{}','on'),(78,'widget_text','a:0:{}','on'),(79,'widget_rss','a:0:{}','on'),(80,'uninstall_plugins','a:2:{s:24:\"wordpress-seo/wp-seo.php\";s:14:\"__return_false\";s:53:\"webp-converter-for-media/webp-converter-for-media.php\";a:2:{i:0;s:37:\"WebpConverter\\Plugin\\UninstallHandler\";i:1;s:22:\"load_uninstall_actions\";}}','off'),(81,'timezone_string','','on'),(82,'page_for_posts','9','on'),(83,'page_on_front','10','on'),(84,'default_post_format','0','on'),(85,'link_manager_enabled','0','on'),(86,'finished_splitting_shared_terms','1','on'),(87,'site_icon','0','on'),(88,'medium_large_size_w','768','on'),(89,'medium_large_size_h','0','on'),(90,'wp_page_for_privacy_policy','3','on'),(91,'show_comments_cookies_opt_in','1','on'),(92,'admin_email_lifespan','1779915744','on'),(93,'disallowed_keys','','off'),(94,'comment_previously_approved','1','on'),(95,'auto_plugin_theme_update_emails','a:0:{}','off'),(96,'auto_update_core_dev','enabled','on'),(97,'auto_update_core_minor','enabled','on'),(98,'auto_update_core_major','enabled','on'),(99,'wp_force_deactivated_plugins','a:0:{}','on'),(100,'wp_attachment_pages_enabled','1','on'),(101,'initial_db_version','60421','on'),(102,'wp_user_roles','a:7:{s:13:\"administrator\";a:2:{s:4:\"name\";s:13:\"Administrator\";s:12:\"capabilities\";a:62:{s:13:\"switch_themes\";b:1;s:11:\"edit_themes\";b:1;s:16:\"activate_plugins\";b:1;s:12:\"edit_plugins\";b:1;s:10:\"edit_users\";b:1;s:10:\"edit_files\";b:1;s:14:\"manage_options\";b:1;s:17:\"moderate_comments\";b:1;s:17:\"manage_categories\";b:1;s:12:\"manage_links\";b:1;s:12:\"upload_files\";b:1;s:6:\"import\";b:1;s:15:\"unfiltered_html\";b:1;s:10:\"edit_posts\";b:1;s:17:\"edit_others_posts\";b:1;s:20:\"edit_published_posts\";b:1;s:13:\"publish_posts\";b:1;s:10:\"edit_pages\";b:1;s:4:\"read\";b:1;s:8:\"level_10\";b:1;s:7:\"level_9\";b:1;s:7:\"level_8\";b:1;s:7:\"level_7\";b:1;s:7:\"level_6\";b:1;s:7:\"level_5\";b:1;s:7:\"level_4\";b:1;s:7:\"level_3\";b:1;s:7:\"level_2\";b:1;s:7:\"level_1\";b:1;s:7:\"level_0\";b:1;s:17:\"edit_others_pages\";b:1;s:20:\"edit_published_pages\";b:1;s:13:\"publish_pages\";b:1;s:12:\"delete_pages\";b:1;s:19:\"delete_others_pages\";b:1;s:22:\"delete_published_pages\";b:1;s:12:\"delete_posts\";b:1;s:19:\"delete_others_posts\";b:1;s:22:\"delete_published_posts\";b:1;s:20:\"delete_private_posts\";b:1;s:18:\"edit_private_posts\";b:1;s:18:\"read_private_posts\";b:1;s:20:\"delete_private_pages\";b:1;s:18:\"edit_private_pages\";b:1;s:18:\"read_private_pages\";b:1;s:12:\"delete_users\";b:1;s:12:\"create_users\";b:1;s:17:\"unfiltered_upload\";b:1;s:14:\"edit_dashboard\";b:1;s:14:\"update_plugins\";b:1;s:14:\"delete_plugins\";b:1;s:15:\"install_plugins\";b:1;s:13:\"update_themes\";b:1;s:14:\"install_themes\";b:1;s:11:\"update_core\";b:1;s:10:\"list_users\";b:1;s:12:\"remove_users\";b:1;s:13:\"promote_users\";b:1;s:18:\"edit_theme_options\";b:1;s:13:\"delete_themes\";b:1;s:6:\"export\";b:1;s:20:\"wpseo_manage_options\";b:1;}}s:6:\"editor\";a:2:{s:4:\"name\";s:6:\"Editor\";s:12:\"capabilities\";a:36:{s:17:\"moderate_comments\";b:1;s:17:\"manage_categories\";b:1;s:12:\"manage_links\";b:1;s:12:\"upload_files\";b:1;s:15:\"unfiltered_html\";b:1;s:10:\"edit_posts\";b:1;s:17:\"edit_others_posts\";b:1;s:20:\"edit_published_posts\";b:1;s:13:\"publish_posts\";b:1;s:10:\"edit_pages\";b:1;s:4:\"read\";b:1;s:7:\"level_7\";b:1;s:7:\"level_6\";b:1;s:7:\"level_5\";b:1;s:7:\"level_4\";b:1;s:7:\"level_3\";b:1;s:7:\"level_2\";b:1;s:7:\"level_1\";b:1;s:7:\"level_0\";b:1;s:17:\"edit_others_pages\";b:1;s:20:\"edit_published_pages\";b:1;s:13:\"publish_pages\";b:1;s:12:\"delete_pages\";b:1;s:19:\"delete_others_pages\";b:1;s:22:\"delete_published_pages\";b:1;s:12:\"delete_posts\";b:1;s:19:\"delete_others_posts\";b:1;s:22:\"delete_published_posts\";b:1;s:20:\"delete_private_posts\";b:1;s:18:\"edit_private_posts\";b:1;s:18:\"read_private_posts\";b:1;s:20:\"delete_private_pages\";b:1;s:18:\"edit_private_pages\";b:1;s:18:\"read_private_pages\";b:1;s:15:\"wpseo_bulk_edit\";b:1;s:28:\"wpseo_edit_advanced_metadata\";b:1;}}s:6:\"author\";a:2:{s:4:\"name\";s:6:\"Author\";s:12:\"capabilities\";a:10:{s:12:\"upload_files\";b:1;s:10:\"edit_posts\";b:1;s:20:\"edit_published_posts\";b:1;s:13:\"publish_posts\";b:1;s:4:\"read\";b:1;s:7:\"level_2\";b:1;s:7:\"level_1\";b:1;s:7:\"level_0\";b:1;s:12:\"delete_posts\";b:1;s:22:\"delete_published_posts\";b:1;}}s:11:\"contributor\";a:2:{s:4:\"name\";s:11:\"Contributor\";s:12:\"capabilities\";a:5:{s:10:\"edit_posts\";b:1;s:4:\"read\";b:1;s:7:\"level_1\";b:1;s:7:\"level_0\";b:1;s:12:\"delete_posts\";b:1;}}s:10:\"subscriber\";a:2:{s:4:\"name\";s:10:\"Subscriber\";s:12:\"capabilities\";a:2:{s:4:\"read\";b:1;s:7:\"level_0\";b:1;}}s:13:\"wpseo_manager\";a:2:{s:4:\"name\";s:11:\"SEO Manager\";s:12:\"capabilities\";a:38:{s:17:\"moderate_comments\";b:1;s:17:\"manage_categories\";b:1;s:12:\"manage_links\";b:1;s:12:\"upload_files\";b:1;s:15:\"unfiltered_html\";b:1;s:10:\"edit_posts\";b:1;s:17:\"edit_others_posts\";b:1;s:20:\"edit_published_posts\";b:1;s:13:\"publish_posts\";b:1;s:10:\"edit_pages\";b:1;s:4:\"read\";b:1;s:7:\"level_7\";b:1;s:7:\"level_6\";b:1;s:7:\"level_5\";b:1;s:7:\"level_4\";b:1;s:7:\"level_3\";b:1;s:7:\"level_2\";b:1;s:7:\"level_1\";b:1;s:7:\"level_0\";b:1;s:17:\"edit_others_pages\";b:1;s:20:\"edit_published_pages\";b:1;s:13:\"publish_pages\";b:1;s:12:\"delete_pages\";b:1;s:19:\"delete_others_pages\";b:1;s:22:\"delete_published_pages\";b:1;s:12:\"delete_posts\";b:1;s:19:\"delete_others_posts\";b:1;s:22:\"delete_published_posts\";b:1;s:20:\"delete_private_posts\";b:1;s:18:\"edit_private_posts\";b:1;s:18:\"read_private_posts\";b:1;s:20:\"delete_private_pages\";b:1;s:18:\"edit_private_pages\";b:1;s:18:\"read_private_pages\";b:1;s:15:\"wpseo_bulk_edit\";b:1;s:28:\"wpseo_edit_advanced_metadata\";b:1;s:20:\"wpseo_manage_options\";b:1;s:23:\"view_site_health_checks\";b:1;}}s:12:\"wpseo_editor\";a:2:{s:4:\"name\";s:10:\"SEO Editor\";s:12:\"capabilities\";a:36:{s:17:\"moderate_comments\";b:1;s:17:\"manage_categories\";b:1;s:12:\"manage_links\";b:1;s:12:\"upload_files\";b:1;s:15:\"unfiltered_html\";b:1;s:10:\"edit_posts\";b:1;s:17:\"edit_others_posts\";b:1;s:20:\"edit_published_posts\";b:1;s:13:\"publish_posts\";b:1;s:10:\"edit_pages\";b:1;s:4:\"read\";b:1;s:7:\"level_7\";b:1;s:7:\"level_6\";b:1;s:7:\"level_5\";b:1;s:7:\"level_4\";b:1;s:7:\"level_3\";b:1;s:7:\"level_2\";b:1;s:7:\"level_1\";b:1;s:7:\"level_0\";b:1;s:17:\"edit_others_pages\";b:1;s:20:\"edit_published_pages\";b:1;s:13:\"publish_pages\";b:1;s:12:\"delete_pages\";b:1;s:19:\"delete_others_pages\";b:1;s:22:\"delete_published_pages\";b:1;s:12:\"delete_posts\";b:1;s:19:\"delete_others_posts\";b:1;s:22:\"delete_published_posts\";b:1;s:20:\"delete_private_posts\";b:1;s:18:\"edit_private_posts\";b:1;s:18:\"read_private_posts\";b:1;s:20:\"delete_private_pages\";b:1;s:18:\"edit_private_pages\";b:1;s:18:\"read_private_pages\";b:1;s:15:\"wpseo_bulk_edit\";b:1;s:28:\"wpseo_edit_advanced_metadata\";b:1;}}}','on'),(103,'fresh_site','0','off'),(104,'user_count','1','off'),(105,'widget_block','a:6:{i:2;a:1:{s:7:\"content\";s:19:\"\";}i:3;a:1:{s:7:\"content\";s:154:\"

Recent Posts

\";}i:4;a:1:{s:7:\"content\";s:227:\"

Recent Comments

\";}i:5;a:1:{s:7:\"content\";s:146:\"

Archives

\";}i:6;a:1:{s:7:\"content\";s:150:\"

Categories

\";}s:12:\"_multiwidget\";i:1;}','auto'),(106,'sidebars_widgets','a:2:{s:19:\"wp_inactive_widgets\";a:5:{i:0;s:7:\"block-2\";i:1;s:7:\"block-3\";i:2;s:7:\"block-4\";i:3;s:7:\"block-5\";i:4;s:7:\"block-6\";}s:13:\"array_version\";i:3;}','auto'),(107,'widget_pages','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(108,'widget_calendar','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(109,'widget_archives','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(110,'widget_media_audio','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(111,'widget_media_image','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(112,'widget_media_gallery','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(113,'widget_media_video','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(114,'widget_meta','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(115,'widget_search','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(116,'widget_recent-posts','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(117,'widget_recent-comments','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(118,'widget_tag_cloud','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(119,'widget_nav_menu','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(120,'widget_custom_html','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(121,'_transient_wp_core_block_css_files','a:2:{s:7:\"version\";s:5:\"6.8.3\";s:5:\"files\";a:536:{i:0;s:23:\"archives/editor-rtl.css\";i:1;s:27:\"archives/editor-rtl.min.css\";i:2;s:19:\"archives/editor.css\";i:3;s:23:\"archives/editor.min.css\";i:4;s:22:\"archives/style-rtl.css\";i:5;s:26:\"archives/style-rtl.min.css\";i:6;s:18:\"archives/style.css\";i:7;s:22:\"archives/style.min.css\";i:8;s:20:\"audio/editor-rtl.css\";i:9;s:24:\"audio/editor-rtl.min.css\";i:10;s:16:\"audio/editor.css\";i:11;s:20:\"audio/editor.min.css\";i:12;s:19:\"audio/style-rtl.css\";i:13;s:23:\"audio/style-rtl.min.css\";i:14;s:15:\"audio/style.css\";i:15;s:19:\"audio/style.min.css\";i:16;s:19:\"audio/theme-rtl.css\";i:17;s:23:\"audio/theme-rtl.min.css\";i:18;s:15:\"audio/theme.css\";i:19;s:19:\"audio/theme.min.css\";i:20;s:21:\"avatar/editor-rtl.css\";i:21;s:25:\"avatar/editor-rtl.min.css\";i:22;s:17:\"avatar/editor.css\";i:23;s:21:\"avatar/editor.min.css\";i:24;s:20:\"avatar/style-rtl.css\";i:25;s:24:\"avatar/style-rtl.min.css\";i:26;s:16:\"avatar/style.css\";i:27;s:20:\"avatar/style.min.css\";i:28;s:21:\"button/editor-rtl.css\";i:29;s:25:\"button/editor-rtl.min.css\";i:30;s:17:\"button/editor.css\";i:31;s:21:\"button/editor.min.css\";i:32;s:20:\"button/style-rtl.css\";i:33;s:24:\"button/style-rtl.min.css\";i:34;s:16:\"button/style.css\";i:35;s:20:\"button/style.min.css\";i:36;s:22:\"buttons/editor-rtl.css\";i:37;s:26:\"buttons/editor-rtl.min.css\";i:38;s:18:\"buttons/editor.css\";i:39;s:22:\"buttons/editor.min.css\";i:40;s:21:\"buttons/style-rtl.css\";i:41;s:25:\"buttons/style-rtl.min.css\";i:42;s:17:\"buttons/style.css\";i:43;s:21:\"buttons/style.min.css\";i:44;s:22:\"calendar/style-rtl.css\";i:45;s:26:\"calendar/style-rtl.min.css\";i:46;s:18:\"calendar/style.css\";i:47;s:22:\"calendar/style.min.css\";i:48;s:25:\"categories/editor-rtl.css\";i:49;s:29:\"categories/editor-rtl.min.css\";i:50;s:21:\"categories/editor.css\";i:51;s:25:\"categories/editor.min.css\";i:52;s:24:\"categories/style-rtl.css\";i:53;s:28:\"categories/style-rtl.min.css\";i:54;s:20:\"categories/style.css\";i:55;s:24:\"categories/style.min.css\";i:56;s:19:\"code/editor-rtl.css\";i:57;s:23:\"code/editor-rtl.min.css\";i:58;s:15:\"code/editor.css\";i:59;s:19:\"code/editor.min.css\";i:60;s:18:\"code/style-rtl.css\";i:61;s:22:\"code/style-rtl.min.css\";i:62;s:14:\"code/style.css\";i:63;s:18:\"code/style.min.css\";i:64;s:18:\"code/theme-rtl.css\";i:65;s:22:\"code/theme-rtl.min.css\";i:66;s:14:\"code/theme.css\";i:67;s:18:\"code/theme.min.css\";i:68;s:22:\"columns/editor-rtl.css\";i:69;s:26:\"columns/editor-rtl.min.css\";i:70;s:18:\"columns/editor.css\";i:71;s:22:\"columns/editor.min.css\";i:72;s:21:\"columns/style-rtl.css\";i:73;s:25:\"columns/style-rtl.min.css\";i:74;s:17:\"columns/style.css\";i:75;s:21:\"columns/style.min.css\";i:76;s:33:\"comment-author-name/style-rtl.css\";i:77;s:37:\"comment-author-name/style-rtl.min.css\";i:78;s:29:\"comment-author-name/style.css\";i:79;s:33:\"comment-author-name/style.min.css\";i:80;s:29:\"comment-content/style-rtl.css\";i:81;s:33:\"comment-content/style-rtl.min.css\";i:82;s:25:\"comment-content/style.css\";i:83;s:29:\"comment-content/style.min.css\";i:84;s:26:\"comment-date/style-rtl.css\";i:85;s:30:\"comment-date/style-rtl.min.css\";i:86;s:22:\"comment-date/style.css\";i:87;s:26:\"comment-date/style.min.css\";i:88;s:31:\"comment-edit-link/style-rtl.css\";i:89;s:35:\"comment-edit-link/style-rtl.min.css\";i:90;s:27:\"comment-edit-link/style.css\";i:91;s:31:\"comment-edit-link/style.min.css\";i:92;s:32:\"comment-reply-link/style-rtl.css\";i:93;s:36:\"comment-reply-link/style-rtl.min.css\";i:94;s:28:\"comment-reply-link/style.css\";i:95;s:32:\"comment-reply-link/style.min.css\";i:96;s:30:\"comment-template/style-rtl.css\";i:97;s:34:\"comment-template/style-rtl.min.css\";i:98;s:26:\"comment-template/style.css\";i:99;s:30:\"comment-template/style.min.css\";i:100;s:42:\"comments-pagination-numbers/editor-rtl.css\";i:101;s:46:\"comments-pagination-numbers/editor-rtl.min.css\";i:102;s:38:\"comments-pagination-numbers/editor.css\";i:103;s:42:\"comments-pagination-numbers/editor.min.css\";i:104;s:34:\"comments-pagination/editor-rtl.css\";i:105;s:38:\"comments-pagination/editor-rtl.min.css\";i:106;s:30:\"comments-pagination/editor.css\";i:107;s:34:\"comments-pagination/editor.min.css\";i:108;s:33:\"comments-pagination/style-rtl.css\";i:109;s:37:\"comments-pagination/style-rtl.min.css\";i:110;s:29:\"comments-pagination/style.css\";i:111;s:33:\"comments-pagination/style.min.css\";i:112;s:29:\"comments-title/editor-rtl.css\";i:113;s:33:\"comments-title/editor-rtl.min.css\";i:114;s:25:\"comments-title/editor.css\";i:115;s:29:\"comments-title/editor.min.css\";i:116;s:23:\"comments/editor-rtl.css\";i:117;s:27:\"comments/editor-rtl.min.css\";i:118;s:19:\"comments/editor.css\";i:119;s:23:\"comments/editor.min.css\";i:120;s:22:\"comments/style-rtl.css\";i:121;s:26:\"comments/style-rtl.min.css\";i:122;s:18:\"comments/style.css\";i:123;s:22:\"comments/style.min.css\";i:124;s:20:\"cover/editor-rtl.css\";i:125;s:24:\"cover/editor-rtl.min.css\";i:126;s:16:\"cover/editor.css\";i:127;s:20:\"cover/editor.min.css\";i:128;s:19:\"cover/style-rtl.css\";i:129;s:23:\"cover/style-rtl.min.css\";i:130;s:15:\"cover/style.css\";i:131;s:19:\"cover/style.min.css\";i:132;s:22:\"details/editor-rtl.css\";i:133;s:26:\"details/editor-rtl.min.css\";i:134;s:18:\"details/editor.css\";i:135;s:22:\"details/editor.min.css\";i:136;s:21:\"details/style-rtl.css\";i:137;s:25:\"details/style-rtl.min.css\";i:138;s:17:\"details/style.css\";i:139;s:21:\"details/style.min.css\";i:140;s:20:\"embed/editor-rtl.css\";i:141;s:24:\"embed/editor-rtl.min.css\";i:142;s:16:\"embed/editor.css\";i:143;s:20:\"embed/editor.min.css\";i:144;s:19:\"embed/style-rtl.css\";i:145;s:23:\"embed/style-rtl.min.css\";i:146;s:15:\"embed/style.css\";i:147;s:19:\"embed/style.min.css\";i:148;s:19:\"embed/theme-rtl.css\";i:149;s:23:\"embed/theme-rtl.min.css\";i:150;s:15:\"embed/theme.css\";i:151;s:19:\"embed/theme.min.css\";i:152;s:19:\"file/editor-rtl.css\";i:153;s:23:\"file/editor-rtl.min.css\";i:154;s:15:\"file/editor.css\";i:155;s:19:\"file/editor.min.css\";i:156;s:18:\"file/style-rtl.css\";i:157;s:22:\"file/style-rtl.min.css\";i:158;s:14:\"file/style.css\";i:159;s:18:\"file/style.min.css\";i:160;s:23:\"footnotes/style-rtl.css\";i:161;s:27:\"footnotes/style-rtl.min.css\";i:162;s:19:\"footnotes/style.css\";i:163;s:23:\"footnotes/style.min.css\";i:164;s:23:\"freeform/editor-rtl.css\";i:165;s:27:\"freeform/editor-rtl.min.css\";i:166;s:19:\"freeform/editor.css\";i:167;s:23:\"freeform/editor.min.css\";i:168;s:22:\"gallery/editor-rtl.css\";i:169;s:26:\"gallery/editor-rtl.min.css\";i:170;s:18:\"gallery/editor.css\";i:171;s:22:\"gallery/editor.min.css\";i:172;s:21:\"gallery/style-rtl.css\";i:173;s:25:\"gallery/style-rtl.min.css\";i:174;s:17:\"gallery/style.css\";i:175;s:21:\"gallery/style.min.css\";i:176;s:21:\"gallery/theme-rtl.css\";i:177;s:25:\"gallery/theme-rtl.min.css\";i:178;s:17:\"gallery/theme.css\";i:179;s:21:\"gallery/theme.min.css\";i:180;s:20:\"group/editor-rtl.css\";i:181;s:24:\"group/editor-rtl.min.css\";i:182;s:16:\"group/editor.css\";i:183;s:20:\"group/editor.min.css\";i:184;s:19:\"group/style-rtl.css\";i:185;s:23:\"group/style-rtl.min.css\";i:186;s:15:\"group/style.css\";i:187;s:19:\"group/style.min.css\";i:188;s:19:\"group/theme-rtl.css\";i:189;s:23:\"group/theme-rtl.min.css\";i:190;s:15:\"group/theme.css\";i:191;s:19:\"group/theme.min.css\";i:192;s:21:\"heading/style-rtl.css\";i:193;s:25:\"heading/style-rtl.min.css\";i:194;s:17:\"heading/style.css\";i:195;s:21:\"heading/style.min.css\";i:196;s:19:\"html/editor-rtl.css\";i:197;s:23:\"html/editor-rtl.min.css\";i:198;s:15:\"html/editor.css\";i:199;s:19:\"html/editor.min.css\";i:200;s:20:\"image/editor-rtl.css\";i:201;s:24:\"image/editor-rtl.min.css\";i:202;s:16:\"image/editor.css\";i:203;s:20:\"image/editor.min.css\";i:204;s:19:\"image/style-rtl.css\";i:205;s:23:\"image/style-rtl.min.css\";i:206;s:15:\"image/style.css\";i:207;s:19:\"image/style.min.css\";i:208;s:19:\"image/theme-rtl.css\";i:209;s:23:\"image/theme-rtl.min.css\";i:210;s:15:\"image/theme.css\";i:211;s:19:\"image/theme.min.css\";i:212;s:29:\"latest-comments/style-rtl.css\";i:213;s:33:\"latest-comments/style-rtl.min.css\";i:214;s:25:\"latest-comments/style.css\";i:215;s:29:\"latest-comments/style.min.css\";i:216;s:27:\"latest-posts/editor-rtl.css\";i:217;s:31:\"latest-posts/editor-rtl.min.css\";i:218;s:23:\"latest-posts/editor.css\";i:219;s:27:\"latest-posts/editor.min.css\";i:220;s:26:\"latest-posts/style-rtl.css\";i:221;s:30:\"latest-posts/style-rtl.min.css\";i:222;s:22:\"latest-posts/style.css\";i:223;s:26:\"latest-posts/style.min.css\";i:224;s:18:\"list/style-rtl.css\";i:225;s:22:\"list/style-rtl.min.css\";i:226;s:14:\"list/style.css\";i:227;s:18:\"list/style.min.css\";i:228;s:22:\"loginout/style-rtl.css\";i:229;s:26:\"loginout/style-rtl.min.css\";i:230;s:18:\"loginout/style.css\";i:231;s:22:\"loginout/style.min.css\";i:232;s:25:\"media-text/editor-rtl.css\";i:233;s:29:\"media-text/editor-rtl.min.css\";i:234;s:21:\"media-text/editor.css\";i:235;s:25:\"media-text/editor.min.css\";i:236;s:24:\"media-text/style-rtl.css\";i:237;s:28:\"media-text/style-rtl.min.css\";i:238;s:20:\"media-text/style.css\";i:239;s:24:\"media-text/style.min.css\";i:240;s:19:\"more/editor-rtl.css\";i:241;s:23:\"more/editor-rtl.min.css\";i:242;s:15:\"more/editor.css\";i:243;s:19:\"more/editor.min.css\";i:244;s:30:\"navigation-link/editor-rtl.css\";i:245;s:34:\"navigation-link/editor-rtl.min.css\";i:246;s:26:\"navigation-link/editor.css\";i:247;s:30:\"navigation-link/editor.min.css\";i:248;s:29:\"navigation-link/style-rtl.css\";i:249;s:33:\"navigation-link/style-rtl.min.css\";i:250;s:25:\"navigation-link/style.css\";i:251;s:29:\"navigation-link/style.min.css\";i:252;s:33:\"navigation-submenu/editor-rtl.css\";i:253;s:37:\"navigation-submenu/editor-rtl.min.css\";i:254;s:29:\"navigation-submenu/editor.css\";i:255;s:33:\"navigation-submenu/editor.min.css\";i:256;s:25:\"navigation/editor-rtl.css\";i:257;s:29:\"navigation/editor-rtl.min.css\";i:258;s:21:\"navigation/editor.css\";i:259;s:25:\"navigation/editor.min.css\";i:260;s:24:\"navigation/style-rtl.css\";i:261;s:28:\"navigation/style-rtl.min.css\";i:262;s:20:\"navigation/style.css\";i:263;s:24:\"navigation/style.min.css\";i:264;s:23:\"nextpage/editor-rtl.css\";i:265;s:27:\"nextpage/editor-rtl.min.css\";i:266;s:19:\"nextpage/editor.css\";i:267;s:23:\"nextpage/editor.min.css\";i:268;s:24:\"page-list/editor-rtl.css\";i:269;s:28:\"page-list/editor-rtl.min.css\";i:270;s:20:\"page-list/editor.css\";i:271;s:24:\"page-list/editor.min.css\";i:272;s:23:\"page-list/style-rtl.css\";i:273;s:27:\"page-list/style-rtl.min.css\";i:274;s:19:\"page-list/style.css\";i:275;s:23:\"page-list/style.min.css\";i:276;s:24:\"paragraph/editor-rtl.css\";i:277;s:28:\"paragraph/editor-rtl.min.css\";i:278;s:20:\"paragraph/editor.css\";i:279;s:24:\"paragraph/editor.min.css\";i:280;s:23:\"paragraph/style-rtl.css\";i:281;s:27:\"paragraph/style-rtl.min.css\";i:282;s:19:\"paragraph/style.css\";i:283;s:23:\"paragraph/style.min.css\";i:284;s:35:\"post-author-biography/style-rtl.css\";i:285;s:39:\"post-author-biography/style-rtl.min.css\";i:286;s:31:\"post-author-biography/style.css\";i:287;s:35:\"post-author-biography/style.min.css\";i:288;s:30:\"post-author-name/style-rtl.css\";i:289;s:34:\"post-author-name/style-rtl.min.css\";i:290;s:26:\"post-author-name/style.css\";i:291;s:30:\"post-author-name/style.min.css\";i:292;s:26:\"post-author/editor-rtl.css\";i:293;s:30:\"post-author/editor-rtl.min.css\";i:294;s:22:\"post-author/editor.css\";i:295;s:26:\"post-author/editor.min.css\";i:296;s:25:\"post-author/style-rtl.css\";i:297;s:29:\"post-author/style-rtl.min.css\";i:298;s:21:\"post-author/style.css\";i:299;s:25:\"post-author/style.min.css\";i:300;s:33:\"post-comments-form/editor-rtl.css\";i:301;s:37:\"post-comments-form/editor-rtl.min.css\";i:302;s:29:\"post-comments-form/editor.css\";i:303;s:33:\"post-comments-form/editor.min.css\";i:304;s:32:\"post-comments-form/style-rtl.css\";i:305;s:36:\"post-comments-form/style-rtl.min.css\";i:306;s:28:\"post-comments-form/style.css\";i:307;s:32:\"post-comments-form/style.min.css\";i:308;s:26:\"post-content/style-rtl.css\";i:309;s:30:\"post-content/style-rtl.min.css\";i:310;s:22:\"post-content/style.css\";i:311;s:26:\"post-content/style.min.css\";i:312;s:23:\"post-date/style-rtl.css\";i:313;s:27:\"post-date/style-rtl.min.css\";i:314;s:19:\"post-date/style.css\";i:315;s:23:\"post-date/style.min.css\";i:316;s:27:\"post-excerpt/editor-rtl.css\";i:317;s:31:\"post-excerpt/editor-rtl.min.css\";i:318;s:23:\"post-excerpt/editor.css\";i:319;s:27:\"post-excerpt/editor.min.css\";i:320;s:26:\"post-excerpt/style-rtl.css\";i:321;s:30:\"post-excerpt/style-rtl.min.css\";i:322;s:22:\"post-excerpt/style.css\";i:323;s:26:\"post-excerpt/style.min.css\";i:324;s:34:\"post-featured-image/editor-rtl.css\";i:325;s:38:\"post-featured-image/editor-rtl.min.css\";i:326;s:30:\"post-featured-image/editor.css\";i:327;s:34:\"post-featured-image/editor.min.css\";i:328;s:33:\"post-featured-image/style-rtl.css\";i:329;s:37:\"post-featured-image/style-rtl.min.css\";i:330;s:29:\"post-featured-image/style.css\";i:331;s:33:\"post-featured-image/style.min.css\";i:332;s:34:\"post-navigation-link/style-rtl.css\";i:333;s:38:\"post-navigation-link/style-rtl.min.css\";i:334;s:30:\"post-navigation-link/style.css\";i:335;s:34:\"post-navigation-link/style.min.css\";i:336;s:27:\"post-template/style-rtl.css\";i:337;s:31:\"post-template/style-rtl.min.css\";i:338;s:23:\"post-template/style.css\";i:339;s:27:\"post-template/style.min.css\";i:340;s:24:\"post-terms/style-rtl.css\";i:341;s:28:\"post-terms/style-rtl.min.css\";i:342;s:20:\"post-terms/style.css\";i:343;s:24:\"post-terms/style.min.css\";i:344;s:24:\"post-title/style-rtl.css\";i:345;s:28:\"post-title/style-rtl.min.css\";i:346;s:20:\"post-title/style.css\";i:347;s:24:\"post-title/style.min.css\";i:348;s:26:\"preformatted/style-rtl.css\";i:349;s:30:\"preformatted/style-rtl.min.css\";i:350;s:22:\"preformatted/style.css\";i:351;s:26:\"preformatted/style.min.css\";i:352;s:24:\"pullquote/editor-rtl.css\";i:353;s:28:\"pullquote/editor-rtl.min.css\";i:354;s:20:\"pullquote/editor.css\";i:355;s:24:\"pullquote/editor.min.css\";i:356;s:23:\"pullquote/style-rtl.css\";i:357;s:27:\"pullquote/style-rtl.min.css\";i:358;s:19:\"pullquote/style.css\";i:359;s:23:\"pullquote/style.min.css\";i:360;s:23:\"pullquote/theme-rtl.css\";i:361;s:27:\"pullquote/theme-rtl.min.css\";i:362;s:19:\"pullquote/theme.css\";i:363;s:23:\"pullquote/theme.min.css\";i:364;s:39:\"query-pagination-numbers/editor-rtl.css\";i:365;s:43:\"query-pagination-numbers/editor-rtl.min.css\";i:366;s:35:\"query-pagination-numbers/editor.css\";i:367;s:39:\"query-pagination-numbers/editor.min.css\";i:368;s:31:\"query-pagination/editor-rtl.css\";i:369;s:35:\"query-pagination/editor-rtl.min.css\";i:370;s:27:\"query-pagination/editor.css\";i:371;s:31:\"query-pagination/editor.min.css\";i:372;s:30:\"query-pagination/style-rtl.css\";i:373;s:34:\"query-pagination/style-rtl.min.css\";i:374;s:26:\"query-pagination/style.css\";i:375;s:30:\"query-pagination/style.min.css\";i:376;s:25:\"query-title/style-rtl.css\";i:377;s:29:\"query-title/style-rtl.min.css\";i:378;s:21:\"query-title/style.css\";i:379;s:25:\"query-title/style.min.css\";i:380;s:25:\"query-total/style-rtl.css\";i:381;s:29:\"query-total/style-rtl.min.css\";i:382;s:21:\"query-total/style.css\";i:383;s:25:\"query-total/style.min.css\";i:384;s:20:\"query/editor-rtl.css\";i:385;s:24:\"query/editor-rtl.min.css\";i:386;s:16:\"query/editor.css\";i:387;s:20:\"query/editor.min.css\";i:388;s:19:\"quote/style-rtl.css\";i:389;s:23:\"quote/style-rtl.min.css\";i:390;s:15:\"quote/style.css\";i:391;s:19:\"quote/style.min.css\";i:392;s:19:\"quote/theme-rtl.css\";i:393;s:23:\"quote/theme-rtl.min.css\";i:394;s:15:\"quote/theme.css\";i:395;s:19:\"quote/theme.min.css\";i:396;s:23:\"read-more/style-rtl.css\";i:397;s:27:\"read-more/style-rtl.min.css\";i:398;s:19:\"read-more/style.css\";i:399;s:23:\"read-more/style.min.css\";i:400;s:18:\"rss/editor-rtl.css\";i:401;s:22:\"rss/editor-rtl.min.css\";i:402;s:14:\"rss/editor.css\";i:403;s:18:\"rss/editor.min.css\";i:404;s:17:\"rss/style-rtl.css\";i:405;s:21:\"rss/style-rtl.min.css\";i:406;s:13:\"rss/style.css\";i:407;s:17:\"rss/style.min.css\";i:408;s:21:\"search/editor-rtl.css\";i:409;s:25:\"search/editor-rtl.min.css\";i:410;s:17:\"search/editor.css\";i:411;s:21:\"search/editor.min.css\";i:412;s:20:\"search/style-rtl.css\";i:413;s:24:\"search/style-rtl.min.css\";i:414;s:16:\"search/style.css\";i:415;s:20:\"search/style.min.css\";i:416;s:20:\"search/theme-rtl.css\";i:417;s:24:\"search/theme-rtl.min.css\";i:418;s:16:\"search/theme.css\";i:419;s:20:\"search/theme.min.css\";i:420;s:24:\"separator/editor-rtl.css\";i:421;s:28:\"separator/editor-rtl.min.css\";i:422;s:20:\"separator/editor.css\";i:423;s:24:\"separator/editor.min.css\";i:424;s:23:\"separator/style-rtl.css\";i:425;s:27:\"separator/style-rtl.min.css\";i:426;s:19:\"separator/style.css\";i:427;s:23:\"separator/style.min.css\";i:428;s:23:\"separator/theme-rtl.css\";i:429;s:27:\"separator/theme-rtl.min.css\";i:430;s:19:\"separator/theme.css\";i:431;s:23:\"separator/theme.min.css\";i:432;s:24:\"shortcode/editor-rtl.css\";i:433;s:28:\"shortcode/editor-rtl.min.css\";i:434;s:20:\"shortcode/editor.css\";i:435;s:24:\"shortcode/editor.min.css\";i:436;s:24:\"site-logo/editor-rtl.css\";i:437;s:28:\"site-logo/editor-rtl.min.css\";i:438;s:20:\"site-logo/editor.css\";i:439;s:24:\"site-logo/editor.min.css\";i:440;s:23:\"site-logo/style-rtl.css\";i:441;s:27:\"site-logo/style-rtl.min.css\";i:442;s:19:\"site-logo/style.css\";i:443;s:23:\"site-logo/style.min.css\";i:444;s:27:\"site-tagline/editor-rtl.css\";i:445;s:31:\"site-tagline/editor-rtl.min.css\";i:446;s:23:\"site-tagline/editor.css\";i:447;s:27:\"site-tagline/editor.min.css\";i:448;s:26:\"site-tagline/style-rtl.css\";i:449;s:30:\"site-tagline/style-rtl.min.css\";i:450;s:22:\"site-tagline/style.css\";i:451;s:26:\"site-tagline/style.min.css\";i:452;s:25:\"site-title/editor-rtl.css\";i:453;s:29:\"site-title/editor-rtl.min.css\";i:454;s:21:\"site-title/editor.css\";i:455;s:25:\"site-title/editor.min.css\";i:456;s:24:\"site-title/style-rtl.css\";i:457;s:28:\"site-title/style-rtl.min.css\";i:458;s:20:\"site-title/style.css\";i:459;s:24:\"site-title/style.min.css\";i:460;s:26:\"social-link/editor-rtl.css\";i:461;s:30:\"social-link/editor-rtl.min.css\";i:462;s:22:\"social-link/editor.css\";i:463;s:26:\"social-link/editor.min.css\";i:464;s:27:\"social-links/editor-rtl.css\";i:465;s:31:\"social-links/editor-rtl.min.css\";i:466;s:23:\"social-links/editor.css\";i:467;s:27:\"social-links/editor.min.css\";i:468;s:26:\"social-links/style-rtl.css\";i:469;s:30:\"social-links/style-rtl.min.css\";i:470;s:22:\"social-links/style.css\";i:471;s:26:\"social-links/style.min.css\";i:472;s:21:\"spacer/editor-rtl.css\";i:473;s:25:\"spacer/editor-rtl.min.css\";i:474;s:17:\"spacer/editor.css\";i:475;s:21:\"spacer/editor.min.css\";i:476;s:20:\"spacer/style-rtl.css\";i:477;s:24:\"spacer/style-rtl.min.css\";i:478;s:16:\"spacer/style.css\";i:479;s:20:\"spacer/style.min.css\";i:480;s:20:\"table/editor-rtl.css\";i:481;s:24:\"table/editor-rtl.min.css\";i:482;s:16:\"table/editor.css\";i:483;s:20:\"table/editor.min.css\";i:484;s:19:\"table/style-rtl.css\";i:485;s:23:\"table/style-rtl.min.css\";i:486;s:15:\"table/style.css\";i:487;s:19:\"table/style.min.css\";i:488;s:19:\"table/theme-rtl.css\";i:489;s:23:\"table/theme-rtl.min.css\";i:490;s:15:\"table/theme.css\";i:491;s:19:\"table/theme.min.css\";i:492;s:24:\"tag-cloud/editor-rtl.css\";i:493;s:28:\"tag-cloud/editor-rtl.min.css\";i:494;s:20:\"tag-cloud/editor.css\";i:495;s:24:\"tag-cloud/editor.min.css\";i:496;s:23:\"tag-cloud/style-rtl.css\";i:497;s:27:\"tag-cloud/style-rtl.min.css\";i:498;s:19:\"tag-cloud/style.css\";i:499;s:23:\"tag-cloud/style.min.css\";i:500;s:28:\"template-part/editor-rtl.css\";i:501;s:32:\"template-part/editor-rtl.min.css\";i:502;s:24:\"template-part/editor.css\";i:503;s:28:\"template-part/editor.min.css\";i:504;s:27:\"template-part/theme-rtl.css\";i:505;s:31:\"template-part/theme-rtl.min.css\";i:506;s:23:\"template-part/theme.css\";i:507;s:27:\"template-part/theme.min.css\";i:508;s:30:\"term-description/style-rtl.css\";i:509;s:34:\"term-description/style-rtl.min.css\";i:510;s:26:\"term-description/style.css\";i:511;s:30:\"term-description/style.min.css\";i:512;s:27:\"text-columns/editor-rtl.css\";i:513;s:31:\"text-columns/editor-rtl.min.css\";i:514;s:23:\"text-columns/editor.css\";i:515;s:27:\"text-columns/editor.min.css\";i:516;s:26:\"text-columns/style-rtl.css\";i:517;s:30:\"text-columns/style-rtl.min.css\";i:518;s:22:\"text-columns/style.css\";i:519;s:26:\"text-columns/style.min.css\";i:520;s:19:\"verse/style-rtl.css\";i:521;s:23:\"verse/style-rtl.min.css\";i:522;s:15:\"verse/style.css\";i:523;s:19:\"verse/style.min.css\";i:524;s:20:\"video/editor-rtl.css\";i:525;s:24:\"video/editor-rtl.min.css\";i:526;s:16:\"video/editor.css\";i:527;s:20:\"video/editor.min.css\";i:528;s:19:\"video/style-rtl.css\";i:529;s:23:\"video/style-rtl.min.css\";i:530;s:15:\"video/style.css\";i:531;s:19:\"video/style.min.css\";i:532;s:19:\"video/theme-rtl.css\";i:533;s:23:\"video/theme-rtl.min.css\";i:534;s:15:\"video/theme.css\";i:535;s:19:\"video/theme.min.css\";}}','on'),(124,'_transient_doing_cron','1764371701.4586930274963378906250','on'),(125,'theme_mods_twentytwentyfive','a:2:{s:18:\"custom_css_post_id\";i:-1;s:16:\"sidebars_widgets\";a:2:{s:4:\"time\";i:1764367183;s:4:\"data\";a:3:{s:19:\"wp_inactive_widgets\";a:0:{}s:9:\"sidebar-1\";a:3:{i:0;s:7:\"block-2\";i:1;s:7:\"block-3\";i:2;s:7:\"block-4\";}s:9:\"sidebar-2\";a:2:{i:0;s:7:\"block-5\";i:1;s:7:\"block-6\";}}}}','off'),(126,'_transient_wp_styles_for_blocks','a:2:{s:4:\"hash\";s:32:\"64ad95698215776f80fa1e80f2eb5417\";s:6:\"blocks\";a:7:{s:11:\"core/button\";s:0:\"\";s:14:\"core/site-logo\";s:0:\"\";s:18:\"core/post-template\";s:0:\"\";s:12:\"core/columns\";s:0:\"\";s:14:\"core/pullquote\";s:121:\":root :where(.wp-block-pullquote){font-size: clamp(0.984em, 0.984rem + ((1vw - 0.2em) * 0.938), 1.5em);line-height: 1.6;}\";s:15:\"core/site-title\";s:89:\":root :where(.wp-block-site-title){font-family: var(--wp--preset--font-family--display);}\";s:15:\"core/navigation\";s:86:\":root :where(.wp-block-navigation){font-family: var(--wp--preset--font-family--body);}\";}}','on'),(129,'category_children','a:0:{}','auto'),(132,'_site_transient_update_themes','O:8:\"stdClass\":5:{s:12:\"last_checked\";i:1764371702;s:7:\"checked\";a:4:{s:8:\"homeproz\";s:5:\"1.0.0\";s:16:\"twentytwentyfive\";s:3:\"1.3\";s:16:\"twentytwentyfour\";s:3:\"1.3\";s:17:\"twentytwentythree\";s:3:\"1.6\";}s:8:\"response\";a:0:{}s:9:\"no_update\";a:3:{s:16:\"twentytwentyfive\";a:6:{s:5:\"theme\";s:16:\"twentytwentyfive\";s:11:\"new_version\";s:3:\"1.3\";s:3:\"url\";s:46:\"https://wordpress.org/themes/twentytwentyfive/\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/theme/twentytwentyfive.1.3.zip\";s:8:\"requires\";s:3:\"6.7\";s:12:\"requires_php\";s:3:\"7.2\";}s:16:\"twentytwentyfour\";a:6:{s:5:\"theme\";s:16:\"twentytwentyfour\";s:11:\"new_version\";s:3:\"1.3\";s:3:\"url\";s:46:\"https://wordpress.org/themes/twentytwentyfour/\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/theme/twentytwentyfour.1.3.zip\";s:8:\"requires\";s:3:\"6.4\";s:12:\"requires_php\";s:3:\"7.0\";}s:17:\"twentytwentythree\";a:6:{s:5:\"theme\";s:17:\"twentytwentythree\";s:11:\"new_version\";s:3:\"1.6\";s:3:\"url\";s:47:\"https://wordpress.org/themes/twentytwentythree/\";s:7:\"package\";s:63:\"https://downloads.wordpress.org/theme/twentytwentythree.1.6.zip\";s:8:\"requires\";s:3:\"6.1\";s:12:\"requires_php\";s:3:\"5.6\";}}s:12:\"translations\";a:0:{}}','off'),(133,'current_theme','HomeProz','auto'),(134,'theme_switched','','auto'),(135,'theme_mods_homeproz','a:2:{s:18:\"nav_menu_locations\";a:1:{s:7:\"primary\";i:15;}s:18:\"custom_css_post_id\";i:-1;}','auto'),(141,'property_type_children','a:0:{}','auto'),(144,'property_status_children','a:0:{}','auto'),(150,'property_location_children','a:0:{}','auto'),(152,'_site_transient_update_core','O:8:\"stdClass\":4:{s:7:\"updates\";a:1:{i:0;O:8:\"stdClass\":10:{s:8:\"response\";s:6:\"latest\";s:8:\"download\";s:59:\"https://downloads.wordpress.org/release/wordpress-6.8.3.zip\";s:6:\"locale\";s:5:\"en_US\";s:8:\"packages\";O:8:\"stdClass\":5:{s:4:\"full\";s:59:\"https://downloads.wordpress.org/release/wordpress-6.8.3.zip\";s:10:\"no_content\";s:70:\"https://downloads.wordpress.org/release/wordpress-6.8.3-no-content.zip\";s:11:\"new_bundled\";s:71:\"https://downloads.wordpress.org/release/wordpress-6.8.3-new-bundled.zip\";s:7:\"partial\";s:0:\"\";s:8:\"rollback\";s:0:\"\";}s:7:\"current\";s:5:\"6.8.3\";s:7:\"version\";s:5:\"6.8.3\";s:11:\"php_version\";s:6:\"7.2.24\";s:13:\"mysql_version\";s:5:\"5.5.5\";s:11:\"new_bundled\";s:3:\"6.7\";s:15:\"partial_version\";s:0:\"\";}}s:12:\"last_checked\";i:1764371702;s:15:\"version_checked\";s:5:\"6.8.3\";s:12:\"translations\";a:0:{}}','off'),(156,'acf_first_activated_version','6.6.2','on'),(157,'acf_site_health','{\"event_first_activated\":1764369116,\"last_updated\":1764369116}','off'),(158,'_site_transient_timeout_wp_theme_files_patterns-2aae27f1f26ef7a6be8ebee5c8a6a86b','1764372438','off'),(159,'_site_transient_wp_theme_files_patterns-2aae27f1f26ef7a6be8ebee5c8a6a86b','a:2:{s:7:\"version\";s:5:\"1.0.0\";s:8:\"patterns\";a:0:{}}','off'),(162,'wpcf7','a:2:{s:7:\"version\";s:5:\"6.1.3\";s:13:\"bulk_validate\";a:4:{s:9:\"timestamp\";i:1764370639;s:7:\"version\";s:5:\"6.1.3\";s:11:\"count_valid\";i:1;s:13:\"count_invalid\";i:0;}}','auto'),(165,'_site_transient_timeout_theme_roots','1764373103','off'),(166,'_site_transient_theme_roots','a:4:{s:8:\"homeproz\";s:7:\"/themes\";s:16:\"twentytwentyfive\";s:7:\"/themes\";s:16:\"twentytwentyfour\";s:7:\"/themes\";s:17:\"twentytwentythree\";s:7:\"/themes\";}','off'),(167,'yoast_migrations_free','a:1:{s:7:\"version\";s:4:\"26.4\";}','auto'),(168,'wpseo','a:120:{s:8:\"tracking\";b:0;s:16:\"toggled_tracking\";b:0;s:22:\"license_server_version\";b:0;s:15:\"ms_defaults_set\";b:0;s:40:\"ignore_search_engines_discouraged_notice\";b:0;s:19:\"indexing_first_time\";b:1;s:16:\"indexing_started\";b:0;s:15:\"indexing_reason\";s:24:\"attachments_made_enabled\";s:29:\"indexables_indexing_completed\";b:0;s:13:\"index_now_key\";s:0:\"\";s:7:\"version\";s:4:\"26.4\";s:16:\"previous_version\";s:0:\"\";s:20:\"disableadvanced_meta\";b:1;s:30:\"enable_headless_rest_endpoints\";b:1;s:17:\"ryte_indexability\";b:0;s:11:\"baiduverify\";s:0:\"\";s:12:\"googleverify\";s:0:\"\";s:8:\"msverify\";s:0:\"\";s:12:\"yandexverify\";s:0:\"\";s:12:\"ahrefsverify\";s:0:\"\";s:9:\"site_type\";s:0:\"\";s:20:\"has_multiple_authors\";s:0:\"\";s:16:\"environment_type\";s:0:\"\";s:23:\"content_analysis_active\";b:1;s:23:\"keyword_analysis_active\";b:1;s:34:\"inclusive_language_analysis_active\";b:0;s:21:\"enable_admin_bar_menu\";b:1;s:26:\"enable_cornerstone_content\";b:1;s:18:\"enable_xml_sitemap\";b:1;s:24:\"enable_text_link_counter\";b:1;s:16:\"enable_index_now\";b:1;s:19:\"enable_ai_generator\";b:1;s:22:\"ai_enabled_pre_default\";b:0;s:22:\"show_onboarding_notice\";b:1;s:18:\"first_activated_on\";i:1764371307;s:13:\"myyoast-oauth\";b:0;s:26:\"semrush_integration_active\";b:1;s:14:\"semrush_tokens\";a:0:{}s:20:\"semrush_country_code\";s:2:\"us\";s:19:\"permalink_structure\";s:0:\"\";s:8:\"home_url\";s:0:\"\";s:18:\"dynamic_permalinks\";b:0;s:17:\"category_base_url\";s:0:\"\";s:12:\"tag_base_url\";s:0:\"\";s:21:\"custom_taxonomy_slugs\";a:0:{}s:29:\"enable_enhanced_slack_sharing\";b:1;s:23:\"enable_metabox_insights\";b:1;s:23:\"enable_link_suggestions\";b:1;s:26:\"algolia_integration_active\";b:0;s:14:\"import_cursors\";a:0:{}s:13:\"workouts_data\";a:1:{s:13:\"configuration\";a:1:{s:13:\"finishedSteps\";a:0:{}}}s:28:\"configuration_finished_steps\";a:0:{}s:36:\"dismiss_configuration_workout_notice\";b:0;s:34:\"dismiss_premium_deactivated_notice\";b:0;s:19:\"importing_completed\";a:0:{}s:26:\"wincher_integration_active\";b:1;s:14:\"wincher_tokens\";a:0:{}s:36:\"wincher_automatically_add_keyphrases\";b:0;s:18:\"wincher_website_id\";s:0:\"\";s:18:\"first_time_install\";b:1;s:34:\"should_redirect_after_install_free\";b:0;s:34:\"activation_redirect_timestamp_free\";i:1764371307;s:18:\"remove_feed_global\";b:0;s:27:\"remove_feed_global_comments\";b:0;s:25:\"remove_feed_post_comments\";b:0;s:19:\"remove_feed_authors\";b:0;s:22:\"remove_feed_categories\";b:0;s:16:\"remove_feed_tags\";b:0;s:29:\"remove_feed_custom_taxonomies\";b:0;s:22:\"remove_feed_post_types\";b:0;s:18:\"remove_feed_search\";b:0;s:21:\"remove_atom_rdf_feeds\";b:0;s:17:\"remove_shortlinks\";b:0;s:21:\"remove_rest_api_links\";b:0;s:20:\"remove_rsd_wlw_links\";b:0;s:19:\"remove_oembed_links\";b:0;s:16:\"remove_generator\";b:0;s:20:\"remove_emoji_scripts\";b:0;s:24:\"remove_powered_by_header\";b:0;s:22:\"remove_pingback_header\";b:0;s:28:\"clean_campaign_tracking_urls\";b:0;s:16:\"clean_permalinks\";b:0;s:32:\"clean_permalinks_extra_variables\";s:0:\"\";s:14:\"search_cleanup\";b:0;s:20:\"search_cleanup_emoji\";b:0;s:23:\"search_cleanup_patterns\";b:0;s:22:\"search_character_limit\";i:50;s:20:\"deny_search_crawling\";b:0;s:21:\"deny_wp_json_crawling\";b:0;s:20:\"deny_adsbot_crawling\";b:0;s:19:\"deny_ccbot_crawling\";b:0;s:29:\"deny_google_extended_crawling\";b:0;s:20:\"deny_gptbot_crawling\";b:0;s:27:\"redirect_search_pretty_urls\";b:0;s:29:\"least_readability_ignore_list\";a:0:{}s:27:\"least_seo_score_ignore_list\";a:0:{}s:23:\"most_linked_ignore_list\";a:0:{}s:24:\"least_linked_ignore_list\";a:0:{}s:28:\"indexables_page_reading_list\";a:5:{i:0;b:0;i:1;b:0;i:2;b:0;i:3;b:0;i:4;b:0;}s:25:\"indexables_overview_state\";s:21:\"dashboard-not-visited\";s:28:\"last_known_public_post_types\";a:0:{}s:28:\"last_known_public_taxonomies\";a:0:{}s:23:\"last_known_no_unindexed\";a:0:{}s:14:\"new_post_types\";a:0:{}s:14:\"new_taxonomies\";a:0:{}s:34:\"show_new_content_type_notification\";b:0;s:44:\"site_kit_configuration_permanently_dismissed\";b:0;s:18:\"site_kit_connected\";b:0;s:37:\"site_kit_tracking_setup_widget_loaded\";s:2:\"no\";s:41:\"site_kit_tracking_first_interaction_stage\";s:0:\"\";s:40:\"site_kit_tracking_last_interaction_stage\";s:0:\"\";s:52:\"site_kit_tracking_setup_widget_temporarily_dismissed\";s:2:\"no\";s:52:\"site_kit_tracking_setup_widget_permanently_dismissed\";s:2:\"no\";s:31:\"google_site_kit_feature_enabled\";b:0;s:25:\"ai_free_sparks_started_on\";N;s:15:\"enable_llms_txt\";b:0;s:15:\"last_updated_on\";b:0;s:17:\"default_seo_title\";a:0:{}s:21:\"default_seo_meta_desc\";a:0:{}s:18:\"first_activated_by\";i:0;}','auto'),(169,'wpseo_titles','a:173:{s:17:\"forcerewritetitle\";b:0;s:9:\"separator\";s:7:\"sc-dash\";s:16:\"title-home-wpseo\";s:47:\"HomeProz Real Estate | Albert Lea MN Properties\";s:18:\"title-author-wpseo\";s:41:\"%%name%%, Author at %%sitename%% %%page%%\";s:19:\"title-archive-wpseo\";s:38:\"%%date%% %%page%% %%sep%% %%sitename%%\";s:18:\"title-search-wpseo\";s:63:\"You searched for %%searchphrase%% %%page%% %%sep%% %%sitename%%\";s:15:\"title-404-wpseo\";s:35:\"Page not found %%sep%% %%sitename%%\";s:25:\"social-title-author-wpseo\";s:8:\"%%name%%\";s:26:\"social-title-archive-wpseo\";s:8:\"%%date%%\";s:31:\"social-description-author-wpseo\";s:0:\"\";s:32:\"social-description-archive-wpseo\";s:0:\"\";s:29:\"social-image-url-author-wpseo\";s:0:\"\";s:30:\"social-image-url-archive-wpseo\";s:0:\"\";s:28:\"social-image-id-author-wpseo\";i:0;s:29:\"social-image-id-archive-wpseo\";i:0;s:19:\"metadesc-home-wpseo\";s:120:\"HomeProz Real Estate - Your trusted partner for buying and selling homes in Albert Lea, Minnesota and surrounding areas.\";s:21:\"metadesc-author-wpseo\";s:0:\"\";s:22:\"metadesc-archive-wpseo\";s:0:\"\";s:9:\"rssbefore\";s:0:\"\";s:8:\"rssafter\";s:53:\"The post %%POSTLINK%% appeared first on %%BLOGLINK%%.\";s:20:\"noindex-author-wpseo\";b:0;s:28:\"noindex-author-noposts-wpseo\";b:0;s:21:\"noindex-archive-wpseo\";b:0;s:14:\"disable-author\";b:0;s:12:\"disable-date\";b:0;s:19:\"disable-post_format\";b:0;s:18:\"disable-attachment\";b:0;s:20:\"breadcrumbs-404crumb\";s:25:\"Error 404: Page not found\";s:29:\"breadcrumbs-display-blog-page\";b:0;s:20:\"breadcrumbs-boldlast\";b:0;s:25:\"breadcrumbs-archiveprefix\";s:12:\"Archives for\";s:18:\"breadcrumbs-enable\";b:0;s:16:\"breadcrumbs-home\";s:4:\"Home\";s:18:\"breadcrumbs-prefix\";s:0:\"\";s:24:\"breadcrumbs-searchprefix\";s:16:\"You searched for\";s:15:\"breadcrumbs-sep\";s:2:\"»\";s:12:\"website_name\";s:0:\"\";s:11:\"person_name\";s:0:\"\";s:11:\"person_logo\";s:0:\"\";s:22:\"alternate_website_name\";s:0:\"\";s:12:\"company_logo\";s:0:\"\";s:12:\"company_name\";s:0:\"\";s:22:\"company_alternate_name\";s:0:\"\";s:17:\"company_or_person\";s:7:\"company\";s:25:\"company_or_person_user_id\";b:0;s:17:\"stripcategorybase\";b:0;s:26:\"open_graph_frontpage_title\";s:12:\"%%sitename%%\";s:25:\"open_graph_frontpage_desc\";s:0:\"\";s:26:\"open_graph_frontpage_image\";s:0:\"\";s:24:\"publishing_principles_id\";i:0;s:25:\"ownership_funding_info_id\";i:0;s:29:\"actionable_feedback_policy_id\";i:0;s:21:\"corrections_policy_id\";i:0;s:16:\"ethics_policy_id\";i:0;s:19:\"diversity_policy_id\";i:0;s:28:\"diversity_staffing_report_id\";i:0;s:15:\"org-description\";s:0:\"\";s:9:\"org-email\";s:0:\"\";s:9:\"org-phone\";s:0:\"\";s:14:\"org-legal-name\";s:0:\"\";s:17:\"org-founding-date\";s:0:\"\";s:20:\"org-number-employees\";s:0:\"\";s:10:\"org-vat-id\";s:0:\"\";s:10:\"org-tax-id\";s:0:\"\";s:7:\"org-iso\";s:0:\"\";s:8:\"org-duns\";s:0:\"\";s:11:\"org-leicode\";s:0:\"\";s:9:\"org-naics\";s:0:\"\";s:10:\"title-post\";s:39:\"%%title%% %%page%% %%sep%% %%sitename%%\";s:13:\"metadesc-post\";s:0:\"\";s:12:\"noindex-post\";b:0;s:23:\"display-metabox-pt-post\";b:0;s:23:\"post_types-post-maintax\";i:0;s:21:\"schema-page-type-post\";s:7:\"WebPage\";s:24:\"schema-article-type-post\";s:7:\"Article\";s:17:\"social-title-post\";s:9:\"%%title%%\";s:23:\"social-description-post\";s:0:\"\";s:21:\"social-image-url-post\";s:0:\"\";s:20:\"social-image-id-post\";i:0;s:10:\"title-page\";s:39:\"%%title%% %%page%% %%sep%% %%sitename%%\";s:13:\"metadesc-page\";s:0:\"\";s:12:\"noindex-page\";b:0;s:23:\"display-metabox-pt-page\";b:0;s:23:\"post_types-page-maintax\";i:0;s:21:\"schema-page-type-page\";s:7:\"WebPage\";s:24:\"schema-article-type-page\";s:4:\"None\";s:17:\"social-title-page\";s:9:\"%%title%%\";s:23:\"social-description-page\";s:0:\"\";s:21:\"social-image-url-page\";s:0:\"\";s:20:\"social-image-id-page\";i:0;s:16:\"title-attachment\";s:39:\"%%title%% %%page%% %%sep%% %%sitename%%\";s:19:\"metadesc-attachment\";s:0:\"\";s:18:\"noindex-attachment\";b:0;s:29:\"display-metabox-pt-attachment\";b:0;s:29:\"post_types-attachment-maintax\";i:0;s:27:\"schema-page-type-attachment\";s:7:\"WebPage\";s:30:\"schema-article-type-attachment\";s:4:\"None\";s:18:\"title-tax-category\";s:53:\"%%term_title%% Archives %%page%% %%sep%% %%sitename%%\";s:21:\"metadesc-tax-category\";s:0:\"\";s:28:\"display-metabox-tax-category\";b:0;s:20:\"noindex-tax-category\";b:0;s:25:\"social-title-tax-category\";s:23:\"%%term_title%% Archives\";s:31:\"social-description-tax-category\";s:0:\"\";s:29:\"social-image-url-tax-category\";s:0:\"\";s:28:\"social-image-id-tax-category\";i:0;s:26:\"taxonomy-category-ptparent\";i:0;s:18:\"title-tax-post_tag\";s:53:\"%%term_title%% Archives %%page%% %%sep%% %%sitename%%\";s:21:\"metadesc-tax-post_tag\";s:0:\"\";s:28:\"display-metabox-tax-post_tag\";b:0;s:20:\"noindex-tax-post_tag\";b:0;s:25:\"social-title-tax-post_tag\";s:23:\"%%term_title%% Archives\";s:31:\"social-description-tax-post_tag\";s:0:\"\";s:29:\"social-image-url-tax-post_tag\";s:0:\"\";s:28:\"social-image-id-tax-post_tag\";i:0;s:26:\"taxonomy-post_tag-ptparent\";i:0;s:21:\"title-tax-post_format\";s:53:\"%%term_title%% Archives %%page%% %%sep%% %%sitename%%\";s:24:\"metadesc-tax-post_format\";s:0:\"\";s:31:\"display-metabox-tax-post_format\";b:0;s:23:\"noindex-tax-post_format\";b:0;s:28:\"social-title-tax-post_format\";s:23:\"%%term_title%% Archives\";s:34:\"social-description-tax-post_format\";s:0:\"\";s:32:\"social-image-url-tax-post_format\";s:0:\"\";s:31:\"social-image-id-tax-post_format\";i:0;s:29:\"taxonomy-post_format-ptparent\";i:0;s:14:\"title-property\";s:30:\"%%title%% %%sep%% %%sitename%%\";s:17:\"metadesc-property\";s:106:\"View property details, photos, and features for %%title%%. Contact HomeProz Real Estate in Albert Lea, MN.\";s:16:\"noindex-property\";b:0;s:27:\"display-metabox-pt-property\";b:0;s:27:\"post_types-property-maintax\";i:0;s:25:\"schema-page-type-property\";s:7:\"WebPage\";s:28:\"schema-article-type-property\";s:4:\"None\";s:21:\"social-title-property\";s:9:\"%%title%%\";s:27:\"social-description-property\";s:0:\"\";s:25:\"social-image-url-property\";s:0:\"\";s:24:\"social-image-id-property\";i:0;s:24:\"title-ptarchive-property\";s:49:\"Properties For Sale %%page%% %%sep%% %%sitename%%\";s:27:\"metadesc-ptarchive-property\";s:126:\"Browse all properties for sale in Albert Lea, Minnesota and surrounding areas. Find your dream home with HomeProz Real Estate.\";s:26:\"bctitle-ptarchive-property\";s:0:\"\";s:26:\"noindex-ptarchive-property\";b:0;s:31:\"social-title-ptarchive-property\";s:21:\"%%pt_plural%% Archive\";s:37:\"social-description-ptarchive-property\";s:0:\"\";s:35:\"social-image-url-ptarchive-property\";s:0:\"\";s:34:\"social-image-id-ptarchive-property\";i:0;s:23:\"title-tax-property_type\";s:53:\"%%term_title%% Archives %%page%% %%sep%% %%sitename%%\";s:26:\"metadesc-tax-property_type\";s:0:\"\";s:33:\"display-metabox-tax-property_type\";b:0;s:25:\"noindex-tax-property_type\";b:0;s:30:\"social-title-tax-property_type\";s:23:\"%%term_title%% Archives\";s:36:\"social-description-tax-property_type\";s:0:\"\";s:34:\"social-image-url-tax-property_type\";s:0:\"\";s:33:\"social-image-id-tax-property_type\";i:0;s:31:\"taxonomy-property_type-ptparent\";i:0;s:25:\"title-tax-property_status\";s:53:\"%%term_title%% Archives %%page%% %%sep%% %%sitename%%\";s:28:\"metadesc-tax-property_status\";s:0:\"\";s:35:\"display-metabox-tax-property_status\";b:0;s:27:\"noindex-tax-property_status\";b:0;s:32:\"social-title-tax-property_status\";s:23:\"%%term_title%% Archives\";s:38:\"social-description-tax-property_status\";s:0:\"\";s:36:\"social-image-url-tax-property_status\";s:0:\"\";s:35:\"social-image-id-tax-property_status\";i:0;s:33:\"taxonomy-property_status-ptparent\";i:0;s:27:\"title-tax-property_location\";s:53:\"%%term_title%% Archives %%page%% %%sep%% %%sitename%%\";s:30:\"metadesc-tax-property_location\";s:0:\"\";s:37:\"display-metabox-tax-property_location\";b:0;s:29:\"noindex-tax-property_location\";b:0;s:34:\"social-title-tax-property_location\";s:23:\"%%term_title%% Archives\";s:40:\"social-description-tax-property_location\";s:0:\"\";s:38:\"social-image-url-tax-property_location\";s:0:\"\";s:37:\"social-image-id-tax-property_location\";i:0;s:35:\"taxonomy-property_location-ptparent\";i:0;s:14:\"person_logo_id\";i:0;s:15:\"company_logo_id\";i:0;s:29:\"open_graph_frontpage_image_id\";i:0;}','auto'),(170,'wpseo_social','a:20:{s:13:\"facebook_site\";s:0:\"\";s:13:\"instagram_url\";s:0:\"\";s:12:\"linkedin_url\";s:0:\"\";s:11:\"myspace_url\";s:0:\"\";s:16:\"og_default_image\";s:0:\"\";s:19:\"og_default_image_id\";s:0:\"\";s:18:\"og_frontpage_title\";s:47:\"HomeProz Real Estate | Albert Lea MN Properties\";s:17:\"og_frontpage_desc\";s:97:\"Your trusted partner for buying and selling homes in Albert Lea, Minnesota and surrounding areas.\";s:18:\"og_frontpage_image\";s:0:\"\";s:21:\"og_frontpage_image_id\";s:0:\"\";s:9:\"opengraph\";b:1;s:13:\"pinterest_url\";s:0:\"\";s:15:\"pinterestverify\";s:0:\"\";s:7:\"twitter\";b:1;s:12:\"twitter_site\";s:0:\"\";s:17:\"twitter_card_type\";s:19:\"summary_large_image\";s:11:\"youtube_url\";s:0:\"\";s:13:\"wikipedia_url\";s:0:\"\";s:17:\"other_social_urls\";a:0:{}s:12:\"mastodon_url\";s:0:\"\";}','auto'),(171,'wpseo_llmstxt','a:7:{s:23:\"llms_txt_selection_mode\";s:4:\"auto\";s:13:\"about_us_page\";i:0;s:12:\"contact_page\";i:0;s:10:\"terms_page\";i:0;s:19:\"privacy_policy_page\";i:0;s:9:\"shop_page\";i:0;s:20:\"other_included_pages\";a:0:{}}','auto'),(174,'webpc_is_new_installation','1','auto'),(175,'webpc_notice_thanks','1765581302','auto'),(176,'webpc_notice_pro_version','1764976502','auto'),(177,'webpc_stats_installation_date','2025-11-28 23:15:02','auto'),(178,'webpc_stats_first_version','6.3.2','auto'); +INSERT INTO `wp_options` VALUES (1,'cron','a:12:{i:1764363747;a:1:{s:32:\"recovery_mode_clean_expired_keys\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:5:\"daily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:86400;}}}i:1764363748;a:1:{s:34:\"wp_privacy_delete_old_export_files\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:6:\"hourly\";s:4:\"args\";a:0:{}s:8:\"interval\";i:3600;}}}i:1764367344;a:1:{s:16:\"wp_version_check\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:10:\"twicedaily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:43200;}}}i:1764369115;a:1:{s:30:\"wp_delete_temp_updater_backups\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:6:\"weekly\";s:4:\"args\";a:0:{}s:8:\"interval\";i:604800;}}}i:1764369116;a:1:{s:27:\"acf_update_site_health_data\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:6:\"weekly\";s:4:\"args\";a:0:{}s:8:\"interval\";i:604800;}}}i:1764369144;a:1:{s:17:\"wp_update_plugins\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:10:\"twicedaily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:43200;}}}i:1764370944;a:1:{s:16:\"wp_update_themes\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:10:\"twicedaily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:43200;}}}i:1764371307;a:1:{s:31:\"wpseo_permalink_structure_check\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:5:\"daily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:86400;}}}i:1764371970;a:4:{s:26:\"aios_15_minutes_cron_event\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:21:\"aios-every-15-minutes\";s:4:\"args\";a:0:{}s:8:\"interval\";i:900;}}s:24:\"aiowps_hourly_cron_event\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:6:\"hourly\";s:4:\"args\";a:0:{}s:8:\"interval\";i:3600;}}s:23:\"aiowps_daily_cron_event\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:5:\"daily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:86400;}}s:24:\"aiowps_weekly_cron_event\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:6:\"weekly\";s:4:\"args\";a:0:{}s:8:\"interval\";i:604800;}}}i:1764371978;a:1:{s:23:\"aiowps_clean_old_events\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:5:\"daily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:86400;}}}i:1764450148;a:1:{s:30:\"wp_site_health_scheduled_check\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:6:\"weekly\";s:4:\"args\";a:0:{}s:8:\"interval\";i:604800;}}}s:7:\"version\";i:2;}','on'),(2,'siteurl','https://homeproz.dev.hanson.xyz','on'),(3,'home','https://homeproz.dev.hanson.xyz','on'),(4,'blogname','HomeProz','on'),(5,'blogdescription','','on'),(6,'users_can_register','0','on'),(7,'admin_email','brian@hanson.xyz','on'),(8,'start_of_week','1','on'),(9,'use_balanceTags','0','on'),(10,'use_smilies','1','on'),(11,'require_name_email','1','on'),(12,'comments_notify','1','on'),(13,'posts_per_rss','10','on'),(14,'rss_use_excerpt','0','on'),(15,'mailserver_url','mail.example.com','on'),(16,'mailserver_login','login@example.com','on'),(17,'mailserver_pass','','on'),(18,'mailserver_port','110','on'),(19,'default_category','1','on'),(20,'default_comment_status','open','on'),(21,'default_ping_status','open','on'),(22,'default_pingback_flag','1','on'),(23,'posts_per_page','10','on'),(24,'date_format','F j, Y','on'),(25,'time_format','g:i a','on'),(26,'links_updated_date_format','F j, Y g:i a','on'),(27,'comment_moderation','0','on'),(28,'moderation_notify','1','on'),(29,'permalink_structure','/%postname%/','on'),(30,'rewrite_rules','a:133:{s:11:\"^wp-json/?$\";s:22:\"index.php?rest_route=/\";s:14:\"^wp-json/(.*)?\";s:33:\"index.php?rest_route=/$matches[1]\";s:21:\"^index.php/wp-json/?$\";s:22:\"index.php?rest_route=/\";s:24:\"^index.php/wp-json/(.*)?\";s:33:\"index.php?rest_route=/$matches[1]\";s:17:\"^wp-sitemap\\.xml$\";s:23:\"index.php?sitemap=index\";s:17:\"^wp-sitemap\\.xsl$\";s:36:\"index.php?sitemap-stylesheet=sitemap\";s:23:\"^wp-sitemap-index\\.xsl$\";s:34:\"index.php?sitemap-stylesheet=index\";s:48:\"^wp-sitemap-([a-z]+?)-([a-z\\d_-]+?)-(\\d+?)\\.xml$\";s:75:\"index.php?sitemap=$matches[1]&sitemap-subtype=$matches[2]&paged=$matches[3]\";s:34:\"^wp-sitemap-([a-z]+?)-(\\d+?)\\.xml$\";s:47:\"index.php?sitemap=$matches[1]&paged=$matches[2]\";s:13:\"properties/?$\";s:28:\"index.php?post_type=property\";s:43:\"properties/feed/(feed|rdf|rss|rss2|atom)/?$\";s:45:\"index.php?post_type=property&feed=$matches[1]\";s:38:\"properties/(feed|rdf|rss|rss2|atom)/?$\";s:45:\"index.php?post_type=property&feed=$matches[1]\";s:30:\"properties/page/([0-9]{1,})/?$\";s:46:\"index.php?post_type=property&paged=$matches[1]\";s:47:\"category/(.+?)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:52:\"index.php?category_name=$matches[1]&feed=$matches[2]\";s:42:\"category/(.+?)/(feed|rdf|rss|rss2|atom)/?$\";s:52:\"index.php?category_name=$matches[1]&feed=$matches[2]\";s:23:\"category/(.+?)/embed/?$\";s:46:\"index.php?category_name=$matches[1]&embed=true\";s:35:\"category/(.+?)/page/?([0-9]{1,})/?$\";s:53:\"index.php?category_name=$matches[1]&paged=$matches[2]\";s:17:\"category/(.+?)/?$\";s:35:\"index.php?category_name=$matches[1]\";s:44:\"tag/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:42:\"index.php?tag=$matches[1]&feed=$matches[2]\";s:39:\"tag/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:42:\"index.php?tag=$matches[1]&feed=$matches[2]\";s:20:\"tag/([^/]+)/embed/?$\";s:36:\"index.php?tag=$matches[1]&embed=true\";s:32:\"tag/([^/]+)/page/?([0-9]{1,})/?$\";s:43:\"index.php?tag=$matches[1]&paged=$matches[2]\";s:14:\"tag/([^/]+)/?$\";s:25:\"index.php?tag=$matches[1]\";s:45:\"type/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:50:\"index.php?post_format=$matches[1]&feed=$matches[2]\";s:40:\"type/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:50:\"index.php?post_format=$matches[1]&feed=$matches[2]\";s:21:\"type/([^/]+)/embed/?$\";s:44:\"index.php?post_format=$matches[1]&embed=true\";s:33:\"type/([^/]+)/page/?([0-9]{1,})/?$\";s:51:\"index.php?post_format=$matches[1]&paged=$matches[2]\";s:15:\"type/([^/]+)/?$\";s:33:\"index.php?post_format=$matches[1]\";s:38:\"properties/[^/]+/attachment/([^/]+)/?$\";s:32:\"index.php?attachment=$matches[1]\";s:48:\"properties/[^/]+/attachment/([^/]+)/trackback/?$\";s:37:\"index.php?attachment=$matches[1]&tb=1\";s:68:\"properties/[^/]+/attachment/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:63:\"properties/[^/]+/attachment/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:63:\"properties/[^/]+/attachment/([^/]+)/comment-page-([0-9]{1,})/?$\";s:50:\"index.php?attachment=$matches[1]&cpage=$matches[2]\";s:44:\"properties/[^/]+/attachment/([^/]+)/embed/?$\";s:43:\"index.php?attachment=$matches[1]&embed=true\";s:27:\"properties/([^/]+)/embed/?$\";s:41:\"index.php?property=$matches[1]&embed=true\";s:31:\"properties/([^/]+)/trackback/?$\";s:35:\"index.php?property=$matches[1]&tb=1\";s:51:\"properties/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:47:\"index.php?property=$matches[1]&feed=$matches[2]\";s:46:\"properties/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:47:\"index.php?property=$matches[1]&feed=$matches[2]\";s:39:\"properties/([^/]+)/page/?([0-9]{1,})/?$\";s:48:\"index.php?property=$matches[1]&paged=$matches[2]\";s:46:\"properties/([^/]+)/comment-page-([0-9]{1,})/?$\";s:48:\"index.php?property=$matches[1]&cpage=$matches[2]\";s:35:\"properties/([^/]+)(?:/([0-9]+))?/?$\";s:47:\"index.php?property=$matches[1]&page=$matches[2]\";s:27:\"properties/[^/]+/([^/]+)/?$\";s:32:\"index.php?attachment=$matches[1]\";s:37:\"properties/[^/]+/([^/]+)/trackback/?$\";s:37:\"index.php?attachment=$matches[1]&tb=1\";s:57:\"properties/[^/]+/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:52:\"properties/[^/]+/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:52:\"properties/[^/]+/([^/]+)/comment-page-([0-9]{1,})/?$\";s:50:\"index.php?attachment=$matches[1]&cpage=$matches[2]\";s:33:\"properties/[^/]+/([^/]+)/embed/?$\";s:43:\"index.php?attachment=$matches[1]&embed=true\";s:54:\"property-type/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:52:\"index.php?property_type=$matches[1]&feed=$matches[2]\";s:49:\"property-type/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:52:\"index.php?property_type=$matches[1]&feed=$matches[2]\";s:30:\"property-type/([^/]+)/embed/?$\";s:46:\"index.php?property_type=$matches[1]&embed=true\";s:42:\"property-type/([^/]+)/page/?([0-9]{1,})/?$\";s:53:\"index.php?property_type=$matches[1]&paged=$matches[2]\";s:24:\"property-type/([^/]+)/?$\";s:35:\"index.php?property_type=$matches[1]\";s:56:\"property-status/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:54:\"index.php?property_status=$matches[1]&feed=$matches[2]\";s:51:\"property-status/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:54:\"index.php?property_status=$matches[1]&feed=$matches[2]\";s:32:\"property-status/([^/]+)/embed/?$\";s:48:\"index.php?property_status=$matches[1]&embed=true\";s:44:\"property-status/([^/]+)/page/?([0-9]{1,})/?$\";s:55:\"index.php?property_status=$matches[1]&paged=$matches[2]\";s:26:\"property-status/([^/]+)/?$\";s:37:\"index.php?property_status=$matches[1]\";s:49:\"location/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:56:\"index.php?property_location=$matches[1]&feed=$matches[2]\";s:44:\"location/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:56:\"index.php?property_location=$matches[1]&feed=$matches[2]\";s:25:\"location/([^/]+)/embed/?$\";s:50:\"index.php?property_location=$matches[1]&embed=true\";s:37:\"location/([^/]+)/page/?([0-9]{1,})/?$\";s:57:\"index.php?property_location=$matches[1]&paged=$matches[2]\";s:19:\"location/([^/]+)/?$\";s:39:\"index.php?property_location=$matches[1]\";s:12:\"robots\\.txt$\";s:18:\"index.php?robots=1\";s:13:\"favicon\\.ico$\";s:19:\"index.php?favicon=1\";s:12:\"sitemap\\.xml\";s:24:\"index.php??sitemap=index\";s:48:\".*wp-(atom|rdf|rss|rss2|feed|commentsrss2)\\.php$\";s:18:\"index.php?feed=old\";s:20:\".*wp-app\\.php(/.*)?$\";s:19:\"index.php?error=403\";s:18:\".*wp-register.php$\";s:23:\"index.php?register=true\";s:32:\"feed/(feed|rdf|rss|rss2|atom)/?$\";s:27:\"index.php?&feed=$matches[1]\";s:27:\"(feed|rdf|rss|rss2|atom)/?$\";s:27:\"index.php?&feed=$matches[1]\";s:8:\"embed/?$\";s:21:\"index.php?&embed=true\";s:20:\"page/?([0-9]{1,})/?$\";s:28:\"index.php?&paged=$matches[1]\";s:27:\"comment-page-([0-9]{1,})/?$\";s:39:\"index.php?&page_id=10&cpage=$matches[1]\";s:41:\"comments/feed/(feed|rdf|rss|rss2|atom)/?$\";s:42:\"index.php?&feed=$matches[1]&withcomments=1\";s:36:\"comments/(feed|rdf|rss|rss2|atom)/?$\";s:42:\"index.php?&feed=$matches[1]&withcomments=1\";s:17:\"comments/embed/?$\";s:21:\"index.php?&embed=true\";s:44:\"search/(.+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:40:\"index.php?s=$matches[1]&feed=$matches[2]\";s:39:\"search/(.+)/(feed|rdf|rss|rss2|atom)/?$\";s:40:\"index.php?s=$matches[1]&feed=$matches[2]\";s:20:\"search/(.+)/embed/?$\";s:34:\"index.php?s=$matches[1]&embed=true\";s:32:\"search/(.+)/page/?([0-9]{1,})/?$\";s:41:\"index.php?s=$matches[1]&paged=$matches[2]\";s:14:\"search/(.+)/?$\";s:23:\"index.php?s=$matches[1]\";s:47:\"author/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:50:\"index.php?author_name=$matches[1]&feed=$matches[2]\";s:42:\"author/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:50:\"index.php?author_name=$matches[1]&feed=$matches[2]\";s:23:\"author/([^/]+)/embed/?$\";s:44:\"index.php?author_name=$matches[1]&embed=true\";s:35:\"author/([^/]+)/page/?([0-9]{1,})/?$\";s:51:\"index.php?author_name=$matches[1]&paged=$matches[2]\";s:17:\"author/([^/]+)/?$\";s:33:\"index.php?author_name=$matches[1]\";s:69:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/feed/(feed|rdf|rss|rss2|atom)/?$\";s:80:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&feed=$matches[4]\";s:64:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/(feed|rdf|rss|rss2|atom)/?$\";s:80:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&feed=$matches[4]\";s:45:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/embed/?$\";s:74:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&embed=true\";s:57:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/page/?([0-9]{1,})/?$\";s:81:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&paged=$matches[4]\";s:39:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/?$\";s:63:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]\";s:56:\"([0-9]{4})/([0-9]{1,2})/feed/(feed|rdf|rss|rss2|atom)/?$\";s:64:\"index.php?year=$matches[1]&monthnum=$matches[2]&feed=$matches[3]\";s:51:\"([0-9]{4})/([0-9]{1,2})/(feed|rdf|rss|rss2|atom)/?$\";s:64:\"index.php?year=$matches[1]&monthnum=$matches[2]&feed=$matches[3]\";s:32:\"([0-9]{4})/([0-9]{1,2})/embed/?$\";s:58:\"index.php?year=$matches[1]&monthnum=$matches[2]&embed=true\";s:44:\"([0-9]{4})/([0-9]{1,2})/page/?([0-9]{1,})/?$\";s:65:\"index.php?year=$matches[1]&monthnum=$matches[2]&paged=$matches[3]\";s:26:\"([0-9]{4})/([0-9]{1,2})/?$\";s:47:\"index.php?year=$matches[1]&monthnum=$matches[2]\";s:43:\"([0-9]{4})/feed/(feed|rdf|rss|rss2|atom)/?$\";s:43:\"index.php?year=$matches[1]&feed=$matches[2]\";s:38:\"([0-9]{4})/(feed|rdf|rss|rss2|atom)/?$\";s:43:\"index.php?year=$matches[1]&feed=$matches[2]\";s:19:\"([0-9]{4})/embed/?$\";s:37:\"index.php?year=$matches[1]&embed=true\";s:31:\"([0-9]{4})/page/?([0-9]{1,})/?$\";s:44:\"index.php?year=$matches[1]&paged=$matches[2]\";s:13:\"([0-9]{4})/?$\";s:26:\"index.php?year=$matches[1]\";s:27:\".?.+?/attachment/([^/]+)/?$\";s:32:\"index.php?attachment=$matches[1]\";s:37:\".?.+?/attachment/([^/]+)/trackback/?$\";s:37:\"index.php?attachment=$matches[1]&tb=1\";s:57:\".?.+?/attachment/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:52:\".?.+?/attachment/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:52:\".?.+?/attachment/([^/]+)/comment-page-([0-9]{1,})/?$\";s:50:\"index.php?attachment=$matches[1]&cpage=$matches[2]\";s:33:\".?.+?/attachment/([^/]+)/embed/?$\";s:43:\"index.php?attachment=$matches[1]&embed=true\";s:16:\"(.?.+?)/embed/?$\";s:41:\"index.php?pagename=$matches[1]&embed=true\";s:20:\"(.?.+?)/trackback/?$\";s:35:\"index.php?pagename=$matches[1]&tb=1\";s:40:\"(.?.+?)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:47:\"index.php?pagename=$matches[1]&feed=$matches[2]\";s:35:\"(.?.+?)/(feed|rdf|rss|rss2|atom)/?$\";s:47:\"index.php?pagename=$matches[1]&feed=$matches[2]\";s:28:\"(.?.+?)/page/?([0-9]{1,})/?$\";s:48:\"index.php?pagename=$matches[1]&paged=$matches[2]\";s:35:\"(.?.+?)/comment-page-([0-9]{1,})/?$\";s:48:\"index.php?pagename=$matches[1]&cpage=$matches[2]\";s:24:\"(.?.+?)(?:/([0-9]+))?/?$\";s:47:\"index.php?pagename=$matches[1]&page=$matches[2]\";s:27:\"[^/]+/attachment/([^/]+)/?$\";s:32:\"index.php?attachment=$matches[1]\";s:37:\"[^/]+/attachment/([^/]+)/trackback/?$\";s:37:\"index.php?attachment=$matches[1]&tb=1\";s:57:\"[^/]+/attachment/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:52:\"[^/]+/attachment/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:52:\"[^/]+/attachment/([^/]+)/comment-page-([0-9]{1,})/?$\";s:50:\"index.php?attachment=$matches[1]&cpage=$matches[2]\";s:33:\"[^/]+/attachment/([^/]+)/embed/?$\";s:43:\"index.php?attachment=$matches[1]&embed=true\";s:16:\"([^/]+)/embed/?$\";s:37:\"index.php?name=$matches[1]&embed=true\";s:20:\"([^/]+)/trackback/?$\";s:31:\"index.php?name=$matches[1]&tb=1\";s:40:\"([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:43:\"index.php?name=$matches[1]&feed=$matches[2]\";s:35:\"([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:43:\"index.php?name=$matches[1]&feed=$matches[2]\";s:28:\"([^/]+)/page/?([0-9]{1,})/?$\";s:44:\"index.php?name=$matches[1]&paged=$matches[2]\";s:35:\"([^/]+)/comment-page-([0-9]{1,})/?$\";s:44:\"index.php?name=$matches[1]&cpage=$matches[2]\";s:24:\"([^/]+)(?:/([0-9]+))?/?$\";s:43:\"index.php?name=$matches[1]&page=$matches[2]\";s:16:\"[^/]+/([^/]+)/?$\";s:32:\"index.php?attachment=$matches[1]\";s:26:\"[^/]+/([^/]+)/trackback/?$\";s:37:\"index.php?attachment=$matches[1]&tb=1\";s:46:\"[^/]+/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:41:\"[^/]+/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:41:\"[^/]+/([^/]+)/comment-page-([0-9]{1,})/?$\";s:50:\"index.php?attachment=$matches[1]&cpage=$matches[2]\";s:22:\"[^/]+/([^/]+)/embed/?$\";s:43:\"index.php?attachment=$matches[1]&embed=true\";}','on'),(31,'hack_file','0','on'),(32,'blog_charset','UTF-8','on'),(33,'moderation_keys','','off'),(34,'active_plugins','a:5:{i:0;s:30:\"advanced-custom-fields/acf.php\";i:1;s:51:\"all-in-one-wp-security-and-firewall/wp-security.php\";i:2;s:36:\"contact-form-7/wp-contact-form-7.php\";i:3;s:53:\"webp-converter-for-media/webp-converter-for-media.php\";i:4;s:24:\"wordpress-seo/wp-seo.php\";}','on'),(35,'category_base','','on'),(36,'ping_sites','https://rpc.pingomatic.com/','on'),(37,'comment_max_links','2','on'),(38,'gmt_offset','0','on'),(39,'default_email_category','1','on'),(40,'recently_edited','','off'),(41,'template','homeproz','on'),(42,'stylesheet','homeproz','on'),(43,'comment_registration','0','on'),(44,'html_type','text/html','on'),(45,'use_trackback','0','on'),(46,'default_role','subscriber','on'),(47,'db_version','60421','on'),(48,'uploads_use_yearmonth_folders','1','on'),(49,'upload_path','','on'),(50,'blog_public','1','on'),(51,'default_link_category','2','on'),(52,'show_on_front','page','on'),(53,'tag_base','','on'),(54,'show_avatars','1','on'),(55,'avatar_rating','G','on'),(56,'upload_url_path','','on'),(57,'thumbnail_size_w','150','on'),(58,'thumbnail_size_h','150','on'),(59,'thumbnail_crop','1','on'),(60,'medium_size_w','300','on'),(61,'medium_size_h','300','on'),(62,'avatar_default','mystery','on'),(63,'large_size_w','1024','on'),(64,'large_size_h','1024','on'),(65,'image_default_link_type','none','on'),(66,'image_default_size','','on'),(67,'image_default_align','','on'),(68,'close_comments_for_old_posts','0','on'),(69,'close_comments_days_old','14','on'),(70,'thread_comments','1','on'),(71,'thread_comments_depth','5','on'),(72,'page_comments','0','on'),(73,'comments_per_page','50','on'),(74,'default_comments_page','newest','on'),(75,'comment_order','asc','on'),(76,'sticky_posts','a:0:{}','on'),(77,'widget_categories','a:0:{}','on'),(78,'widget_text','a:0:{}','on'),(79,'widget_rss','a:0:{}','on'),(80,'uninstall_plugins','a:3:{s:24:\"wordpress-seo/wp-seo.php\";s:14:\"__return_false\";s:53:\"webp-converter-for-media/webp-converter-for-media.php\";a:2:{i:0;s:37:\"WebpConverter\\Plugin\\UninstallHandler\";i:1;s:22:\"load_uninstall_actions\";}s:51:\"all-in-one-wp-security-and-firewall/wp-security.php\";a:2:{i:0;s:15:\"AIO_WP_Security\";i:1;s:17:\"uninstall_handler\";}}','off'),(81,'timezone_string','','on'),(82,'page_for_posts','9','on'),(83,'page_on_front','10','on'),(84,'default_post_format','0','on'),(85,'link_manager_enabled','0','on'),(86,'finished_splitting_shared_terms','1','on'),(87,'site_icon','0','on'),(88,'medium_large_size_w','768','on'),(89,'medium_large_size_h','0','on'),(90,'wp_page_for_privacy_policy','3','on'),(91,'show_comments_cookies_opt_in','1','on'),(92,'admin_email_lifespan','1779915744','on'),(93,'disallowed_keys','','off'),(94,'comment_previously_approved','1','on'),(95,'auto_plugin_theme_update_emails','a:0:{}','off'),(96,'auto_update_core_dev','enabled','on'),(97,'auto_update_core_minor','enabled','on'),(98,'auto_update_core_major','enabled','on'),(99,'wp_force_deactivated_plugins','a:0:{}','on'),(100,'wp_attachment_pages_enabled','1','on'),(101,'initial_db_version','60421','on'),(102,'wp_user_roles','a:7:{s:13:\"administrator\";a:2:{s:4:\"name\";s:13:\"Administrator\";s:12:\"capabilities\";a:62:{s:13:\"switch_themes\";b:1;s:11:\"edit_themes\";b:1;s:16:\"activate_plugins\";b:1;s:12:\"edit_plugins\";b:1;s:10:\"edit_users\";b:1;s:10:\"edit_files\";b:1;s:14:\"manage_options\";b:1;s:17:\"moderate_comments\";b:1;s:17:\"manage_categories\";b:1;s:12:\"manage_links\";b:1;s:12:\"upload_files\";b:1;s:6:\"import\";b:1;s:15:\"unfiltered_html\";b:1;s:10:\"edit_posts\";b:1;s:17:\"edit_others_posts\";b:1;s:20:\"edit_published_posts\";b:1;s:13:\"publish_posts\";b:1;s:10:\"edit_pages\";b:1;s:4:\"read\";b:1;s:8:\"level_10\";b:1;s:7:\"level_9\";b:1;s:7:\"level_8\";b:1;s:7:\"level_7\";b:1;s:7:\"level_6\";b:1;s:7:\"level_5\";b:1;s:7:\"level_4\";b:1;s:7:\"level_3\";b:1;s:7:\"level_2\";b:1;s:7:\"level_1\";b:1;s:7:\"level_0\";b:1;s:17:\"edit_others_pages\";b:1;s:20:\"edit_published_pages\";b:1;s:13:\"publish_pages\";b:1;s:12:\"delete_pages\";b:1;s:19:\"delete_others_pages\";b:1;s:22:\"delete_published_pages\";b:1;s:12:\"delete_posts\";b:1;s:19:\"delete_others_posts\";b:1;s:22:\"delete_published_posts\";b:1;s:20:\"delete_private_posts\";b:1;s:18:\"edit_private_posts\";b:1;s:18:\"read_private_posts\";b:1;s:20:\"delete_private_pages\";b:1;s:18:\"edit_private_pages\";b:1;s:18:\"read_private_pages\";b:1;s:12:\"delete_users\";b:1;s:12:\"create_users\";b:1;s:17:\"unfiltered_upload\";b:1;s:14:\"edit_dashboard\";b:1;s:14:\"update_plugins\";b:1;s:14:\"delete_plugins\";b:1;s:15:\"install_plugins\";b:1;s:13:\"update_themes\";b:1;s:14:\"install_themes\";b:1;s:11:\"update_core\";b:1;s:10:\"list_users\";b:1;s:12:\"remove_users\";b:1;s:13:\"promote_users\";b:1;s:18:\"edit_theme_options\";b:1;s:13:\"delete_themes\";b:1;s:6:\"export\";b:1;s:20:\"wpseo_manage_options\";b:1;}}s:6:\"editor\";a:2:{s:4:\"name\";s:6:\"Editor\";s:12:\"capabilities\";a:36:{s:17:\"moderate_comments\";b:1;s:17:\"manage_categories\";b:1;s:12:\"manage_links\";b:1;s:12:\"upload_files\";b:1;s:15:\"unfiltered_html\";b:1;s:10:\"edit_posts\";b:1;s:17:\"edit_others_posts\";b:1;s:20:\"edit_published_posts\";b:1;s:13:\"publish_posts\";b:1;s:10:\"edit_pages\";b:1;s:4:\"read\";b:1;s:7:\"level_7\";b:1;s:7:\"level_6\";b:1;s:7:\"level_5\";b:1;s:7:\"level_4\";b:1;s:7:\"level_3\";b:1;s:7:\"level_2\";b:1;s:7:\"level_1\";b:1;s:7:\"level_0\";b:1;s:17:\"edit_others_pages\";b:1;s:20:\"edit_published_pages\";b:1;s:13:\"publish_pages\";b:1;s:12:\"delete_pages\";b:1;s:19:\"delete_others_pages\";b:1;s:22:\"delete_published_pages\";b:1;s:12:\"delete_posts\";b:1;s:19:\"delete_others_posts\";b:1;s:22:\"delete_published_posts\";b:1;s:20:\"delete_private_posts\";b:1;s:18:\"edit_private_posts\";b:1;s:18:\"read_private_posts\";b:1;s:20:\"delete_private_pages\";b:1;s:18:\"edit_private_pages\";b:1;s:18:\"read_private_pages\";b:1;s:15:\"wpseo_bulk_edit\";b:1;s:28:\"wpseo_edit_advanced_metadata\";b:1;}}s:6:\"author\";a:2:{s:4:\"name\";s:6:\"Author\";s:12:\"capabilities\";a:10:{s:12:\"upload_files\";b:1;s:10:\"edit_posts\";b:1;s:20:\"edit_published_posts\";b:1;s:13:\"publish_posts\";b:1;s:4:\"read\";b:1;s:7:\"level_2\";b:1;s:7:\"level_1\";b:1;s:7:\"level_0\";b:1;s:12:\"delete_posts\";b:1;s:22:\"delete_published_posts\";b:1;}}s:11:\"contributor\";a:2:{s:4:\"name\";s:11:\"Contributor\";s:12:\"capabilities\";a:5:{s:10:\"edit_posts\";b:1;s:4:\"read\";b:1;s:7:\"level_1\";b:1;s:7:\"level_0\";b:1;s:12:\"delete_posts\";b:1;}}s:10:\"subscriber\";a:2:{s:4:\"name\";s:10:\"Subscriber\";s:12:\"capabilities\";a:2:{s:4:\"read\";b:1;s:7:\"level_0\";b:1;}}s:13:\"wpseo_manager\";a:2:{s:4:\"name\";s:11:\"SEO Manager\";s:12:\"capabilities\";a:38:{s:17:\"moderate_comments\";b:1;s:17:\"manage_categories\";b:1;s:12:\"manage_links\";b:1;s:12:\"upload_files\";b:1;s:15:\"unfiltered_html\";b:1;s:10:\"edit_posts\";b:1;s:17:\"edit_others_posts\";b:1;s:20:\"edit_published_posts\";b:1;s:13:\"publish_posts\";b:1;s:10:\"edit_pages\";b:1;s:4:\"read\";b:1;s:7:\"level_7\";b:1;s:7:\"level_6\";b:1;s:7:\"level_5\";b:1;s:7:\"level_4\";b:1;s:7:\"level_3\";b:1;s:7:\"level_2\";b:1;s:7:\"level_1\";b:1;s:7:\"level_0\";b:1;s:17:\"edit_others_pages\";b:1;s:20:\"edit_published_pages\";b:1;s:13:\"publish_pages\";b:1;s:12:\"delete_pages\";b:1;s:19:\"delete_others_pages\";b:1;s:22:\"delete_published_pages\";b:1;s:12:\"delete_posts\";b:1;s:19:\"delete_others_posts\";b:1;s:22:\"delete_published_posts\";b:1;s:20:\"delete_private_posts\";b:1;s:18:\"edit_private_posts\";b:1;s:18:\"read_private_posts\";b:1;s:20:\"delete_private_pages\";b:1;s:18:\"edit_private_pages\";b:1;s:18:\"read_private_pages\";b:1;s:15:\"wpseo_bulk_edit\";b:1;s:28:\"wpseo_edit_advanced_metadata\";b:1;s:20:\"wpseo_manage_options\";b:1;s:23:\"view_site_health_checks\";b:1;}}s:12:\"wpseo_editor\";a:2:{s:4:\"name\";s:10:\"SEO Editor\";s:12:\"capabilities\";a:36:{s:17:\"moderate_comments\";b:1;s:17:\"manage_categories\";b:1;s:12:\"manage_links\";b:1;s:12:\"upload_files\";b:1;s:15:\"unfiltered_html\";b:1;s:10:\"edit_posts\";b:1;s:17:\"edit_others_posts\";b:1;s:20:\"edit_published_posts\";b:1;s:13:\"publish_posts\";b:1;s:10:\"edit_pages\";b:1;s:4:\"read\";b:1;s:7:\"level_7\";b:1;s:7:\"level_6\";b:1;s:7:\"level_5\";b:1;s:7:\"level_4\";b:1;s:7:\"level_3\";b:1;s:7:\"level_2\";b:1;s:7:\"level_1\";b:1;s:7:\"level_0\";b:1;s:17:\"edit_others_pages\";b:1;s:20:\"edit_published_pages\";b:1;s:13:\"publish_pages\";b:1;s:12:\"delete_pages\";b:1;s:19:\"delete_others_pages\";b:1;s:22:\"delete_published_pages\";b:1;s:12:\"delete_posts\";b:1;s:19:\"delete_others_posts\";b:1;s:22:\"delete_published_posts\";b:1;s:20:\"delete_private_posts\";b:1;s:18:\"edit_private_posts\";b:1;s:18:\"read_private_posts\";b:1;s:20:\"delete_private_pages\";b:1;s:18:\"edit_private_pages\";b:1;s:18:\"read_private_pages\";b:1;s:15:\"wpseo_bulk_edit\";b:1;s:28:\"wpseo_edit_advanced_metadata\";b:1;}}}','on'),(103,'fresh_site','0','off'),(104,'user_count','1','off'),(105,'widget_block','a:6:{i:2;a:1:{s:7:\"content\";s:19:\"\";}i:3;a:1:{s:7:\"content\";s:154:\"

Recent Posts

\";}i:4;a:1:{s:7:\"content\";s:227:\"

Recent Comments

\";}i:5;a:1:{s:7:\"content\";s:146:\"

Archives

\";}i:6;a:1:{s:7:\"content\";s:150:\"

Categories

\";}s:12:\"_multiwidget\";i:1;}','auto'),(106,'sidebars_widgets','a:2:{s:19:\"wp_inactive_widgets\";a:5:{i:0;s:7:\"block-2\";i:1;s:7:\"block-3\";i:2;s:7:\"block-4\";i:3;s:7:\"block-5\";i:4;s:7:\"block-6\";}s:13:\"array_version\";i:3;}','auto'),(107,'widget_pages','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(108,'widget_calendar','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(109,'widget_archives','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(110,'widget_media_audio','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(111,'widget_media_image','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(112,'widget_media_gallery','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(113,'widget_media_video','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(114,'widget_meta','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(115,'widget_search','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(116,'widget_recent-posts','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(117,'widget_recent-comments','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(118,'widget_tag_cloud','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(119,'widget_nav_menu','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(120,'widget_custom_html','a:1:{s:12:\"_multiwidget\";i:1;}','auto'),(121,'_transient_wp_core_block_css_files','a:2:{s:7:\"version\";s:5:\"6.8.3\";s:5:\"files\";a:536:{i:0;s:23:\"archives/editor-rtl.css\";i:1;s:27:\"archives/editor-rtl.min.css\";i:2;s:19:\"archives/editor.css\";i:3;s:23:\"archives/editor.min.css\";i:4;s:22:\"archives/style-rtl.css\";i:5;s:26:\"archives/style-rtl.min.css\";i:6;s:18:\"archives/style.css\";i:7;s:22:\"archives/style.min.css\";i:8;s:20:\"audio/editor-rtl.css\";i:9;s:24:\"audio/editor-rtl.min.css\";i:10;s:16:\"audio/editor.css\";i:11;s:20:\"audio/editor.min.css\";i:12;s:19:\"audio/style-rtl.css\";i:13;s:23:\"audio/style-rtl.min.css\";i:14;s:15:\"audio/style.css\";i:15;s:19:\"audio/style.min.css\";i:16;s:19:\"audio/theme-rtl.css\";i:17;s:23:\"audio/theme-rtl.min.css\";i:18;s:15:\"audio/theme.css\";i:19;s:19:\"audio/theme.min.css\";i:20;s:21:\"avatar/editor-rtl.css\";i:21;s:25:\"avatar/editor-rtl.min.css\";i:22;s:17:\"avatar/editor.css\";i:23;s:21:\"avatar/editor.min.css\";i:24;s:20:\"avatar/style-rtl.css\";i:25;s:24:\"avatar/style-rtl.min.css\";i:26;s:16:\"avatar/style.css\";i:27;s:20:\"avatar/style.min.css\";i:28;s:21:\"button/editor-rtl.css\";i:29;s:25:\"button/editor-rtl.min.css\";i:30;s:17:\"button/editor.css\";i:31;s:21:\"button/editor.min.css\";i:32;s:20:\"button/style-rtl.css\";i:33;s:24:\"button/style-rtl.min.css\";i:34;s:16:\"button/style.css\";i:35;s:20:\"button/style.min.css\";i:36;s:22:\"buttons/editor-rtl.css\";i:37;s:26:\"buttons/editor-rtl.min.css\";i:38;s:18:\"buttons/editor.css\";i:39;s:22:\"buttons/editor.min.css\";i:40;s:21:\"buttons/style-rtl.css\";i:41;s:25:\"buttons/style-rtl.min.css\";i:42;s:17:\"buttons/style.css\";i:43;s:21:\"buttons/style.min.css\";i:44;s:22:\"calendar/style-rtl.css\";i:45;s:26:\"calendar/style-rtl.min.css\";i:46;s:18:\"calendar/style.css\";i:47;s:22:\"calendar/style.min.css\";i:48;s:25:\"categories/editor-rtl.css\";i:49;s:29:\"categories/editor-rtl.min.css\";i:50;s:21:\"categories/editor.css\";i:51;s:25:\"categories/editor.min.css\";i:52;s:24:\"categories/style-rtl.css\";i:53;s:28:\"categories/style-rtl.min.css\";i:54;s:20:\"categories/style.css\";i:55;s:24:\"categories/style.min.css\";i:56;s:19:\"code/editor-rtl.css\";i:57;s:23:\"code/editor-rtl.min.css\";i:58;s:15:\"code/editor.css\";i:59;s:19:\"code/editor.min.css\";i:60;s:18:\"code/style-rtl.css\";i:61;s:22:\"code/style-rtl.min.css\";i:62;s:14:\"code/style.css\";i:63;s:18:\"code/style.min.css\";i:64;s:18:\"code/theme-rtl.css\";i:65;s:22:\"code/theme-rtl.min.css\";i:66;s:14:\"code/theme.css\";i:67;s:18:\"code/theme.min.css\";i:68;s:22:\"columns/editor-rtl.css\";i:69;s:26:\"columns/editor-rtl.min.css\";i:70;s:18:\"columns/editor.css\";i:71;s:22:\"columns/editor.min.css\";i:72;s:21:\"columns/style-rtl.css\";i:73;s:25:\"columns/style-rtl.min.css\";i:74;s:17:\"columns/style.css\";i:75;s:21:\"columns/style.min.css\";i:76;s:33:\"comment-author-name/style-rtl.css\";i:77;s:37:\"comment-author-name/style-rtl.min.css\";i:78;s:29:\"comment-author-name/style.css\";i:79;s:33:\"comment-author-name/style.min.css\";i:80;s:29:\"comment-content/style-rtl.css\";i:81;s:33:\"comment-content/style-rtl.min.css\";i:82;s:25:\"comment-content/style.css\";i:83;s:29:\"comment-content/style.min.css\";i:84;s:26:\"comment-date/style-rtl.css\";i:85;s:30:\"comment-date/style-rtl.min.css\";i:86;s:22:\"comment-date/style.css\";i:87;s:26:\"comment-date/style.min.css\";i:88;s:31:\"comment-edit-link/style-rtl.css\";i:89;s:35:\"comment-edit-link/style-rtl.min.css\";i:90;s:27:\"comment-edit-link/style.css\";i:91;s:31:\"comment-edit-link/style.min.css\";i:92;s:32:\"comment-reply-link/style-rtl.css\";i:93;s:36:\"comment-reply-link/style-rtl.min.css\";i:94;s:28:\"comment-reply-link/style.css\";i:95;s:32:\"comment-reply-link/style.min.css\";i:96;s:30:\"comment-template/style-rtl.css\";i:97;s:34:\"comment-template/style-rtl.min.css\";i:98;s:26:\"comment-template/style.css\";i:99;s:30:\"comment-template/style.min.css\";i:100;s:42:\"comments-pagination-numbers/editor-rtl.css\";i:101;s:46:\"comments-pagination-numbers/editor-rtl.min.css\";i:102;s:38:\"comments-pagination-numbers/editor.css\";i:103;s:42:\"comments-pagination-numbers/editor.min.css\";i:104;s:34:\"comments-pagination/editor-rtl.css\";i:105;s:38:\"comments-pagination/editor-rtl.min.css\";i:106;s:30:\"comments-pagination/editor.css\";i:107;s:34:\"comments-pagination/editor.min.css\";i:108;s:33:\"comments-pagination/style-rtl.css\";i:109;s:37:\"comments-pagination/style-rtl.min.css\";i:110;s:29:\"comments-pagination/style.css\";i:111;s:33:\"comments-pagination/style.min.css\";i:112;s:29:\"comments-title/editor-rtl.css\";i:113;s:33:\"comments-title/editor-rtl.min.css\";i:114;s:25:\"comments-title/editor.css\";i:115;s:29:\"comments-title/editor.min.css\";i:116;s:23:\"comments/editor-rtl.css\";i:117;s:27:\"comments/editor-rtl.min.css\";i:118;s:19:\"comments/editor.css\";i:119;s:23:\"comments/editor.min.css\";i:120;s:22:\"comments/style-rtl.css\";i:121;s:26:\"comments/style-rtl.min.css\";i:122;s:18:\"comments/style.css\";i:123;s:22:\"comments/style.min.css\";i:124;s:20:\"cover/editor-rtl.css\";i:125;s:24:\"cover/editor-rtl.min.css\";i:126;s:16:\"cover/editor.css\";i:127;s:20:\"cover/editor.min.css\";i:128;s:19:\"cover/style-rtl.css\";i:129;s:23:\"cover/style-rtl.min.css\";i:130;s:15:\"cover/style.css\";i:131;s:19:\"cover/style.min.css\";i:132;s:22:\"details/editor-rtl.css\";i:133;s:26:\"details/editor-rtl.min.css\";i:134;s:18:\"details/editor.css\";i:135;s:22:\"details/editor.min.css\";i:136;s:21:\"details/style-rtl.css\";i:137;s:25:\"details/style-rtl.min.css\";i:138;s:17:\"details/style.css\";i:139;s:21:\"details/style.min.css\";i:140;s:20:\"embed/editor-rtl.css\";i:141;s:24:\"embed/editor-rtl.min.css\";i:142;s:16:\"embed/editor.css\";i:143;s:20:\"embed/editor.min.css\";i:144;s:19:\"embed/style-rtl.css\";i:145;s:23:\"embed/style-rtl.min.css\";i:146;s:15:\"embed/style.css\";i:147;s:19:\"embed/style.min.css\";i:148;s:19:\"embed/theme-rtl.css\";i:149;s:23:\"embed/theme-rtl.min.css\";i:150;s:15:\"embed/theme.css\";i:151;s:19:\"embed/theme.min.css\";i:152;s:19:\"file/editor-rtl.css\";i:153;s:23:\"file/editor-rtl.min.css\";i:154;s:15:\"file/editor.css\";i:155;s:19:\"file/editor.min.css\";i:156;s:18:\"file/style-rtl.css\";i:157;s:22:\"file/style-rtl.min.css\";i:158;s:14:\"file/style.css\";i:159;s:18:\"file/style.min.css\";i:160;s:23:\"footnotes/style-rtl.css\";i:161;s:27:\"footnotes/style-rtl.min.css\";i:162;s:19:\"footnotes/style.css\";i:163;s:23:\"footnotes/style.min.css\";i:164;s:23:\"freeform/editor-rtl.css\";i:165;s:27:\"freeform/editor-rtl.min.css\";i:166;s:19:\"freeform/editor.css\";i:167;s:23:\"freeform/editor.min.css\";i:168;s:22:\"gallery/editor-rtl.css\";i:169;s:26:\"gallery/editor-rtl.min.css\";i:170;s:18:\"gallery/editor.css\";i:171;s:22:\"gallery/editor.min.css\";i:172;s:21:\"gallery/style-rtl.css\";i:173;s:25:\"gallery/style-rtl.min.css\";i:174;s:17:\"gallery/style.css\";i:175;s:21:\"gallery/style.min.css\";i:176;s:21:\"gallery/theme-rtl.css\";i:177;s:25:\"gallery/theme-rtl.min.css\";i:178;s:17:\"gallery/theme.css\";i:179;s:21:\"gallery/theme.min.css\";i:180;s:20:\"group/editor-rtl.css\";i:181;s:24:\"group/editor-rtl.min.css\";i:182;s:16:\"group/editor.css\";i:183;s:20:\"group/editor.min.css\";i:184;s:19:\"group/style-rtl.css\";i:185;s:23:\"group/style-rtl.min.css\";i:186;s:15:\"group/style.css\";i:187;s:19:\"group/style.min.css\";i:188;s:19:\"group/theme-rtl.css\";i:189;s:23:\"group/theme-rtl.min.css\";i:190;s:15:\"group/theme.css\";i:191;s:19:\"group/theme.min.css\";i:192;s:21:\"heading/style-rtl.css\";i:193;s:25:\"heading/style-rtl.min.css\";i:194;s:17:\"heading/style.css\";i:195;s:21:\"heading/style.min.css\";i:196;s:19:\"html/editor-rtl.css\";i:197;s:23:\"html/editor-rtl.min.css\";i:198;s:15:\"html/editor.css\";i:199;s:19:\"html/editor.min.css\";i:200;s:20:\"image/editor-rtl.css\";i:201;s:24:\"image/editor-rtl.min.css\";i:202;s:16:\"image/editor.css\";i:203;s:20:\"image/editor.min.css\";i:204;s:19:\"image/style-rtl.css\";i:205;s:23:\"image/style-rtl.min.css\";i:206;s:15:\"image/style.css\";i:207;s:19:\"image/style.min.css\";i:208;s:19:\"image/theme-rtl.css\";i:209;s:23:\"image/theme-rtl.min.css\";i:210;s:15:\"image/theme.css\";i:211;s:19:\"image/theme.min.css\";i:212;s:29:\"latest-comments/style-rtl.css\";i:213;s:33:\"latest-comments/style-rtl.min.css\";i:214;s:25:\"latest-comments/style.css\";i:215;s:29:\"latest-comments/style.min.css\";i:216;s:27:\"latest-posts/editor-rtl.css\";i:217;s:31:\"latest-posts/editor-rtl.min.css\";i:218;s:23:\"latest-posts/editor.css\";i:219;s:27:\"latest-posts/editor.min.css\";i:220;s:26:\"latest-posts/style-rtl.css\";i:221;s:30:\"latest-posts/style-rtl.min.css\";i:222;s:22:\"latest-posts/style.css\";i:223;s:26:\"latest-posts/style.min.css\";i:224;s:18:\"list/style-rtl.css\";i:225;s:22:\"list/style-rtl.min.css\";i:226;s:14:\"list/style.css\";i:227;s:18:\"list/style.min.css\";i:228;s:22:\"loginout/style-rtl.css\";i:229;s:26:\"loginout/style-rtl.min.css\";i:230;s:18:\"loginout/style.css\";i:231;s:22:\"loginout/style.min.css\";i:232;s:25:\"media-text/editor-rtl.css\";i:233;s:29:\"media-text/editor-rtl.min.css\";i:234;s:21:\"media-text/editor.css\";i:235;s:25:\"media-text/editor.min.css\";i:236;s:24:\"media-text/style-rtl.css\";i:237;s:28:\"media-text/style-rtl.min.css\";i:238;s:20:\"media-text/style.css\";i:239;s:24:\"media-text/style.min.css\";i:240;s:19:\"more/editor-rtl.css\";i:241;s:23:\"more/editor-rtl.min.css\";i:242;s:15:\"more/editor.css\";i:243;s:19:\"more/editor.min.css\";i:244;s:30:\"navigation-link/editor-rtl.css\";i:245;s:34:\"navigation-link/editor-rtl.min.css\";i:246;s:26:\"navigation-link/editor.css\";i:247;s:30:\"navigation-link/editor.min.css\";i:248;s:29:\"navigation-link/style-rtl.css\";i:249;s:33:\"navigation-link/style-rtl.min.css\";i:250;s:25:\"navigation-link/style.css\";i:251;s:29:\"navigation-link/style.min.css\";i:252;s:33:\"navigation-submenu/editor-rtl.css\";i:253;s:37:\"navigation-submenu/editor-rtl.min.css\";i:254;s:29:\"navigation-submenu/editor.css\";i:255;s:33:\"navigation-submenu/editor.min.css\";i:256;s:25:\"navigation/editor-rtl.css\";i:257;s:29:\"navigation/editor-rtl.min.css\";i:258;s:21:\"navigation/editor.css\";i:259;s:25:\"navigation/editor.min.css\";i:260;s:24:\"navigation/style-rtl.css\";i:261;s:28:\"navigation/style-rtl.min.css\";i:262;s:20:\"navigation/style.css\";i:263;s:24:\"navigation/style.min.css\";i:264;s:23:\"nextpage/editor-rtl.css\";i:265;s:27:\"nextpage/editor-rtl.min.css\";i:266;s:19:\"nextpage/editor.css\";i:267;s:23:\"nextpage/editor.min.css\";i:268;s:24:\"page-list/editor-rtl.css\";i:269;s:28:\"page-list/editor-rtl.min.css\";i:270;s:20:\"page-list/editor.css\";i:271;s:24:\"page-list/editor.min.css\";i:272;s:23:\"page-list/style-rtl.css\";i:273;s:27:\"page-list/style-rtl.min.css\";i:274;s:19:\"page-list/style.css\";i:275;s:23:\"page-list/style.min.css\";i:276;s:24:\"paragraph/editor-rtl.css\";i:277;s:28:\"paragraph/editor-rtl.min.css\";i:278;s:20:\"paragraph/editor.css\";i:279;s:24:\"paragraph/editor.min.css\";i:280;s:23:\"paragraph/style-rtl.css\";i:281;s:27:\"paragraph/style-rtl.min.css\";i:282;s:19:\"paragraph/style.css\";i:283;s:23:\"paragraph/style.min.css\";i:284;s:35:\"post-author-biography/style-rtl.css\";i:285;s:39:\"post-author-biography/style-rtl.min.css\";i:286;s:31:\"post-author-biography/style.css\";i:287;s:35:\"post-author-biography/style.min.css\";i:288;s:30:\"post-author-name/style-rtl.css\";i:289;s:34:\"post-author-name/style-rtl.min.css\";i:290;s:26:\"post-author-name/style.css\";i:291;s:30:\"post-author-name/style.min.css\";i:292;s:26:\"post-author/editor-rtl.css\";i:293;s:30:\"post-author/editor-rtl.min.css\";i:294;s:22:\"post-author/editor.css\";i:295;s:26:\"post-author/editor.min.css\";i:296;s:25:\"post-author/style-rtl.css\";i:297;s:29:\"post-author/style-rtl.min.css\";i:298;s:21:\"post-author/style.css\";i:299;s:25:\"post-author/style.min.css\";i:300;s:33:\"post-comments-form/editor-rtl.css\";i:301;s:37:\"post-comments-form/editor-rtl.min.css\";i:302;s:29:\"post-comments-form/editor.css\";i:303;s:33:\"post-comments-form/editor.min.css\";i:304;s:32:\"post-comments-form/style-rtl.css\";i:305;s:36:\"post-comments-form/style-rtl.min.css\";i:306;s:28:\"post-comments-form/style.css\";i:307;s:32:\"post-comments-form/style.min.css\";i:308;s:26:\"post-content/style-rtl.css\";i:309;s:30:\"post-content/style-rtl.min.css\";i:310;s:22:\"post-content/style.css\";i:311;s:26:\"post-content/style.min.css\";i:312;s:23:\"post-date/style-rtl.css\";i:313;s:27:\"post-date/style-rtl.min.css\";i:314;s:19:\"post-date/style.css\";i:315;s:23:\"post-date/style.min.css\";i:316;s:27:\"post-excerpt/editor-rtl.css\";i:317;s:31:\"post-excerpt/editor-rtl.min.css\";i:318;s:23:\"post-excerpt/editor.css\";i:319;s:27:\"post-excerpt/editor.min.css\";i:320;s:26:\"post-excerpt/style-rtl.css\";i:321;s:30:\"post-excerpt/style-rtl.min.css\";i:322;s:22:\"post-excerpt/style.css\";i:323;s:26:\"post-excerpt/style.min.css\";i:324;s:34:\"post-featured-image/editor-rtl.css\";i:325;s:38:\"post-featured-image/editor-rtl.min.css\";i:326;s:30:\"post-featured-image/editor.css\";i:327;s:34:\"post-featured-image/editor.min.css\";i:328;s:33:\"post-featured-image/style-rtl.css\";i:329;s:37:\"post-featured-image/style-rtl.min.css\";i:330;s:29:\"post-featured-image/style.css\";i:331;s:33:\"post-featured-image/style.min.css\";i:332;s:34:\"post-navigation-link/style-rtl.css\";i:333;s:38:\"post-navigation-link/style-rtl.min.css\";i:334;s:30:\"post-navigation-link/style.css\";i:335;s:34:\"post-navigation-link/style.min.css\";i:336;s:27:\"post-template/style-rtl.css\";i:337;s:31:\"post-template/style-rtl.min.css\";i:338;s:23:\"post-template/style.css\";i:339;s:27:\"post-template/style.min.css\";i:340;s:24:\"post-terms/style-rtl.css\";i:341;s:28:\"post-terms/style-rtl.min.css\";i:342;s:20:\"post-terms/style.css\";i:343;s:24:\"post-terms/style.min.css\";i:344;s:24:\"post-title/style-rtl.css\";i:345;s:28:\"post-title/style-rtl.min.css\";i:346;s:20:\"post-title/style.css\";i:347;s:24:\"post-title/style.min.css\";i:348;s:26:\"preformatted/style-rtl.css\";i:349;s:30:\"preformatted/style-rtl.min.css\";i:350;s:22:\"preformatted/style.css\";i:351;s:26:\"preformatted/style.min.css\";i:352;s:24:\"pullquote/editor-rtl.css\";i:353;s:28:\"pullquote/editor-rtl.min.css\";i:354;s:20:\"pullquote/editor.css\";i:355;s:24:\"pullquote/editor.min.css\";i:356;s:23:\"pullquote/style-rtl.css\";i:357;s:27:\"pullquote/style-rtl.min.css\";i:358;s:19:\"pullquote/style.css\";i:359;s:23:\"pullquote/style.min.css\";i:360;s:23:\"pullquote/theme-rtl.css\";i:361;s:27:\"pullquote/theme-rtl.min.css\";i:362;s:19:\"pullquote/theme.css\";i:363;s:23:\"pullquote/theme.min.css\";i:364;s:39:\"query-pagination-numbers/editor-rtl.css\";i:365;s:43:\"query-pagination-numbers/editor-rtl.min.css\";i:366;s:35:\"query-pagination-numbers/editor.css\";i:367;s:39:\"query-pagination-numbers/editor.min.css\";i:368;s:31:\"query-pagination/editor-rtl.css\";i:369;s:35:\"query-pagination/editor-rtl.min.css\";i:370;s:27:\"query-pagination/editor.css\";i:371;s:31:\"query-pagination/editor.min.css\";i:372;s:30:\"query-pagination/style-rtl.css\";i:373;s:34:\"query-pagination/style-rtl.min.css\";i:374;s:26:\"query-pagination/style.css\";i:375;s:30:\"query-pagination/style.min.css\";i:376;s:25:\"query-title/style-rtl.css\";i:377;s:29:\"query-title/style-rtl.min.css\";i:378;s:21:\"query-title/style.css\";i:379;s:25:\"query-title/style.min.css\";i:380;s:25:\"query-total/style-rtl.css\";i:381;s:29:\"query-total/style-rtl.min.css\";i:382;s:21:\"query-total/style.css\";i:383;s:25:\"query-total/style.min.css\";i:384;s:20:\"query/editor-rtl.css\";i:385;s:24:\"query/editor-rtl.min.css\";i:386;s:16:\"query/editor.css\";i:387;s:20:\"query/editor.min.css\";i:388;s:19:\"quote/style-rtl.css\";i:389;s:23:\"quote/style-rtl.min.css\";i:390;s:15:\"quote/style.css\";i:391;s:19:\"quote/style.min.css\";i:392;s:19:\"quote/theme-rtl.css\";i:393;s:23:\"quote/theme-rtl.min.css\";i:394;s:15:\"quote/theme.css\";i:395;s:19:\"quote/theme.min.css\";i:396;s:23:\"read-more/style-rtl.css\";i:397;s:27:\"read-more/style-rtl.min.css\";i:398;s:19:\"read-more/style.css\";i:399;s:23:\"read-more/style.min.css\";i:400;s:18:\"rss/editor-rtl.css\";i:401;s:22:\"rss/editor-rtl.min.css\";i:402;s:14:\"rss/editor.css\";i:403;s:18:\"rss/editor.min.css\";i:404;s:17:\"rss/style-rtl.css\";i:405;s:21:\"rss/style-rtl.min.css\";i:406;s:13:\"rss/style.css\";i:407;s:17:\"rss/style.min.css\";i:408;s:21:\"search/editor-rtl.css\";i:409;s:25:\"search/editor-rtl.min.css\";i:410;s:17:\"search/editor.css\";i:411;s:21:\"search/editor.min.css\";i:412;s:20:\"search/style-rtl.css\";i:413;s:24:\"search/style-rtl.min.css\";i:414;s:16:\"search/style.css\";i:415;s:20:\"search/style.min.css\";i:416;s:20:\"search/theme-rtl.css\";i:417;s:24:\"search/theme-rtl.min.css\";i:418;s:16:\"search/theme.css\";i:419;s:20:\"search/theme.min.css\";i:420;s:24:\"separator/editor-rtl.css\";i:421;s:28:\"separator/editor-rtl.min.css\";i:422;s:20:\"separator/editor.css\";i:423;s:24:\"separator/editor.min.css\";i:424;s:23:\"separator/style-rtl.css\";i:425;s:27:\"separator/style-rtl.min.css\";i:426;s:19:\"separator/style.css\";i:427;s:23:\"separator/style.min.css\";i:428;s:23:\"separator/theme-rtl.css\";i:429;s:27:\"separator/theme-rtl.min.css\";i:430;s:19:\"separator/theme.css\";i:431;s:23:\"separator/theme.min.css\";i:432;s:24:\"shortcode/editor-rtl.css\";i:433;s:28:\"shortcode/editor-rtl.min.css\";i:434;s:20:\"shortcode/editor.css\";i:435;s:24:\"shortcode/editor.min.css\";i:436;s:24:\"site-logo/editor-rtl.css\";i:437;s:28:\"site-logo/editor-rtl.min.css\";i:438;s:20:\"site-logo/editor.css\";i:439;s:24:\"site-logo/editor.min.css\";i:440;s:23:\"site-logo/style-rtl.css\";i:441;s:27:\"site-logo/style-rtl.min.css\";i:442;s:19:\"site-logo/style.css\";i:443;s:23:\"site-logo/style.min.css\";i:444;s:27:\"site-tagline/editor-rtl.css\";i:445;s:31:\"site-tagline/editor-rtl.min.css\";i:446;s:23:\"site-tagline/editor.css\";i:447;s:27:\"site-tagline/editor.min.css\";i:448;s:26:\"site-tagline/style-rtl.css\";i:449;s:30:\"site-tagline/style-rtl.min.css\";i:450;s:22:\"site-tagline/style.css\";i:451;s:26:\"site-tagline/style.min.css\";i:452;s:25:\"site-title/editor-rtl.css\";i:453;s:29:\"site-title/editor-rtl.min.css\";i:454;s:21:\"site-title/editor.css\";i:455;s:25:\"site-title/editor.min.css\";i:456;s:24:\"site-title/style-rtl.css\";i:457;s:28:\"site-title/style-rtl.min.css\";i:458;s:20:\"site-title/style.css\";i:459;s:24:\"site-title/style.min.css\";i:460;s:26:\"social-link/editor-rtl.css\";i:461;s:30:\"social-link/editor-rtl.min.css\";i:462;s:22:\"social-link/editor.css\";i:463;s:26:\"social-link/editor.min.css\";i:464;s:27:\"social-links/editor-rtl.css\";i:465;s:31:\"social-links/editor-rtl.min.css\";i:466;s:23:\"social-links/editor.css\";i:467;s:27:\"social-links/editor.min.css\";i:468;s:26:\"social-links/style-rtl.css\";i:469;s:30:\"social-links/style-rtl.min.css\";i:470;s:22:\"social-links/style.css\";i:471;s:26:\"social-links/style.min.css\";i:472;s:21:\"spacer/editor-rtl.css\";i:473;s:25:\"spacer/editor-rtl.min.css\";i:474;s:17:\"spacer/editor.css\";i:475;s:21:\"spacer/editor.min.css\";i:476;s:20:\"spacer/style-rtl.css\";i:477;s:24:\"spacer/style-rtl.min.css\";i:478;s:16:\"spacer/style.css\";i:479;s:20:\"spacer/style.min.css\";i:480;s:20:\"table/editor-rtl.css\";i:481;s:24:\"table/editor-rtl.min.css\";i:482;s:16:\"table/editor.css\";i:483;s:20:\"table/editor.min.css\";i:484;s:19:\"table/style-rtl.css\";i:485;s:23:\"table/style-rtl.min.css\";i:486;s:15:\"table/style.css\";i:487;s:19:\"table/style.min.css\";i:488;s:19:\"table/theme-rtl.css\";i:489;s:23:\"table/theme-rtl.min.css\";i:490;s:15:\"table/theme.css\";i:491;s:19:\"table/theme.min.css\";i:492;s:24:\"tag-cloud/editor-rtl.css\";i:493;s:28:\"tag-cloud/editor-rtl.min.css\";i:494;s:20:\"tag-cloud/editor.css\";i:495;s:24:\"tag-cloud/editor.min.css\";i:496;s:23:\"tag-cloud/style-rtl.css\";i:497;s:27:\"tag-cloud/style-rtl.min.css\";i:498;s:19:\"tag-cloud/style.css\";i:499;s:23:\"tag-cloud/style.min.css\";i:500;s:28:\"template-part/editor-rtl.css\";i:501;s:32:\"template-part/editor-rtl.min.css\";i:502;s:24:\"template-part/editor.css\";i:503;s:28:\"template-part/editor.min.css\";i:504;s:27:\"template-part/theme-rtl.css\";i:505;s:31:\"template-part/theme-rtl.min.css\";i:506;s:23:\"template-part/theme.css\";i:507;s:27:\"template-part/theme.min.css\";i:508;s:30:\"term-description/style-rtl.css\";i:509;s:34:\"term-description/style-rtl.min.css\";i:510;s:26:\"term-description/style.css\";i:511;s:30:\"term-description/style.min.css\";i:512;s:27:\"text-columns/editor-rtl.css\";i:513;s:31:\"text-columns/editor-rtl.min.css\";i:514;s:23:\"text-columns/editor.css\";i:515;s:27:\"text-columns/editor.min.css\";i:516;s:26:\"text-columns/style-rtl.css\";i:517;s:30:\"text-columns/style-rtl.min.css\";i:518;s:22:\"text-columns/style.css\";i:519;s:26:\"text-columns/style.min.css\";i:520;s:19:\"verse/style-rtl.css\";i:521;s:23:\"verse/style-rtl.min.css\";i:522;s:15:\"verse/style.css\";i:523;s:19:\"verse/style.min.css\";i:524;s:20:\"video/editor-rtl.css\";i:525;s:24:\"video/editor-rtl.min.css\";i:526;s:16:\"video/editor.css\";i:527;s:20:\"video/editor.min.css\";i:528;s:19:\"video/style-rtl.css\";i:529;s:23:\"video/style-rtl.min.css\";i:530;s:15:\"video/style.css\";i:531;s:19:\"video/style.min.css\";i:532;s:19:\"video/theme-rtl.css\";i:533;s:23:\"video/theme-rtl.min.css\";i:534;s:15:\"video/theme.css\";i:535;s:19:\"video/theme.min.css\";}}','on'),(124,'_transient_doing_cron','1764371989.4203000068664550781250','on'),(125,'theme_mods_twentytwentyfive','a:2:{s:18:\"custom_css_post_id\";i:-1;s:16:\"sidebars_widgets\";a:2:{s:4:\"time\";i:1764367183;s:4:\"data\";a:3:{s:19:\"wp_inactive_widgets\";a:0:{}s:9:\"sidebar-1\";a:3:{i:0;s:7:\"block-2\";i:1;s:7:\"block-3\";i:2;s:7:\"block-4\";}s:9:\"sidebar-2\";a:2:{i:0;s:7:\"block-5\";i:1;s:7:\"block-6\";}}}}','off'),(126,'_transient_wp_styles_for_blocks','a:2:{s:4:\"hash\";s:32:\"64ad95698215776f80fa1e80f2eb5417\";s:6:\"blocks\";a:7:{s:11:\"core/button\";s:0:\"\";s:14:\"core/site-logo\";s:0:\"\";s:18:\"core/post-template\";s:0:\"\";s:12:\"core/columns\";s:0:\"\";s:14:\"core/pullquote\";s:121:\":root :where(.wp-block-pullquote){font-size: clamp(0.984em, 0.984rem + ((1vw - 0.2em) * 0.938), 1.5em);line-height: 1.6;}\";s:15:\"core/site-title\";s:89:\":root :where(.wp-block-site-title){font-family: var(--wp--preset--font-family--display);}\";s:15:\"core/navigation\";s:86:\":root :where(.wp-block-navigation){font-family: var(--wp--preset--font-family--body);}\";}}','on'),(129,'category_children','a:0:{}','auto'),(132,'_site_transient_update_themes','O:8:\"stdClass\":5:{s:12:\"last_checked\";i:1764371969;s:7:\"checked\";a:4:{s:8:\"homeproz\";s:5:\"1.0.0\";s:16:\"twentytwentyfive\";s:3:\"1.3\";s:16:\"twentytwentyfour\";s:3:\"1.3\";s:17:\"twentytwentythree\";s:3:\"1.6\";}s:8:\"response\";a:0:{}s:9:\"no_update\";a:3:{s:16:\"twentytwentyfive\";a:6:{s:5:\"theme\";s:16:\"twentytwentyfive\";s:11:\"new_version\";s:3:\"1.3\";s:3:\"url\";s:46:\"https://wordpress.org/themes/twentytwentyfive/\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/theme/twentytwentyfive.1.3.zip\";s:8:\"requires\";s:3:\"6.7\";s:12:\"requires_php\";s:3:\"7.2\";}s:16:\"twentytwentyfour\";a:6:{s:5:\"theme\";s:16:\"twentytwentyfour\";s:11:\"new_version\";s:3:\"1.3\";s:3:\"url\";s:46:\"https://wordpress.org/themes/twentytwentyfour/\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/theme/twentytwentyfour.1.3.zip\";s:8:\"requires\";s:3:\"6.4\";s:12:\"requires_php\";s:3:\"7.0\";}s:17:\"twentytwentythree\";a:6:{s:5:\"theme\";s:17:\"twentytwentythree\";s:11:\"new_version\";s:3:\"1.6\";s:3:\"url\";s:47:\"https://wordpress.org/themes/twentytwentythree/\";s:7:\"package\";s:63:\"https://downloads.wordpress.org/theme/twentytwentythree.1.6.zip\";s:8:\"requires\";s:3:\"6.1\";s:12:\"requires_php\";s:3:\"5.6\";}}s:12:\"translations\";a:0:{}}','off'),(133,'current_theme','HomeProz','auto'),(134,'theme_switched','','auto'),(135,'theme_mods_homeproz','a:2:{s:18:\"nav_menu_locations\";a:1:{s:7:\"primary\";i:15;}s:18:\"custom_css_post_id\";i:-1;}','auto'),(141,'property_type_children','a:0:{}','auto'),(144,'property_status_children','a:0:{}','auto'),(150,'property_location_children','a:0:{}','auto'),(152,'_site_transient_update_core','O:8:\"stdClass\":4:{s:7:\"updates\";a:1:{i:0;O:8:\"stdClass\":10:{s:8:\"response\";s:6:\"latest\";s:8:\"download\";s:59:\"https://downloads.wordpress.org/release/wordpress-6.8.3.zip\";s:6:\"locale\";s:5:\"en_US\";s:8:\"packages\";O:8:\"stdClass\":5:{s:4:\"full\";s:59:\"https://downloads.wordpress.org/release/wordpress-6.8.3.zip\";s:10:\"no_content\";s:70:\"https://downloads.wordpress.org/release/wordpress-6.8.3-no-content.zip\";s:11:\"new_bundled\";s:71:\"https://downloads.wordpress.org/release/wordpress-6.8.3-new-bundled.zip\";s:7:\"partial\";s:0:\"\";s:8:\"rollback\";s:0:\"\";}s:7:\"current\";s:5:\"6.8.3\";s:7:\"version\";s:5:\"6.8.3\";s:11:\"php_version\";s:6:\"7.2.24\";s:13:\"mysql_version\";s:5:\"5.5.5\";s:11:\"new_bundled\";s:3:\"6.7\";s:15:\"partial_version\";s:0:\"\";}}s:12:\"last_checked\";i:1764371969;s:15:\"version_checked\";s:5:\"6.8.3\";s:12:\"translations\";a:0:{}}','off'),(156,'acf_first_activated_version','6.6.2','on'),(157,'acf_site_health','{\"event_first_activated\":1764369116,\"last_updated\":1764369116}','off'),(158,'_site_transient_timeout_wp_theme_files_patterns-2aae27f1f26ef7a6be8ebee5c8a6a86b','1764372438','off'),(159,'_site_transient_wp_theme_files_patterns-2aae27f1f26ef7a6be8ebee5c8a6a86b','a:2:{s:7:\"version\";s:5:\"1.0.0\";s:8:\"patterns\";a:0:{}}','off'),(162,'wpcf7','a:2:{s:7:\"version\";s:5:\"6.1.3\";s:13:\"bulk_validate\";a:4:{s:9:\"timestamp\";i:1764370639;s:7:\"version\";s:5:\"6.1.3\";s:11:\"count_valid\";i:1;s:13:\"count_invalid\";i:0;}}','auto'),(165,'_site_transient_timeout_theme_roots','1764373103','off'),(166,'_site_transient_theme_roots','a:4:{s:8:\"homeproz\";s:7:\"/themes\";s:16:\"twentytwentyfive\";s:7:\"/themes\";s:16:\"twentytwentyfour\";s:7:\"/themes\";s:17:\"twentytwentythree\";s:7:\"/themes\";}','off'),(167,'yoast_migrations_free','a:1:{s:7:\"version\";s:4:\"26.4\";}','auto'),(168,'wpseo','a:120:{s:8:\"tracking\";b:0;s:16:\"toggled_tracking\";b:0;s:22:\"license_server_version\";b:0;s:15:\"ms_defaults_set\";b:0;s:40:\"ignore_search_engines_discouraged_notice\";b:0;s:19:\"indexing_first_time\";b:1;s:16:\"indexing_started\";b:0;s:15:\"indexing_reason\";s:24:\"attachments_made_enabled\";s:29:\"indexables_indexing_completed\";b:0;s:13:\"index_now_key\";s:0:\"\";s:7:\"version\";s:4:\"26.4\";s:16:\"previous_version\";s:0:\"\";s:20:\"disableadvanced_meta\";b:1;s:30:\"enable_headless_rest_endpoints\";b:1;s:17:\"ryte_indexability\";b:0;s:11:\"baiduverify\";s:0:\"\";s:12:\"googleverify\";s:0:\"\";s:8:\"msverify\";s:0:\"\";s:12:\"yandexverify\";s:0:\"\";s:12:\"ahrefsverify\";s:0:\"\";s:9:\"site_type\";s:0:\"\";s:20:\"has_multiple_authors\";s:0:\"\";s:16:\"environment_type\";s:0:\"\";s:23:\"content_analysis_active\";b:1;s:23:\"keyword_analysis_active\";b:1;s:34:\"inclusive_language_analysis_active\";b:0;s:21:\"enable_admin_bar_menu\";b:1;s:26:\"enable_cornerstone_content\";b:1;s:18:\"enable_xml_sitemap\";b:1;s:24:\"enable_text_link_counter\";b:1;s:16:\"enable_index_now\";b:1;s:19:\"enable_ai_generator\";b:1;s:22:\"ai_enabled_pre_default\";b:0;s:22:\"show_onboarding_notice\";b:1;s:18:\"first_activated_on\";i:1764371307;s:13:\"myyoast-oauth\";b:0;s:26:\"semrush_integration_active\";b:1;s:14:\"semrush_tokens\";a:0:{}s:20:\"semrush_country_code\";s:2:\"us\";s:19:\"permalink_structure\";s:0:\"\";s:8:\"home_url\";s:0:\"\";s:18:\"dynamic_permalinks\";b:0;s:17:\"category_base_url\";s:0:\"\";s:12:\"tag_base_url\";s:0:\"\";s:21:\"custom_taxonomy_slugs\";a:0:{}s:29:\"enable_enhanced_slack_sharing\";b:1;s:23:\"enable_metabox_insights\";b:1;s:23:\"enable_link_suggestions\";b:1;s:26:\"algolia_integration_active\";b:0;s:14:\"import_cursors\";a:0:{}s:13:\"workouts_data\";a:1:{s:13:\"configuration\";a:1:{s:13:\"finishedSteps\";a:0:{}}}s:28:\"configuration_finished_steps\";a:0:{}s:36:\"dismiss_configuration_workout_notice\";b:0;s:34:\"dismiss_premium_deactivated_notice\";b:0;s:19:\"importing_completed\";a:0:{}s:26:\"wincher_integration_active\";b:1;s:14:\"wincher_tokens\";a:0:{}s:36:\"wincher_automatically_add_keyphrases\";b:0;s:18:\"wincher_website_id\";s:0:\"\";s:18:\"first_time_install\";b:1;s:34:\"should_redirect_after_install_free\";b:0;s:34:\"activation_redirect_timestamp_free\";i:1764371307;s:18:\"remove_feed_global\";b:0;s:27:\"remove_feed_global_comments\";b:0;s:25:\"remove_feed_post_comments\";b:0;s:19:\"remove_feed_authors\";b:0;s:22:\"remove_feed_categories\";b:0;s:16:\"remove_feed_tags\";b:0;s:29:\"remove_feed_custom_taxonomies\";b:0;s:22:\"remove_feed_post_types\";b:0;s:18:\"remove_feed_search\";b:0;s:21:\"remove_atom_rdf_feeds\";b:0;s:17:\"remove_shortlinks\";b:0;s:21:\"remove_rest_api_links\";b:0;s:20:\"remove_rsd_wlw_links\";b:0;s:19:\"remove_oembed_links\";b:0;s:16:\"remove_generator\";b:0;s:20:\"remove_emoji_scripts\";b:0;s:24:\"remove_powered_by_header\";b:0;s:22:\"remove_pingback_header\";b:0;s:28:\"clean_campaign_tracking_urls\";b:0;s:16:\"clean_permalinks\";b:0;s:32:\"clean_permalinks_extra_variables\";s:0:\"\";s:14:\"search_cleanup\";b:0;s:20:\"search_cleanup_emoji\";b:0;s:23:\"search_cleanup_patterns\";b:0;s:22:\"search_character_limit\";i:50;s:20:\"deny_search_crawling\";b:0;s:21:\"deny_wp_json_crawling\";b:0;s:20:\"deny_adsbot_crawling\";b:0;s:19:\"deny_ccbot_crawling\";b:0;s:29:\"deny_google_extended_crawling\";b:0;s:20:\"deny_gptbot_crawling\";b:0;s:27:\"redirect_search_pretty_urls\";b:0;s:29:\"least_readability_ignore_list\";a:0:{}s:27:\"least_seo_score_ignore_list\";a:0:{}s:23:\"most_linked_ignore_list\";a:0:{}s:24:\"least_linked_ignore_list\";a:0:{}s:28:\"indexables_page_reading_list\";a:5:{i:0;b:0;i:1;b:0;i:2;b:0;i:3;b:0;i:4;b:0;}s:25:\"indexables_overview_state\";s:21:\"dashboard-not-visited\";s:28:\"last_known_public_post_types\";a:0:{}s:28:\"last_known_public_taxonomies\";a:0:{}s:23:\"last_known_no_unindexed\";a:0:{}s:14:\"new_post_types\";a:0:{}s:14:\"new_taxonomies\";a:0:{}s:34:\"show_new_content_type_notification\";b:0;s:44:\"site_kit_configuration_permanently_dismissed\";b:0;s:18:\"site_kit_connected\";b:0;s:37:\"site_kit_tracking_setup_widget_loaded\";s:2:\"no\";s:41:\"site_kit_tracking_first_interaction_stage\";s:0:\"\";s:40:\"site_kit_tracking_last_interaction_stage\";s:0:\"\";s:52:\"site_kit_tracking_setup_widget_temporarily_dismissed\";s:2:\"no\";s:52:\"site_kit_tracking_setup_widget_permanently_dismissed\";s:2:\"no\";s:31:\"google_site_kit_feature_enabled\";b:0;s:25:\"ai_free_sparks_started_on\";N;s:15:\"enable_llms_txt\";b:0;s:15:\"last_updated_on\";b:0;s:17:\"default_seo_title\";a:0:{}s:21:\"default_seo_meta_desc\";a:0:{}s:18:\"first_activated_by\";i:0;}','auto'),(169,'wpseo_titles','a:173:{s:17:\"forcerewritetitle\";b:0;s:9:\"separator\";s:7:\"sc-dash\";s:16:\"title-home-wpseo\";s:47:\"HomeProz Real Estate | Albert Lea MN Properties\";s:18:\"title-author-wpseo\";s:41:\"%%name%%, Author at %%sitename%% %%page%%\";s:19:\"title-archive-wpseo\";s:38:\"%%date%% %%page%% %%sep%% %%sitename%%\";s:18:\"title-search-wpseo\";s:63:\"You searched for %%searchphrase%% %%page%% %%sep%% %%sitename%%\";s:15:\"title-404-wpseo\";s:35:\"Page not found %%sep%% %%sitename%%\";s:25:\"social-title-author-wpseo\";s:8:\"%%name%%\";s:26:\"social-title-archive-wpseo\";s:8:\"%%date%%\";s:31:\"social-description-author-wpseo\";s:0:\"\";s:32:\"social-description-archive-wpseo\";s:0:\"\";s:29:\"social-image-url-author-wpseo\";s:0:\"\";s:30:\"social-image-url-archive-wpseo\";s:0:\"\";s:28:\"social-image-id-author-wpseo\";i:0;s:29:\"social-image-id-archive-wpseo\";i:0;s:19:\"metadesc-home-wpseo\";s:120:\"HomeProz Real Estate - Your trusted partner for buying and selling homes in Albert Lea, Minnesota and surrounding areas.\";s:21:\"metadesc-author-wpseo\";s:0:\"\";s:22:\"metadesc-archive-wpseo\";s:0:\"\";s:9:\"rssbefore\";s:0:\"\";s:8:\"rssafter\";s:53:\"The post %%POSTLINK%% appeared first on %%BLOGLINK%%.\";s:20:\"noindex-author-wpseo\";b:0;s:28:\"noindex-author-noposts-wpseo\";b:0;s:21:\"noindex-archive-wpseo\";b:0;s:14:\"disable-author\";b:0;s:12:\"disable-date\";b:0;s:19:\"disable-post_format\";b:0;s:18:\"disable-attachment\";b:0;s:20:\"breadcrumbs-404crumb\";s:25:\"Error 404: Page not found\";s:29:\"breadcrumbs-display-blog-page\";b:0;s:20:\"breadcrumbs-boldlast\";b:0;s:25:\"breadcrumbs-archiveprefix\";s:12:\"Archives for\";s:18:\"breadcrumbs-enable\";b:0;s:16:\"breadcrumbs-home\";s:4:\"Home\";s:18:\"breadcrumbs-prefix\";s:0:\"\";s:24:\"breadcrumbs-searchprefix\";s:16:\"You searched for\";s:15:\"breadcrumbs-sep\";s:2:\"»\";s:12:\"website_name\";s:0:\"\";s:11:\"person_name\";s:0:\"\";s:11:\"person_logo\";s:0:\"\";s:22:\"alternate_website_name\";s:0:\"\";s:12:\"company_logo\";s:0:\"\";s:12:\"company_name\";s:0:\"\";s:22:\"company_alternate_name\";s:0:\"\";s:17:\"company_or_person\";s:7:\"company\";s:25:\"company_or_person_user_id\";b:0;s:17:\"stripcategorybase\";b:0;s:26:\"open_graph_frontpage_title\";s:12:\"%%sitename%%\";s:25:\"open_graph_frontpage_desc\";s:0:\"\";s:26:\"open_graph_frontpage_image\";s:0:\"\";s:24:\"publishing_principles_id\";i:0;s:25:\"ownership_funding_info_id\";i:0;s:29:\"actionable_feedback_policy_id\";i:0;s:21:\"corrections_policy_id\";i:0;s:16:\"ethics_policy_id\";i:0;s:19:\"diversity_policy_id\";i:0;s:28:\"diversity_staffing_report_id\";i:0;s:15:\"org-description\";s:0:\"\";s:9:\"org-email\";s:0:\"\";s:9:\"org-phone\";s:0:\"\";s:14:\"org-legal-name\";s:0:\"\";s:17:\"org-founding-date\";s:0:\"\";s:20:\"org-number-employees\";s:0:\"\";s:10:\"org-vat-id\";s:0:\"\";s:10:\"org-tax-id\";s:0:\"\";s:7:\"org-iso\";s:0:\"\";s:8:\"org-duns\";s:0:\"\";s:11:\"org-leicode\";s:0:\"\";s:9:\"org-naics\";s:0:\"\";s:10:\"title-post\";s:39:\"%%title%% %%page%% %%sep%% %%sitename%%\";s:13:\"metadesc-post\";s:0:\"\";s:12:\"noindex-post\";b:0;s:23:\"display-metabox-pt-post\";b:0;s:23:\"post_types-post-maintax\";i:0;s:21:\"schema-page-type-post\";s:7:\"WebPage\";s:24:\"schema-article-type-post\";s:7:\"Article\";s:17:\"social-title-post\";s:9:\"%%title%%\";s:23:\"social-description-post\";s:0:\"\";s:21:\"social-image-url-post\";s:0:\"\";s:20:\"social-image-id-post\";i:0;s:10:\"title-page\";s:39:\"%%title%% %%page%% %%sep%% %%sitename%%\";s:13:\"metadesc-page\";s:0:\"\";s:12:\"noindex-page\";b:0;s:23:\"display-metabox-pt-page\";b:0;s:23:\"post_types-page-maintax\";i:0;s:21:\"schema-page-type-page\";s:7:\"WebPage\";s:24:\"schema-article-type-page\";s:4:\"None\";s:17:\"social-title-page\";s:9:\"%%title%%\";s:23:\"social-description-page\";s:0:\"\";s:21:\"social-image-url-page\";s:0:\"\";s:20:\"social-image-id-page\";i:0;s:16:\"title-attachment\";s:39:\"%%title%% %%page%% %%sep%% %%sitename%%\";s:19:\"metadesc-attachment\";s:0:\"\";s:18:\"noindex-attachment\";b:0;s:29:\"display-metabox-pt-attachment\";b:0;s:29:\"post_types-attachment-maintax\";i:0;s:27:\"schema-page-type-attachment\";s:7:\"WebPage\";s:30:\"schema-article-type-attachment\";s:4:\"None\";s:18:\"title-tax-category\";s:53:\"%%term_title%% Archives %%page%% %%sep%% %%sitename%%\";s:21:\"metadesc-tax-category\";s:0:\"\";s:28:\"display-metabox-tax-category\";b:0;s:20:\"noindex-tax-category\";b:0;s:25:\"social-title-tax-category\";s:23:\"%%term_title%% Archives\";s:31:\"social-description-tax-category\";s:0:\"\";s:29:\"social-image-url-tax-category\";s:0:\"\";s:28:\"social-image-id-tax-category\";i:0;s:26:\"taxonomy-category-ptparent\";i:0;s:18:\"title-tax-post_tag\";s:53:\"%%term_title%% Archives %%page%% %%sep%% %%sitename%%\";s:21:\"metadesc-tax-post_tag\";s:0:\"\";s:28:\"display-metabox-tax-post_tag\";b:0;s:20:\"noindex-tax-post_tag\";b:0;s:25:\"social-title-tax-post_tag\";s:23:\"%%term_title%% Archives\";s:31:\"social-description-tax-post_tag\";s:0:\"\";s:29:\"social-image-url-tax-post_tag\";s:0:\"\";s:28:\"social-image-id-tax-post_tag\";i:0;s:26:\"taxonomy-post_tag-ptparent\";i:0;s:21:\"title-tax-post_format\";s:53:\"%%term_title%% Archives %%page%% %%sep%% %%sitename%%\";s:24:\"metadesc-tax-post_format\";s:0:\"\";s:31:\"display-metabox-tax-post_format\";b:0;s:23:\"noindex-tax-post_format\";b:0;s:28:\"social-title-tax-post_format\";s:23:\"%%term_title%% Archives\";s:34:\"social-description-tax-post_format\";s:0:\"\";s:32:\"social-image-url-tax-post_format\";s:0:\"\";s:31:\"social-image-id-tax-post_format\";i:0;s:29:\"taxonomy-post_format-ptparent\";i:0;s:14:\"title-property\";s:30:\"%%title%% %%sep%% %%sitename%%\";s:17:\"metadesc-property\";s:106:\"View property details, photos, and features for %%title%%. Contact HomeProz Real Estate in Albert Lea, MN.\";s:16:\"noindex-property\";b:0;s:27:\"display-metabox-pt-property\";b:0;s:27:\"post_types-property-maintax\";i:0;s:25:\"schema-page-type-property\";s:7:\"WebPage\";s:28:\"schema-article-type-property\";s:4:\"None\";s:21:\"social-title-property\";s:9:\"%%title%%\";s:27:\"social-description-property\";s:0:\"\";s:25:\"social-image-url-property\";s:0:\"\";s:24:\"social-image-id-property\";i:0;s:24:\"title-ptarchive-property\";s:49:\"Properties For Sale %%page%% %%sep%% %%sitename%%\";s:27:\"metadesc-ptarchive-property\";s:126:\"Browse all properties for sale in Albert Lea, Minnesota and surrounding areas. Find your dream home with HomeProz Real Estate.\";s:26:\"bctitle-ptarchive-property\";s:0:\"\";s:26:\"noindex-ptarchive-property\";b:0;s:31:\"social-title-ptarchive-property\";s:21:\"%%pt_plural%% Archive\";s:37:\"social-description-ptarchive-property\";s:0:\"\";s:35:\"social-image-url-ptarchive-property\";s:0:\"\";s:34:\"social-image-id-ptarchive-property\";i:0;s:23:\"title-tax-property_type\";s:53:\"%%term_title%% Archives %%page%% %%sep%% %%sitename%%\";s:26:\"metadesc-tax-property_type\";s:0:\"\";s:33:\"display-metabox-tax-property_type\";b:0;s:25:\"noindex-tax-property_type\";b:0;s:30:\"social-title-tax-property_type\";s:23:\"%%term_title%% Archives\";s:36:\"social-description-tax-property_type\";s:0:\"\";s:34:\"social-image-url-tax-property_type\";s:0:\"\";s:33:\"social-image-id-tax-property_type\";i:0;s:31:\"taxonomy-property_type-ptparent\";i:0;s:25:\"title-tax-property_status\";s:53:\"%%term_title%% Archives %%page%% %%sep%% %%sitename%%\";s:28:\"metadesc-tax-property_status\";s:0:\"\";s:35:\"display-metabox-tax-property_status\";b:0;s:27:\"noindex-tax-property_status\";b:0;s:32:\"social-title-tax-property_status\";s:23:\"%%term_title%% Archives\";s:38:\"social-description-tax-property_status\";s:0:\"\";s:36:\"social-image-url-tax-property_status\";s:0:\"\";s:35:\"social-image-id-tax-property_status\";i:0;s:33:\"taxonomy-property_status-ptparent\";i:0;s:27:\"title-tax-property_location\";s:53:\"%%term_title%% Archives %%page%% %%sep%% %%sitename%%\";s:30:\"metadesc-tax-property_location\";s:0:\"\";s:37:\"display-metabox-tax-property_location\";b:0;s:29:\"noindex-tax-property_location\";b:0;s:34:\"social-title-tax-property_location\";s:23:\"%%term_title%% Archives\";s:40:\"social-description-tax-property_location\";s:0:\"\";s:38:\"social-image-url-tax-property_location\";s:0:\"\";s:37:\"social-image-id-tax-property_location\";i:0;s:35:\"taxonomy-property_location-ptparent\";i:0;s:14:\"person_logo_id\";i:0;s:15:\"company_logo_id\";i:0;s:29:\"open_graph_frontpage_image_id\";i:0;}','auto'),(170,'wpseo_social','a:20:{s:13:\"facebook_site\";s:0:\"\";s:13:\"instagram_url\";s:0:\"\";s:12:\"linkedin_url\";s:0:\"\";s:11:\"myspace_url\";s:0:\"\";s:16:\"og_default_image\";s:0:\"\";s:19:\"og_default_image_id\";s:0:\"\";s:18:\"og_frontpage_title\";s:47:\"HomeProz Real Estate | Albert Lea MN Properties\";s:17:\"og_frontpage_desc\";s:97:\"Your trusted partner for buying and selling homes in Albert Lea, Minnesota and surrounding areas.\";s:18:\"og_frontpage_image\";s:0:\"\";s:21:\"og_frontpage_image_id\";s:0:\"\";s:9:\"opengraph\";b:1;s:13:\"pinterest_url\";s:0:\"\";s:15:\"pinterestverify\";s:0:\"\";s:7:\"twitter\";b:1;s:12:\"twitter_site\";s:0:\"\";s:17:\"twitter_card_type\";s:19:\"summary_large_image\";s:11:\"youtube_url\";s:0:\"\";s:13:\"wikipedia_url\";s:0:\"\";s:17:\"other_social_urls\";a:0:{}s:12:\"mastodon_url\";s:0:\"\";}','auto'),(171,'wpseo_llmstxt','a:7:{s:23:\"llms_txt_selection_mode\";s:4:\"auto\";s:13:\"about_us_page\";i:0;s:12:\"contact_page\";i:0;s:10:\"terms_page\";i:0;s:19:\"privacy_policy_page\";i:0;s:9:\"shop_page\";i:0;s:20:\"other_included_pages\";a:0:{}}','auto'),(174,'webpc_is_new_installation','1','auto'),(175,'webpc_notice_thanks','1765581302','auto'),(176,'webpc_notice_pro_version','1764976502','auto'),(177,'webpc_stats_installation_date','2025-11-28 23:15:02','auto'),(178,'webpc_stats_first_version','6.3.2','auto'),(181,'aio_wp_security_configs','a:47:{s:28:\"aiowps_enable_login_lockdown\";s:1:\"1\";s:28:\"aiowps_allow_unlock_requests\";s:1:\"1\";s:25:\"aiowps_max_login_attempts\";s:2:\"10\";s:24:\"aiowps_retry_time_period\";s:1:\"5\";s:26:\"aiowps_lockout_time_length\";s:2:\"30\";s:30:\"aiowps_max_lockout_time_length\";s:2:\"60\";s:28:\"aiowps_set_generic_login_msg\";s:1:\"1\";s:26:\"aiowps_enable_email_notify\";s:1:\"1\";s:20:\"aiowps_email_address\";s:16:\"brian@hanson.xyz\";s:39:\"aiowps_enable_invalid_username_lockdown\";s:0:\"\";s:43:\"aiowps_instantly_lockout_specific_usernames\";a:3:{i:0;s:5:\"admin\";i:1;s:13:\"administrator\";i:2;s:4:\"test\";}s:36:\"aiowps_remove_wp_generator_meta_info\";s:1:\"1\";s:27:\"aiowps_disable_file_editing\";s:1:\"1\";s:37:\"aiowps_prevent_default_wp_file_access\";s:1:\"1\";s:28:\"aiowps_enable_basic_firewall\";s:1:\"1\";s:27:\"aiowps_max_file_upload_size\";i:100;s:38:\"aiowps_disable_xmlrpc_pingback_methods\";s:1:\"1\";s:34:\"aiowps_block_debug_log_file_access\";s:1:\"1\";s:26:\"aiowps_disable_index_views\";s:1:\"1\";s:32:\"aiowps_prevent_users_enumeration\";s:1:\"1\";s:42:\"aiowps_disallow_unauthorized_rest_requests\";s:1:\"1\";s:40:\"aiowps_prevent_site_display_inside_frame\";s:1:\"1\";s:28:\"aiowps_enable_login_honeypot\";s:1:\"1\";s:35:\"aiowps_disable_application_password\";s:0:\"\";s:30:\"aiowps_enable_spambot_blocking\";s:1:\"1\";s:29:\"aiowps_enable_comment_captcha\";s:0:\"\";s:25:\"aiowps_enable_404_logging\";s:1:\"1\";s:28:\"aiowps_enable_404_IP_lockout\";s:0:\"\";s:36:\"aiowps_on_uninstall_delete_db_tables\";s:1:\"1\";s:34:\"aiowps_on_uninstall_delete_configs\";s:1:\"1\";s:31:\"aiowps_enable_rename_login_page\";s:0:\"\";s:43:\"aiowps_enable_brute_force_attack_prevention\";s:0:\"\";s:19:\"aiowps_site_lockout\";s:0:\"\";s:19:\"aiowps_enable_debug\";s:0:\"\";s:22:\"aiowps_default_captcha\";s:0:\"\";s:27:\"aiowps_enable_login_captcha\";s:0:\"\";s:35:\"aiowps_enable_registration_honeypot\";s:1:\"1\";s:26:\"aiowps_enable_blacklisting\";s:0:\"\";s:25:\"aiowps_enable_5g_firewall\";s:0:\"\";s:25:\"aiowps_enable_6g_firewall\";s:0:\"\";s:26:\"aiowps_enable_custom_rules\";s:0:\"\";s:25:\"aiowps_prevent_hotlinking\";s:0:\"\";s:22:\"aiowps_copy_protection\";s:0:\"\";s:33:\"aiowps_disable_rss_and_atom_feeds\";s:0:\"\";s:27:\"aiowps_enable_forced_logout\";s:0:\"\";s:32:\"aiowps_enable_automated_fcd_scan\";s:0:\"\";s:12:\"installed-at\";i:1764371970;}','auto'),(182,'aios_antibot_key_map_info','a:3:{i:0;a:2:{i:0;a:2:{i:0;s:8:\"dz7zzn8y\";i:1;s:12:\"ewbnnm47eqe7\";}i:1;a:2:{i:0;s:8:\"ovzo7jga\";i:1;s:12:\"zojsx526xhvu\";}}i:1;a:2:{i:0;a:2:{i:0;s:8:\"xdxz27wr\";i:1;s:12:\"xeft4p3ib2l1\";}i:1;a:2:{i:0;s:8:\"oth0fymk\";i:1;s:12:\"bjcyxlmg09pv\";}}i:2;i:1764720000;}','off'),(183,'aiowpsec_db_version','2.1.4','auto'),(184,'aiowpsec_firewall_version','1.0.8','auto'); /*!40000 ALTER TABLE `wp_options` ENABLE KEYS */; UNLOCK TABLES; @@ -466,7 +721,7 @@ CREATE TABLE `wp_yoast_indexable` ( KEY `subpages` (`post_parent`,`object_type`,`post_status`,`object_id`), KEY `prominent_words` (`prominent_words_version`,`object_type`,`object_sub_type`,`post_status`), KEY `published_sitemap_index` (`object_published_at`,`is_robots_noindex`,`object_type`,`object_sub_type`) -) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -475,7 +730,7 @@ CREATE TABLE `wp_yoast_indexable` ( LOCK TABLES `wp_yoast_indexable` WRITE; /*!40000 ALTER TABLE `wp_yoast_indexable` DISABLE KEYS */; -INSERT INTO `wp_yoast_indexable` VALUES (1,NULL,NULL,NULL,'date-archive',NULL,NULL,NULL,'%%date%% %%page%% %%sep%% %%sitename%%','',NULL,NULL,1,0,NULL,NULL,NULL,NULL,NULL,NULL,0,0,0,0,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'2025-11-28 23:08:35','2025-11-29 05:08:35',1,NULL,NULL,NULL,NULL,0,NULL,1,NULL,NULL,NULL),(2,'https://homeproz.dev.hanson.xyz/properties/','43:fe19fb00353a16a1e0f990a64c3584a1',NULL,'post-type-archive','property',NULL,NULL,'Properties For Sale %%page%% %%sep%% %%sitename%%','Browse all properties for sale in Albert Lea, Minnesota and surrounding areas. Find your dream home with HomeProz Real Estate.','Properties',NULL,1,0,NULL,NULL,NULL,NULL,NULL,NULL,0,0,0,0,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'2025-11-28 23:08:35','2025-11-29 05:08:35',1,NULL,NULL,NULL,NULL,0,NULL,2,'2025-11-28 23:08:35','2025-11-28 22:33:26',NULL),(3,'https://homeproz.dev.hanson.xyz/','32:69cc765724b94f94108e52a02a04fa6f',NULL,'home-page',NULL,NULL,NULL,'HomeProz Real Estate | Albert Lea MN Properties','HomeProz Real Estate - Your trusted partner for buying and selling homes in Albert Lea, Minnesota and surrounding areas.','Home',NULL,NULL,0,NULL,NULL,NULL,NULL,NULL,NULL,0,0,0,0,0,0,NULL,NULL,NULL,NULL,NULL,'%%sitename%%','','','0',NULL,NULL,NULL,NULL,NULL,'2025-11-28 23:08:35','2025-11-29 05:08:35',1,NULL,NULL,NULL,NULL,0,NULL,2,'2025-11-28 23:08:35','2025-11-28 21:02:25',NULL); +INSERT INTO `wp_yoast_indexable` VALUES (1,NULL,NULL,NULL,'date-archive',NULL,NULL,NULL,'%%date%% %%page%% %%sep%% %%sitename%%','',NULL,NULL,1,0,NULL,NULL,NULL,NULL,NULL,NULL,0,0,0,0,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'2025-11-28 23:08:35','2025-11-29 05:08:35',1,NULL,NULL,NULL,NULL,0,NULL,1,NULL,NULL,NULL),(2,'https://homeproz.dev.hanson.xyz/properties/','43:fe19fb00353a16a1e0f990a64c3584a1',NULL,'post-type-archive','property',NULL,NULL,'Properties For Sale %%page%% %%sep%% %%sitename%%','Browse all properties for sale in Albert Lea, Minnesota and surrounding areas. Find your dream home with HomeProz Real Estate.','Properties',NULL,1,0,NULL,NULL,NULL,NULL,NULL,NULL,0,0,0,0,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'2025-11-28 23:08:35','2025-11-29 05:08:35',1,NULL,NULL,NULL,NULL,0,NULL,2,'2025-11-28 23:08:35','2025-11-28 22:33:26',NULL),(3,'https://homeproz.dev.hanson.xyz/','32:69cc765724b94f94108e52a02a04fa6f',NULL,'home-page',NULL,NULL,NULL,'HomeProz Real Estate | Albert Lea MN Properties','HomeProz Real Estate - Your trusted partner for buying and selling homes in Albert Lea, Minnesota and surrounding areas.','Home',NULL,NULL,0,NULL,NULL,NULL,NULL,NULL,NULL,0,0,0,0,0,0,NULL,NULL,NULL,NULL,NULL,'%%sitename%%','','','0',NULL,NULL,NULL,NULL,NULL,'2025-11-28 23:08:35','2025-11-29 05:08:35',1,NULL,NULL,NULL,NULL,0,NULL,2,'2025-11-28 23:08:35','2025-11-28 21:02:25',NULL),(4,'https://homeproz.dev.hanson.xyz/','32:69cc765724b94f94108e52a02a04fa6f',10,'post','page',0,0,NULL,NULL,'Home','publish',NULL,0,NULL,NULL,NULL,NULL,NULL,0,0,NULL,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'2025-11-28 23:18:48','2025-11-29 05:18:48',1,NULL,NULL,NULL,NULL,0,NULL,2,'2025-11-28 22:57:59','2025-11-28 22:57:59',0); /*!40000 ALTER TABLE `wp_yoast_indexable` ENABLE KEYS */; UNLOCK TABLES; @@ -504,6 +759,7 @@ CREATE TABLE `wp_yoast_indexable_hierarchy` ( LOCK TABLES `wp_yoast_indexable_hierarchy` WRITE; /*!40000 ALTER TABLE `wp_yoast_indexable_hierarchy` DISABLE KEYS */; +INSERT INTO `wp_yoast_indexable_hierarchy` VALUES (4,0,0,1); /*!40000 ALTER TABLE `wp_yoast_indexable_hierarchy` ENABLE KEYS */; UNLOCK TABLES; @@ -606,4 +862,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2025-11-28 17:16:24 +-- Dump completed on 2025-11-28 17:19:54 diff --git a/wp-content/aiowps_backups/index.html b/wp-content/aiowps_backups/index.html new file mode 100644 index 00000000..e69de29b diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/SECURITY.md b/wp-content/plugins/all-in-one-wp-security-and-firewall/SECURITY.md new file mode 100755 index 00000000..1a912378 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/SECURITY.md @@ -0,0 +1,19 @@ +If you believe that you have found a security issue associated with the current release of this plugin, then please report it to the email address with local part security-reports-only and the domain updraftplus.com. If receipt of the email is not acknowledged within 3 working days, then you can try again and also use the inquiry form on the plugin's website. + +Do not send emails on any other subject to this address. They will not be acknowledged, regardless of whether they contain pleas to do otherwise; there are inquiry forms and support forums available which are linked within the plugin and easy to find on the plugin website. + +Please include as much of the information listed below as you can to help us better understand and resolve the issue: + +* The type of issue (e.g., buffer overflow, SQL injection, or cross-site scripting) +* Affected version(s) +* Impact of the issue, including how an attacker might exploit the issue +* Step-by-step instructions to reproduce the issue +* The location of the affected code +* Full paths of source file(s) related to the manifestation of the issue +* Any special configuration required to reproduce the issue +* Any log files that are related to this issue (if possible) +* Proof-of-concept or exploit code (if possible) + +This information will help us triage your report more quickly. + +Thank you! \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/general/wp-security-ajax-data-table.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/general/wp-security-ajax-data-table.php new file mode 100755 index 00000000..efd8d1f4 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/general/wp-security-ajax-data-table.php @@ -0,0 +1,1486 @@ +get_column_info(). + * + * @since 4.1.0 + * @var array + */ + protected $_column_headers; + + /** + * {@internal Missing Summary} + * + * @var array + */ + protected $compat_fields = array('_args', '_pagination_args', 'screen', '_actions', '_pagination'); + + /** + * {@internal Missing Summary} + * + * @var array + */ + protected $compat_methods = array( + 'set_pagination_args', + 'get_views', + 'get_bulk_actions', + 'bulk_actions', + 'row_actions', + 'months_dropdown', + 'view_switcher', + 'comments_bubble', + 'get_items_per_page', + 'pagination', + 'get_sortable_columns', + 'get_column_info', + 'get_table_classes', + 'display_tablenav', + 'extra_tablenav', + 'single_row_columns', + ); + + /** + * Constructor. + * + * The child class should call this constructor from its own constructor to override + * the default $args. + * + * @since 3.1.0 + * + * @param array|string $args { + * Array or string of arguments. + * + * @type string $plural Plural value used for labels and the objects being listed. + * This affects things such as CSS class-names and nonces used + * in the list table, e.g. 'posts'. Default empty. + * @type string $singular Singular label for an object being listed, e.g. 'post'. + * Default empty + * @type bool $ajax Whether the list table supports Ajax. This includes loading + * and sorting data, for example. If true, the class will call + * the js_vars() method in the footer to provide variables + * to any scripts handling Ajax events. Default false. + * @type string $screen String containing the hook name used to determine the current + * screen. If left null, the current screen will be automatically set. + * Default null. + * } + */ + public function __construct($args = array()) { + $args = wp_parse_args( + $args, + array( + 'plural' => '', + 'singular' => '', + 'ajax' => false, + 'screen' => null, + ) + ); + + $this->screen = convert_to_screen($args['screen']); + + add_filter("manage_{$this->screen->id}_columns", array($this, 'get_columns'), 0); + + if (!$args['plural']) { + $args['plural'] = $this->screen->base; + } + + $args['plural'] = sanitize_key($args['plural']); + $args['singular'] = sanitize_key($args['singular']); + + $this->_args = $args; + + if ($args['ajax']) { + // wp_enqueue_script('list-table'); + add_action('admin_footer', array($this, 'js_vars')); + } + + if (empty($this->modes)) { + $this->modes = array( + 'list' => __('List view', 'all-in-one-wp-security-and-firewall'), + 'excerpt' => __('Excerpt view', 'all-in-one-wp-security-and-firewall'), + ); + } + } + + /** + * Make private properties readable for backward compatibility. + * + * @since 4.0.0 + * + * @param string $name - Property to get. + * @return mixed Property. + */ + public function __get($name) { + if (in_array($name, $this->compat_fields)) { + return $this->$name; + } + } + + /** + * Make private properties settable for backward compatibility. + * + * @since 4.0.0 + * + * @param string $name - Property to check if set. + * @param mixed $value - Property value. + * @return mixed Newly-set property. + */ + public function __set($name, $value) { + if (in_array($name, $this->compat_fields)) { + return $this->$name = $value; + } + } + + /** + * Make private properties checkable for backward compatibility. + * + * @since 4.0.0 + * + * @param string $name - Property to check if set. + * @return bool Whether the property is set. + */ + public function __isset($name) { + if (in_array($name, $this->compat_fields)) { + return isset($this->$name); + } + } + + /** + * Make private properties un-settable for backward compatibility. + * + * @since 4.0.0 + * + * @param string $name - Property to unset. + */ + public function __unset($name) { + if (in_array($name, $this->compat_fields)) { + unset($this->$name); + } + } + + /** + * Make private/protected methods readable for backward compatibility. + * + * @since 4.0.0 + * + * @param string $name - Method to call. + * @param array $arguments - Arguments to pass when calling. + * @return mixed|bool Return value of the callback, false otherwise. + */ + public function __call($name, $arguments) { + if (in_array($name, $this->compat_methods)) { + return call_user_func_array(array($this, $name), $arguments); + } + return false; + } + + /** + * Checks the current user's permissions + * + * @since 3.1.0 + * @abstract + */ + public function ajax_user_can() { + die('function AIOWPSecurity_List_Table::ajax_user_can() must be over-ridden in a sub-class.'); + } + + /** + * Prepares the list of items for displaying. + * + * @uses AIOWPSecurity_List_Table::set_pagination_args() + * + * @since 3.1.0 + * @abstract + */ + public function prepare_items() { + die('function AIOWPSecurity_List_Table::prepare_items() must be over-ridden in a sub-class.'); + } + + /** + * An internal method that sets all the necessary pagination arguments + * + * @since 3.1.0 + * + * @param array|string $args - Array or string of arguments with information about the pagination. + */ + protected function set_pagination_args($args) { + $args = wp_parse_args( + $args, + array( + 'total_items' => 0, + 'total_pages' => 0, + 'per_page' => 0, + ) + ); + + if (!$args['total_pages'] && $args['per_page'] > 0) { + $args['total_pages'] = ceil($args['total_items'] / $args['per_page']); + } + + // Redirect if page number is invalid and headers are not already sent. + if (!headers_sent() && !wp_doing_ajax() && $args['total_pages'] > 0 && $this->get_pagenum() > $args['total_pages']) { + wp_redirect(add_query_arg('paged', $args['total_pages'])); + exit; + } + + $this->_pagination_args = $args; + } + + /** + * Access the pagination args. + * + * @since 3.1.0 + * + * @param string $key - Pagination argument to retrieve. Common values include 'total_items', + * 'total_pages', 'per_page', or 'infinite_scroll'. + * @return int Number of items that correspond to the given pagination argument. + */ + public function get_pagination_arg($key) { + if ('page' === $key) { + return $this->get_pagenum(); + } + + if (isset($this->_pagination_args[$key])) { + return $this->_pagination_args[$key]; + } + } + + /** + * Whether the table has items to display or not + * + * @since 3.1.0 + * + * @return bool + */ + public function has_items() { + return !empty($this->items); + } + + /** + * Message to be displayed when there are no items + * + * @since 3.1.0 + */ + public function no_items() { + esc_html_e('No items found.', 'all-in-one-wp-security-and-firewall'); + } + + /** + * Displays the search box. + * + * @since 3.1.0 + * + * @param string $text - The 'submit' button label. + * @param string $input_id - ID attribute value for the search input field. + */ + public function search_box($text, $input_id) { + if (empty($this->_args['data']['s']) && !$this->has_items()) { + return; + } + + $input_id = $input_id . '-search-input'; + + if (!empty($this->_args['data']['orderby'])) { + echo ''; + } + if (!empty($this->_args['data']['order'])) { + echo ''; + } + if (!empty($this->_args['data']['post_mime_type'])) { + echo ''; + } + if (!empty($this->_args['data']['detached'])) { + echo ''; + } + ?> + + link) with the list + * of views available on this table. + * + * @since 3.1.0 + * + * @return array + */ + protected function get_views() { + return array(); + } + + /** + * Display the list of views available on this table. + * + * @since 3.1.0 + */ + public function views() { + $views = $this->get_views(); + /** + * Filters the list of available list table views. + * + * The dynamic portion of the hook name, `$this->screen->id`, refers + * to the ID of the current screen, usually a string. + * + * @since 3.5.0 + * + * @param string[] - $views An array of available list table views. + */ + $views = apply_filters("views_{$this->screen->id}", $views); + + if (empty($views)) { + return; + } + + $this->screen->render_screen_reader_content('heading_views'); + + echo "'; + } + + /** + * Get an associative array (option_name => option_title) with the list + * of bulk actions available on this table. + * + * @since 3.1.0 + * + * @return array + */ + protected function get_bulk_actions() { + return array(); + } + + /** + * Display the bulk actions dropdown. + * + * @since 3.1.0 + * + * @param string $which - The location of the bulk actions: 'top' or 'bottom'. + * This is designated as optional for backward compatibility. + */ + protected function bulk_actions($which = '') { + if (is_null($this->_actions)) { + $this->_actions = $this->get_bulk_actions(); + /** + * Filters the list table Bulk Actions drop-down. + * + * The dynamic portion of the hook name, `$this->screen->id`, refers + * to the ID of the current screen, usually a string. + * + * This filter can currently only be used to remove bulk actions. + * + * @since 3.5.0 + * + * @param string[] $actions - An array of the available bulk actions. + */ + $this->_actions = apply_filters("bulk_actions-{$this->screen->id}", $this->_actions); + $two = ''; + } else { + $two = '2'; + } + + if (empty($this->_actions)) { + return; + } + + echo ''; + echo '\n"; + + $submit_attributes = array('id' => "doaction$two"); + + if ('top' == $which) { + $submit_attributes['onclick'] = "return confirm('".esc_js(__('Are you sure you want to perform this bulk action?', 'all-in-one-wp-security-and-firewall'))."')"; + } + + submit_button(__('Apply', 'all-in-one-wp-security-and-firewall'), 'action', '', false, $submit_attributes); + echo "\n"; + } + + /** + * Get the current action selected from the bulk actions dropdown. + * + * @since 3.1.0 + * + * @return string|false The action name or False if no action was selected + */ + public function current_action() { + if (isset($this->_args['data']['filter_action']) && !empty($this->_args['data']['filter_action'])) { + return false; + } + + if (isset($this->_args['data']['action']) && -1 != $this->_args['data']['action']) { + return $this->_args['data']['action']; + } + + if (isset($this->_args['data']['action2']) && -1 != $this->_args['data']['action2']) { + return $this->_args['data']['action2']; + } + + return false; + } + + /** + * Generate row actions div + * + * @since 3.1.0 + * + * @param string[] $actions - An array of action links. + * @param bool $always_visible - Whether the actions should be always visible. + * @return string + */ + protected function row_actions($actions, $always_visible = false) { + $action_count = count($actions); + $i = 0; + + if (!$action_count) { + return ''; + } + + $out = '
'; + foreach ($actions as $action => $link) { + ++$i; + ($i == $action_count) ? $sep = '' : $sep = ' | '; + $out .= "$link$sep"; + } + $out .= '
'; + + $out .= ''; + + return $out; + } + + /** + * Display a monthly dropdown for filtering items + * + * @since 3.1.0 + * + * @global wpdb $wpdb + * @global WP_Locale $wp_locale + * + * @param string $post_type + */ + protected function months_dropdown($post_type) { + global $wpdb, $wp_locale; + + /** + * Filters whether to remove the 'Months' drop-down from the post list table. + * + * @since 4.2.0 + * + * @param bool $disable - Whether to disable the drop-down. Default false. + * @param string $post_type - The post type. + */ + if (apply_filters('disable_months_dropdown', false, $post_type)) { + return; + } + + $extra_checks = "AND post_status != 'auto-draft'"; + if (!isset($this->_args['data']['post_status']) || 'trash' !== $this->_args['data']['post_status']) { + $extra_checks .= " AND post_status != 'trash'"; + } elseif (isset($this->_args['data']['post_status'])) { + $extra_checks = $wpdb->prepare(' AND post_status = %s', $this->_args['data']['post_status']); + } + + // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- The $extra_checks variable, although prepared above, cannot be added to the prepare args in this statement. + $months = $wpdb->get_results($wpdb->prepare("SELECT DISTINCT YEAR(post_date) AS year, MONTH(post_date) AS month FROM $wpdb->posts WHERE post_type = %s $extra_checks ORDER BY post_date DESC", $post_type)); + + /** + * Filters the 'Months' drop-down results. + * + * @since 3.7.0 + * + * @param object $months The months drop-down query results. + * @param string $post_type The post type. + */ + $months = apply_filters('months_dropdown_results', $months, $post_type); + + $month_count = count($months); + + if (!$month_count || (1 == $month_count && 0 == $months[0]->month)) { + return; + } + + $m = isset($this->_args['data']['m']) ? (int) $this->_args['data']['m'] : 0; + ?> + + + + +
+ modes as $mode => $title) { + $classes = array('view-' . $mode); + if ($current_mode === $mode) { + $classes[] = 'current'; + } + printf("%s\n", + esc_url(add_query_arg('mode', $mode)), + implode(' ', array_map('esc_attr', $classes)), + esc_html($title) + ); + } + ?> +
+ %s', esc_html__('No comments', 'all-in-one-wp-security-and-firewall')); + // Approved comments have different display depending on some conditions. + } elseif ($approved_comments) { + printf('%s', + esc_url( + add_query_arg( + array( + 'p' => $post_id, + 'comment_status' => 'approved', + ), + admin_url('edit-comments.php') + ) + ), + esc_html($approved_comments_number), + $pending_comments ? esc_html($approved_phrase) : esc_html($approved_only_phrase) + ); + } else { + printf( + '%s', + esc_html($approved_comments_number), + $pending_comments ? esc_html__('No approved comments', 'all-in-one-wp-security-and-firewall') : esc_html__('No comments', 'all-in-one-wp-security-and-firewall') + ); + } + + if ($pending_comments) { + printf( + '%s', + esc_url( + add_query_arg( + array( + 'p' => $post_id, + 'comment_status' => 'moderated', + ), + admin_url('edit-comments.php') + ) + ), + esc_html($pending_comments_number), + esc_html($pending_phrase) + ); + } else { + printf( + '%s', + esc_html($pending_comments_number), + $approved_comments ? esc_html__('No pending comments', 'all-in-one-wp-security-and-firewall') : esc_html__('No comments', 'all-in-one-wp-security-and-firewall') + ); + } + } + + /** + * Get the current page number + * + * @since 3.1.0 + * + * @return int + */ + public function get_pagenum() { + $pagenum = isset($this->_args['data']['paged']) ? absint($this->_args['data']['paged']) : 0; + + if (isset($this->_pagination_args['total_pages']) && $pagenum > $this->_pagination_args['total_pages']) { + $pagenum = $this->_pagination_args['total_pages']; + } + + return max(1, $pagenum); + } + + /** + * Get number of items to display on a single page + * + * @since 3.1.0 + * + * @param string $option + * @param int $default + * @return int + */ + protected function get_items_per_page($option, $default = 20) { + $per_page = (int) get_user_option($option); + if (empty($per_page) || $per_page < 1) { + $per_page = $default; + } + + /** + * Filters the number of items to be displayed on each page of the list table. + * + * The dynamic hook name, $option, refers to the `per_page` option depending + * on the type of list table in use. Possible values include: 'edit_comments_per_page', + * 'sites_network_per_page', 'site_themes_network_per_page', 'themes_network_per_page', + * 'users_network_per_page', 'edit_post_per_page', 'edit_page_per_page', + * 'edit_{$post_type}_per_page', etc. + * + * @since 2.9.0 + * + * @param int $per_page - Number of items to be displayed. Default 20. + */ + return (int) apply_filters("{$option}", $per_page); + } + + + + /** + * Display the pagination. + * + * @since 3.1.0 + * + * @param string $which + */ + protected function pagination($which) { + if (empty($this->_pagination_args)) { + return; + } + + $total_items = $this->_pagination_args['total_items']; + $total_pages = $this->_pagination_args['total_pages']; + $infinite_scroll = false; + if (isset($this->_pagination_args['infinite_scroll'])) { + $infinite_scroll = $this->_pagination_args['infinite_scroll']; + } + + if ('top' === $which && $total_pages > 1) { + $this->screen->render_screen_reader_content('heading_pagination'); + } + + /* translators: %s: Total items */ + $output = '' . sprintf(_n('%s item', '%s items', esc_html($total_items), 'all-in-one-wp-security-and-firewall'), number_format_i18n($total_items)) . ''; + + $current = $this->get_pagenum(); + + $removable_query_args = wp_removable_query_args(); + + $host = isset($_SERVER['HTTP_HOST']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'])) : ''; + $request = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : ''; + $current_url = set_url_scheme('http://' . $host . $request); + + $current_url = remove_query_arg($removable_query_args, $current_url); + + $page_links = array(); + + $total_pages_before = ''; + $total_pages_after = ''; + + $disable_first = $disable_last = $disable_prev = $disable_next = false; + + if (1 == $current) { + $disable_first = true; + $disable_prev = true; + } + if (2 == $current) { + $disable_first = true; + } + if ($current == $total_pages) { + $disable_last = true; + $disable_next = true; + } + if ($current == $total_pages - 1) { + $disable_last = true; + } + + if ($disable_first) { + $page_links[] = ''; + } else { + $page_links[] = sprintf( + "%s", + esc_url(remove_query_arg('paged', $current_url)), + esc_html__('First page', 'all-in-one-wp-security-and-firewall'), + '«' + ); + } + + if ($disable_prev) { + $page_links[] = ''; + } else { + $page_links[] = sprintf( + "%s", + esc_url(add_query_arg('paged', max(1, $current - 1), $current_url)), + esc_html__('Previous page', 'all-in-one-wp-security-and-firewall'), + '‹' + ); + } + + if ('bottom' === $which) { + $html_current_page = $current; + $total_pages_before = '' . __('Current page', 'all-in-one-wp-security-and-firewall') . ''; + } else { + $html_current_page = sprintf( + "%s", + '', + $current, + strlen($total_pages) + ); + } + $html_total_pages = sprintf("%s", number_format_i18n($total_pages)); + /* translators: 1: Current page, 2: Total pages */ + $page_links[] = $total_pages_before . sprintf(esc_html_x('%1$s of %2$s', 'paging', 'all-in-one-wp-security-and-firewall'), $html_current_page, $html_total_pages) . $total_pages_after; + + if ($disable_next) { + $page_links[] = ''; + } else { + $page_links[] = sprintf( + "%s", + esc_url(add_query_arg('paged', min($total_pages, $current + 1), $current_url)), + esc_html__('Next page', 'all-in-one-wp-security-and-firewall'), + '›' + ); + } + + if ($disable_last) { + $page_links[] = ''; + } else { + $page_links[] = sprintf( + "%s", + esc_url(add_query_arg('paged', $total_pages, $current_url)), + esc_html__('Last page', 'all-in-one-wp-security-and-firewall'), + '»' + ); + } + + $pagination_links_class = 'pagination-links'; + if (!empty($infinite_scroll)) { + $pagination_links_class .= ' hide-if-js'; + } + $output .= "\n" . join("\n", $page_links) . ''; + + if ($total_pages) { + $page_class = $total_pages < 2 ? ' one-page' : ''; + } else { + $page_class = ' no-pages'; + } + $this->_pagination = "
" . $output . "
"; + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Necessary escaping done above. + echo $this->_pagination; + } + + /** + * Get a list of columns. The format is: + * 'internal-name' => 'Title' + * + * @since 3.1.0 + * @abstract + * + * @return array + */ + public function get_columns() { + die('function AIOWPSecurity_List_Table::get_columns() must be over-ridden in a sub-class.'); + } + + /** + * Get a list of sortable columns. The format is: + * 'internal-name' => 'orderby' + * or + * 'internal-name' => array('orderby', true) + * + * The second format will make the initial sorting order be descending + * + * @since 3.1.0 + * + * @return array + */ + protected function get_sortable_columns() { + return array(); + } + + /** + * Gets the name of the default primary column. + * + * @since 4.3.0 + * + * @return string Name of the default primary column, in this case, an empty string. + */ + protected function get_default_primary_column_name() { + $columns = $this->get_columns(); + $column = ''; + + if (empty($columns)) { + return $column; + } + + // We need a primary defined so responsive views show something, + // so let's fall back to the first non-checkbox column. + foreach ($columns as $col => $column_name) { + if ('cb' === $col) { + continue; + } + + $column = $col; + break; + } + + return $column; + } + + /** + * Public wrapper for AIOWPSecurity_List_Table::get_default_primary_column_name(). + * + * @since 4.4.0 + * + * @return string Name of the default primary column. + */ + public function get_primary_column() { + return $this->get_primary_column_name(); + } + + /** + * Gets the name of the primary column. + * + * @since 4.3.0 + * + * @return string The name of the primary column. + */ + protected function get_primary_column_name() { + $columns = get_column_headers($this->screen); + $default = $this->get_default_primary_column_name(); + + // If the primary column doesn't exist fall back to the + // first non-checkbox column. + if (!isset($columns[$default])) { + $default = AIOWPSecurity_Ajax_Data_Table::get_default_primary_column_name(); + } + + /** + * Filters the name of the primary column for the current list table. + * + * @since 4.3.0 + * + * @param string $default Column name default for the specific list table, e.g. 'name'. + * @param string $context Screen ID for specific list table, e.g. 'plugins'. + */ + $column = apply_filters('list_table_primary_column', $default, $this->screen->id); + + if (empty($column) || !isset($columns[$column])) { + $column = $default; + } + + return $column; + } + + /** + * Get a list of all, hidden and sortable columns, with filter applied + * + * @since 3.1.0 + * + * @return array + */ + protected function get_column_info() { + // $_column_headers is already set / cached + if (isset($this->_column_headers) && is_array($this->_column_headers)) { + // Back-compat for list tables that have been manually setting $_column_headers for horse reasons. + // In 4.3, we added a fourth argument for primary column. + $column_headers = array(array(), array(), array(), $this->get_primary_column_name()); + foreach ($this->_column_headers as $key => $value) { + $column_headers[$key] = $value; + } + + return $column_headers; + } + + $columns = get_column_headers($this->screen); + $hidden = get_hidden_columns($this->screen); + + $sortable_columns = $this->get_sortable_columns(); + /** + * Filters the list table sortable columns for a specific screen. + * + * The dynamic portion of the hook name, `$this->screen->id`, refers + * to the ID of the current screen, usually a string. + * + * @since 3.5.0 + * + * @param array $sortable_columns - An array of sortable columns. + */ + $_sortable = apply_filters("manage_{$this->screen->id}_sortable_columns", $sortable_columns); + + $sortable = array(); + foreach ($_sortable as $id => $data) { + if (empty($data)) { + continue; + } + + $data = (array) $data; + if (!isset($data[1])) { + $data[1] = false; + } + + $sortable[$id] = $data; + } + + $primary = $this->get_primary_column_name(); + $this->_column_headers = array($columns, $hidden, $sortable, $primary); + + return $this->_column_headers; + } + + /** + * Return number of visible columns + * + * @since 3.1.0 + * + * @return int + */ + public function get_column_count() { + list ($columns, $hidden) = $this->get_column_info(); + $hidden = array_intersect(array_keys($columns), array_filter($hidden)); + return count($columns) - count($hidden); + } + + /** + * Print column headers, accounting for hidden and sortable columns. + * + * @since 3.1.0 + * + * @staticvar int $cb_counter + * + * @param bool $with_id - Whether to set the id attribute or not + */ + public function print_column_headers($with_id = true) { + list($columns, $hidden, $sortable, $primary) = $this->get_column_info(); + + $host = isset($_SERVER['HTTP_HOST']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'])) : ''; + $request = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : ''; + $current_url = set_url_scheme('http://' . $host . $request); + $current_url = remove_query_arg('paged', $current_url); + + if (isset($this->_args['data']['orderby'])) { + $current_orderby = $this->_args['data']['orderby']; + } else { + $current_orderby = ''; + } + + if (isset($this->_args['data']['order']) && 'desc' === $this->_args['data']['order']) { + $current_order = 'desc'; + } else { + $current_order = 'asc'; + } + + if (!empty($columns['cb'])) { + static $cb_counter = 1; + $columns['cb'] = '' + . ''; + $cb_counter++; + } + + foreach ($columns as $column_key => $column_display_name) { + $class = array('manage-column', "column-$column_key"); + + if (in_array($column_key, $hidden)) { + $class[] = 'hidden'; + } + + if ('cb' === $column_key) { + $class[] = 'check-column'; + } elseif (in_array($column_key, array('posts', 'comments', 'links'))) { + $class[] = 'num'; + } + + if ($column_key === $primary) { + $class[] = 'column-primary'; + } + + if (isset($sortable[$column_key])) { + list($orderby, $desc_first) = $sortable[$column_key]; + + if ($current_orderby === $orderby) { + $order = 'asc' === $current_order ? 'desc' : 'asc'; + $class[] = 'sorted'; + $class[] = $current_order; + } else { + $order = $desc_first ? 'desc' : 'asc'; + $class[] = 'sortable'; + $class[] = $desc_first ? 'asc' : 'desc'; + } + + $column_display_name = '' . $column_display_name . ''; + } + + $tag = ('cb' === $column_key) ? 'td' : 'th'; + $scope = ('th' === $tag) ? 'scope="col"' : ''; + $id = $with_id ? "id='$column_key'" : ''; + + if (!empty($class)) { + $class = "class='" . join(' ', $class) . "'"; + } + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped earlier in other functions. + echo "<$tag $scope $id $class>$column_display_name"; + } + } + + /** + * Display the table + * + * @since 3.1.0 + */ + public function display() { + $singular = $this->_args['singular']; + + $this->display_tablenav('top'); + + $this->screen->render_screen_reader_content('heading_list'); + ?> + + + + print_column_headers(); ?> + + + + + > + display_rows_or_placeholder(); ?> + + + + + print_column_headers(false); ?> + + + +
+ display_tablenav('bottom'); + } + + /** + * Get a list of CSS classes for the AIOWPSecurity_List_Table table tag. + * + * @since 3.1.0 + * + * @return array List of CSS classes for the table tag. + */ + protected function get_table_classes() { + return array('widefat', 'fixed', 'striped', $this->_args['plural']); + } + + /** + * Generate the table navigation above or below the table + * + * @since 3.1.0 + * @param string $which + */ + protected function display_tablenav($which) { + if ('top' === $which) { + wp_nonce_field('bulk-' . $this->_args['plural']); + } + ?> +
+ + has_items()) : ?> +
+ bulk_actions($which); ?> +
+ extra_tablenav($which); + $this->pagination($which); + ?> + +
+
+ has_items()) { + $this->display_rows(); + } else { + echo ''; + $this->no_items(); + echo ''; + } + } + + /** + * Generate the table rows + * + * @since 3.1.0 + */ + public function display_rows() { + foreach ($this->items as $item) { + $this->single_row($item); + } + } + + /** + * Generates content for a single row of the table + * + * @since 3.1.0 + * + * @param object $item The current item + */ + public function single_row($item) { + echo ''; + $this->single_row_columns($item); + echo ''; + } + + /** + * This function renders a default column item + * + * @param array $item - Item object + * @param string $column_name - Column name to be rendered from item object + */ + protected function column_default($item, $column_name) {} // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable, Squiz.WhiteSpace.ScopeClosingBrace.ContentBefore, PEAR.WhiteSpace.ScopeClosingBrace.Line -- this is a protected function + + /** + * This function renders the checkbox column + * + * @param array $item - item object + */ + protected function column_cb($item) {} // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable, Squiz.WhiteSpace.ScopeClosingBrace.ContentBefore, PEAR.WhiteSpace.ScopeClosingBrace.Line -- this is a protected function + + + /** + * Generates the columns for a single row of the table + * + * @since 3.1.0 + * + * @param object $item - The current item + * + * removed $sortable as it was unused from list() call + */ + protected function single_row_columns($item) { + list($columns, $hidden, $sortable, $primary) = $this->get_column_info(); // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Unused parameters are for future use. + + foreach ($columns as $column_name => $column_display_name) { + $classes = "$column_name column-$column_name"; + if ($primary === $column_name) { + $classes .= ' has-row-actions column-primary'; + } + + if (in_array($column_name, $hidden)) { + $classes .= ' hidden'; + } + + // Comments column uses HTML in the display name with screen reader text. + // Instead of using esc_attr(), we strip tags to get closer to a user-friendly string. + $data = 'data-colname="' . wp_strip_all_tags($column_display_name) . '"'; + + $attributes = "class='$classes' $data"; + if ('cb' === $column_name) { + echo ''; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP Error. Escaped earlier in other functions. + echo $this->column_cb($item); + echo ''; + } elseif (method_exists($this, '_column_' . $column_name)) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP Error. Escaped earlier in other functions. + echo call_user_func( + array($this, '_column_' . $column_name), + $item, + $classes, + $data, + $primary + ); + } elseif (method_exists($this, 'column_' . $column_name)) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP Error. Escaped earlier in other functions. + echo ""; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP Error. Escaped earlier in other functions. + echo call_user_func(array($this, 'column_' . $column_name), $item); + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP Error. Escaped earlier in other functions. + echo $this->handle_row_actions($item, $column_name, $primary); + echo ''; + } else { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP Error. Escaped earlier in other functions. + echo ""; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP Error. Escaped earlier in other functions. + echo $this->column_default($item, $column_name); + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP Error. Escaped earlier in other functions. + echo $this->handle_row_actions($item, $column_name, $primary); + echo ''; + } + } + } + + /** + * Generates and display row actions links for the list table. + * + * @since 4.3.0 + * + * @param object $item - The item being acted upon. + * @param string $column_name - Current column name. + * @param string $primary - Primary column name. + * @return string The row actions HTML, or an empty string if the current column is the primary column. + */ + protected function handle_row_actions($item, $column_name, $primary) { + return $column_name === $primary ? '' : ''; + } + + + /** + * Handle an incoming ajax request (called from admin-ajax.php) + * + * @param bool $return_instead_of_echo - Whether to return data or die() with data. + * + * @since 3.1.0 + */ + public function ajax_response($return_instead_of_echo = false) { + $this->prepare_items(false); + + ob_start(); + if (!empty($this->_args['data']['no_placeholder'])) { + $this->display_rows(); + } else { + $this->display_rows_or_placeholder(); + } + + $rows = ob_get_clean(); + + ob_start(); + $this->print_column_headers(true); + $headers = ob_get_clean(); + + ob_start(); + $this->pagination('top'); + $pagination_top = ob_get_clean(); + + ob_start(); + $this->pagination('bottom'); + $pagination_bottom = ob_get_clean(); + + $response = array( + 'rows' => $rows, + 'pagination' => array( + 'top' => $pagination_top, + 'bottom' => $pagination_bottom, + ), + 'column_headers' => $headers, + ); + + if (isset($this->_pagination_args['total_items'])) { + $response['total_items_i18n'] = sprintf( + /* translators: %s: Total items */ + _n('%s item', '%s items', $this->_pagination_args['total_items'], 'all-in-one-wp-security-and-firewall'), + number_format_i18n($this->_pagination_args['total_items']) + ); + } + if (isset($this->_pagination_args['total_pages'])) { + $response['total_pages'] = $this->_pagination_args['total_pages']; + $response['total_pages_i18n'] = number_format_i18n($this->_pagination_args['total_pages']); + } + + // Get the message from the helper + $list_message = AIOS_Helper::get_message('aios_list_message'); + if ($list_message) { + $response['message'] = $list_message['message']; + $response['status'] = $list_message['type']; + } + + if ($return_instead_of_echo) { + return $response; + } + + die(wp_json_encode($response)); + } + + /** + * Send required variables to JavaScript land + */ + public function js_vars() { + $args = array( + 'class' => get_class($this), + 'screen' => array( + 'id' => $this->screen->id, + 'base' => $this->screen->base, + ), + ); + + printf("\n", wp_json_encode($args)); + } + + /** + * Retrieves and returns current WP general settings date time format. + * + * @return String + */ + protected function get_wp_date_time_format() { + static $wp_date_time_format; + + if (!isset($wp_date_time_format)) { + $wp_date_time_format = get_option('date_format').' '.get_option('time_format'); + } + + return $wp_date_time_format; + } +} \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/general/wp-security-list-table.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/general/wp-security-list-table.php new file mode 100755 index 00000000..c3e5013c --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/general/wp-security-list-table.php @@ -0,0 +1,1451 @@ +get_column_info(). + * + * @since 4.1.0 + * @var array + */ + protected $_column_headers; + + /** + * {@internal Missing Summary} + * + * @var array + */ + protected $compat_fields = array('_args', '_pagination_args', 'screen', '_actions', '_pagination'); + + /** + * {@internal Missing Summary} + * + * @var array + */ + protected $compat_methods = array( + 'set_pagination_args', + 'get_views', + 'get_bulk_actions', + 'bulk_actions', + 'row_actions', + 'months_dropdown', + 'view_switcher', + 'comments_bubble', + 'get_items_per_page', + 'pagination', + 'get_sortable_columns', + 'get_column_info', + 'get_table_classes', + 'display_tablenav', + 'extra_tablenav', + 'single_row_columns', + ); + + /** + * Constructor. + * + * The child class should call this constructor from its own constructor to override + * the default $args. + * + * @since 3.1.0 + * + * @param array|string $args { + * + * @type string $plural Plural value used for labels and the objects being listed. + * This affects things such as CSS class-names and nonces used + * in the list table, e.g. 'posts'. Default empty. + * @type string $singular Singular label for an object being listed, e.g. 'post'. + * Default empty + * @type bool $ajax Whether the list table supports Ajax. This includes loading + * and sorting data, for example. If true, the class will call + * the js_vars() method in the footer to provide variables + * to any scripts handling Ajax events. Default false. + * @type string $screen String containing the hook name used to determine the current + * screen. If left null, the current screen will be automatically set. + * Default null. + * } + */ + public function __construct($args = array()) { + $args = wp_parse_args( + $args, + array( + 'plural' => '', + 'singular' => '', + 'ajax' => false, + 'screen' => null, + ) + ); + + $this->screen = convert_to_screen($args['screen']); + + add_filter("manage_{$this->screen->id}_columns", array($this, 'get_columns'), 0); + + if (!$args['plural']) { + $args['plural'] = $this->screen->base; + } + + $args['plural'] = sanitize_key($args['plural']); + $args['singular'] = sanitize_key($args['singular']); + + $this->_args = $args; + + if ($args['ajax']) { + // wp_enqueue_script('list-table'); + add_action('admin_footer', array($this, 'js_vars')); + } + + if (empty($this->modes)) { + $this->modes = array( + 'list' => __('List view', 'all-in-one-wp-security-and-firewall'), + 'excerpt' => __('Excerpt view', 'all-in-one-wp-security-and-firewall'), + ); + } + } + + /** + * Make private properties readable for backward compatibility. + * + * @since 4.0.0 + * + * @param string $name Property to get. + * @return mixed|void Property. + */ + public function __get($name) { + if (in_array($name, $this->compat_fields)) { + return $this->$name; + } + } + + /** + * Make private properties settable for backward compatibility. + * + * @since 4.0.0 + * + * @param string $name Property to check if set. + * @param mixed $value Property value. + * @return mixed Newly-set property. + */ + public function __set($name, $value) { + if (in_array($name, $this->compat_fields)) { + return $this->$name = $value; + } + } + + /** + * Make private properties checkable for backward compatibility. + * + * @since 4.0.0 + * + * @param string $name Property to check if set. + * @return bool Whether the property is set. + */ + public function __isset($name) { + if (in_array($name, $this->compat_fields)) { + return isset($this->$name); + } + } + + /** + * Make private properties un-settable for backward compatibility. + * + * @since 4.0.0 + * + * @param string $name Property to unset. + */ + public function __unset($name) { + if (in_array($name, $this->compat_fields)) { + unset($this->$name); + } + } + + /** + * Make private/protected methods readable for backward compatibility. + * + * @since 4.0.0 + * + * @param string $name Method to call. + * @param array $arguments Arguments to pass when calling. + * @return mixed|bool Return value of the callback, false otherwise. + */ + public function __call($name, $arguments) { + if (in_array($name, $this->compat_methods)) { + return call_user_func_array(array($this, $name), $arguments); + } + return false; + } + + /** + * Checks the current user's permissions + * + * @since 3.1.0 + * @abstract + */ + public function ajax_user_can() { + die('function AIOWPSecurity_List_Table::ajax_user_can() must be over-ridden in a sub-class.'); + } + + /** + * Prepares the list of items for displaying. + * + * @uses AIOWPSecurity_List_Table::set_pagination_args() + * + * @since 3.1.0 + * @abstract + */ + public function prepare_items() { + die('function AIOWPSecurity_List_Table::prepare_items() must be over-ridden in a sub-class.'); + } + + /** + * An internal method that sets all the necessary pagination arguments + * + * @since 3.1.0 + * + * @param array|string $args Array or string of arguments with information about the pagination. + */ + protected function set_pagination_args($args) { + $args = wp_parse_args( + $args, + array( + 'total_items' => 0, + 'total_pages' => 0, + 'per_page' => 0, + ) + ); + + if (!$args['total_pages'] && $args['per_page'] > 0) { + $args['total_pages'] = ceil($args['total_items'] / $args['per_page']); + } + + // Redirect if page number is invalid and headers are not already sent. + if (! headers_sent() && ! wp_doing_ajax() && $args['total_pages'] > 0 && $this->get_pagenum() > $args['total_pages']) { + wp_redirect(add_query_arg('paged', $args['total_pages'])); + exit; + } + + $this->_pagination_args = $args; + } + + /** + * Access the pagination args. + * + * @since 3.1.0 + * + * @param string $key Pagination argument to retrieve. Common values include 'total_items', + * 'total_pages', 'per_page', or 'infinite_scroll'. + * @return int Number of items that correspond to the given pagination argument. + */ + public function get_pagination_arg($key) { + if ('page' === $key) { + return $this->get_pagenum(); + } + + if (isset($this->_pagination_args[$key])) { + return $this->_pagination_args[$key]; + } + } + + /** + * Whether the table has items to display or not + * + * @since 3.1.0 + * + * @return bool + */ + public function has_items() { + return ! empty($this->items); + } + + /** + * Message to be displayed when there are no items + * + * @since 3.1.0 + */ + public function no_items() { + esc_html_e('No items found.', 'all-in-one-wp-security-and-firewall'); + } + + /** + * Displays the search box. + * + * @since 3.1.0 + * + * @param string $text The 'submit' button label. + * @param string $input_id ID attribute value for the search input field. + */ + public function search_box($text, $input_id) { + // phpcs:disable WordPress.Security.NonceVerification.Recommended -- No nonce. + if (empty($_REQUEST['s']) && !$this->has_items()) { + return; + } + + $input_id = $input_id . '-search-input'; + + if (!empty($_REQUEST['orderby'])) { + echo ''; + } + if (!empty($_REQUEST['order'])) { + echo ''; + } + if (!empty($_REQUEST['post_mime_type'])) { + echo ''; + } + if (!empty($_REQUEST['detached'])) { + echo ''; + } + // phpcs:enable WordPress.Security.NonceVerification.Recommended -- No nonce. + ?> + + link) with the list + * of views available on this table. + * + * @since 3.1.0 + * + * @return array + */ + protected function get_views() { + return array(); + } + + /** + * Display the list of views available on this table. + * + * @since 3.1.0 + */ + public function views() { + $views = $this->get_views(); + /** + * Filters the list of available list table views. + * + * The dynamic portion of the hook name, `$this->screen->id`, refers + * to the ID of the current screen, usually a string. + * + * @since 3.5.0 + * + * @param string[] $views An array of available list table views. + */ + $views = apply_filters("views_{$this->screen->id}", $views); + + if (empty($views)) { + return; + } + + $this->screen->render_screen_reader_content('heading_views'); + + echo "
    \n"; + foreach ($views as $class => $view) { + $views[$class] = "\t
  • $view"; + } + echo implode(" |
  • \n", array_map('esc_attr', $views)) . "\n"; + echo '
'; + } + + /** + * Get an associative array (option_name => option_title) with the list + * of bulk actions available on this table. + * + * @since 3.1.0 + * + * @return array + */ + protected function get_bulk_actions() { + return array(); + } + + /** + * Display the bulk actions dropdown. + * + * @since 3.1.0 + * + * @param string $which The location of the bulk actions: 'top' or 'bottom'. + * This is designated as optional for backward compatibility. + */ + protected function bulk_actions($which = '') { + if (is_null($this->_actions)) { + $this->_actions = $this->get_bulk_actions(); + /** + * Filters the list table Bulk Actions drop-down. + * + * The dynamic portion of the hook name, `$this->screen->id`, refers + * to the ID of the current screen, usually a string. + * + * This filter can currently only be used to remove bulk actions. + * + * @since 3.5.0 + * + * @param string[] $actions An array of the available bulk actions. + */ + $this->_actions = apply_filters("bulk_actions-{$this->screen->id}", $this->_actions); + $two = ''; + } else { + $two = '2'; + } + + if (empty($this->_actions)) { + return; + } + + echo ''; + echo '\n"; + + $submit_attributes = array('id' => "doaction$two"); + + if ('top' == $which) { + $submit_attributes['onclick'] = "return confirm('".esc_js(__('Are you sure you want to perform this bulk action?', 'all-in-one-wp-security-and-firewall'))."')"; + } + + submit_button(__('Apply', 'all-in-one-wp-security-and-firewall'), 'action', '', false, $submit_attributes); + echo "\n"; + } + + /** + * Get the current action selected from the bulk actions dropdown. + * + * @since 3.1.0 + * + * @return string|false The action name or False if no action was selected + */ + public function current_action() { + // phpcs:disable WordPress.Security.NonceVerification.Recommended -- No nonce. + if (isset($_REQUEST['filter_action']) && ! empty($_REQUEST['filter_action'])) { + return false; + } + + if (isset($_REQUEST['action']) && -1 != $_REQUEST['action']) { + return sanitize_text_field(wp_unslash($_REQUEST['action'])); + } + + if (isset($_REQUEST['action2']) && -1 != $_REQUEST['action2']) { + return sanitize_text_field(wp_unslash($_REQUEST['action2'])); + } + + return false; + // phpcs:enable WordPress.Security.NonceVerification.Recommended -- No nonce. + } + + /** + * Generate row actions div + * + * @since 3.1.0 + * + * @param string[] $actions An array of action links. + * @param bool $always_visible Whether the actions should be always visible. + * @return string + */ + protected function row_actions($actions, $always_visible = false) { + $action_count = count($actions); + $i = 0; + + if (!$action_count) { + return ''; + } + + $out = '
'; + foreach ($actions as $action => $link) { + ++$i; + ($i == $action_count) ? $sep = '' : $sep = ' | '; + $out .= "$link$sep"; + } + $out .= '
'; + + $out .= ''; + + return $out; + } + + /** + * Display a monthly dropdown for filtering items + * + * @since 3.1.0 + * + * @global wpdb $wpdb + * @global WP_Locale $wp_locale + * + * @param string $post_type + */ + protected function months_dropdown($post_type) { + // phpcs:disable WordPress.Security.NonceVerification.Recommended -- No nonce. + global $wpdb, $wp_locale; + + /** + * Filters whether to remove the 'Months' drop-down from the post list table. + * + * @since 4.2.0 + * + * @param bool $disable Whether to disable the drop-down. Default false. + * @param string $post_type The post type. + */ + if (apply_filters('disable_months_dropdown', false, $post_type)) { + return; + } + + $extra_checks = "AND post_status != 'auto-draft'"; + if (! isset($_GET['post_status']) || 'trash' !== $_GET['post_status']) { + $extra_checks .= " AND post_status != 'trash'"; + } elseif (isset($_GET['post_status'])) { + $extra_checks = $wpdb->prepare(' AND post_status = %s', sanitize_text_field(wp_unslash($_GET['post_status']))); + } + + // phpcs:disable WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- PCP warning. Direct call needed. + $months = $wpdb->get_results( + $wpdb->prepare( + " + SELECT DISTINCT YEAR(post_date) AS year, MONTH(post_date) AS month + FROM $wpdb->posts + WHERE post_type = %s + $extra_checks + ORDER BY post_date DESC + ", + $post_type + ) + ); + // phpcs:enable WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- PCP warning. Direct call needed. + + /** + * Filters the 'Months' drop-down results. + * + * @since 3.7.0 + * + * @param object $months The months drop-down query results. + * @param string $post_type The post type. + */ + $months = apply_filters('months_dropdown_results', $months, $post_type); + + $month_count = count($months); + + if (!$month_count || (1 == $month_count && 0 == $months[0]->month)) { + return; + } + + $m = isset($_GET['m']) ? (int) $_GET['m'] : 0; + ?> + + + + +
+ modes as $mode => $title) { + $classes = array('view-' . $mode); + if ($current_mode === $mode) { + $classes[] = 'current'; + } + printf( + "%s\n", + esc_url(add_query_arg('mode', $mode)), + implode(' ', array_map('esc_attr', $classes)), + esc_html($title) + ); + } + ?> +
+
%s', + esc_html__('No comments', 'all-in-one-wp-security-and-firewall') + ); + // Approved comments have different display depending on some conditions. + } elseif ($approved_comments) { + printf( + '%s', + esc_url( + add_query_arg( + array( + 'p' => $post_id, + 'comment_status' => 'approved', + ), + admin_url('edit-comments.php') + ) + ), + esc_html($approved_comments_number), + $pending_comments ? esc_html($approved_phrase) : esc_html($approved_only_phrase) + ); + } else { + printf( + '%s', + esc_html($approved_comments_number), + $pending_comments ? esc_html__('No approved comments', 'all-in-one-wp-security-and-firewall') : esc_html__('No comments', 'all-in-one-wp-security-and-firewall') + ); + } + + if ($pending_comments) { + printf( + '%s', + esc_url( + add_query_arg( + array( + 'p' => $post_id, + 'comment_status' => 'moderated', + ), + admin_url('edit-comments.php') + ) + ), + esc_html($pending_comments_number), + esc_html($pending_phrase) + ); + } else { + printf( + '%s', + esc_html($pending_comments_number), + $approved_comments ? esc_html__('No pending comments', 'all-in-one-wp-security-and-firewall') : esc_html__('No comments', 'all-in-one-wp-security-and-firewall') + ); + } + } + + /** + * Get the current page number + * + * @since 3.1.0 + * + * @return int + */ + public function get_pagenum() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No nonce. + $pagenum = isset($_REQUEST['paged']) ? absint($_REQUEST['paged']) : 0; + + if (isset($this->_pagination_args['total_pages']) && $pagenum > $this->_pagination_args['total_pages']) { + $pagenum = $this->_pagination_args['total_pages']; + } + + return max(1, $pagenum); + } + + /** + * Get number of items to display on a single page + * + * @since 3.1.0 + * + * @param string $option + * @param int $default + * @return int + */ + protected function get_items_per_page($option, $default = 20) { + $per_page = (int) get_user_option($option); + if (empty($per_page) || $per_page < 1) { + $per_page = $default; + } + + /** + * Filters the number of items to be displayed on each page of the list table. + * + * The dynamic hook name, $option, refers to the `per_page` option depending + * on the type of list table in use. Possible values include: 'edit_comments_per_page', + * 'sites_network_per_page', 'site_themes_network_per_page', 'themes_network_per_page', + * 'users_network_per_page', 'edit_post_per_page', 'edit_page_per_page', + * 'edit_{$post_type}_per_page', etc. + * + * @since 2.9.0 + * + * @param int $per_page Number of items to be displayed. Default 20. + */ + return (int) apply_filters("{$option}", $per_page); + } + + /** + * Display the pagination. + * + * @since 3.1.0 + * + * @param string $which + */ + protected function pagination($which) { + if (empty($this->_pagination_args)) { + return; + } + + $total_items = $this->_pagination_args['total_items']; + $total_pages = $this->_pagination_args['total_pages']; + $infinite_scroll = false; + if (isset($this->_pagination_args['infinite_scroll'])) { + $infinite_scroll = $this->_pagination_args['infinite_scroll']; + } + + if ('top' === $which && $total_pages > 1) { + $this->screen->render_screen_reader_content('heading_pagination'); + } + + /* translators: %s: Item count. */ + $output = '' . sprintf(_n('%s item', '%s items', esc_html($total_items), 'all-in-one-wp-security-and-firewall'), number_format_i18n($total_items)) . ''; + + $current = $this->get_pagenum(); + $removable_query_args = wp_removable_query_args(); + + $host = isset($_SERVER['HTTP_HOST']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'])) : ''; + $request = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : ''; + $current_url = set_url_scheme('http://' . $host . $request); + + $current_url = remove_query_arg($removable_query_args, $current_url); + + $page_links = array(); + + $total_pages_before = ''; + $total_pages_after = '
'; + + $disable_first = $disable_last = $disable_prev = $disable_next = false; + + if (1 == $current) { + $disable_first = true; + $disable_prev = true; + } + if (2 == $current) { + $disable_first = true; + } + if ($current == $total_pages) { + $disable_last = true; + $disable_next = true; + } + if ($current == $total_pages - 1) { + $disable_last = true; + } + + if ($disable_first) { + $page_links[] = ''; + } else { + $page_links[] = sprintf( + "%s", + esc_url(remove_query_arg('paged', $current_url)), + esc_html__('First page', 'all-in-one-wp-security-and-firewall'), + '«' + ); + } + + if ($disable_prev) { + $page_links[] = ''; + } else { + $page_links[] = sprintf( + "%s", + esc_url(add_query_arg('paged', max(1, $current - 1), $current_url)), + esc_html__('Previous page', 'all-in-one-wp-security-and-firewall'), + '‹' + ); + } + + if ('bottom' === $which) { + $html_current_page = $current; + $total_pages_before = '' . __('Current page', 'all-in-one-wp-security-and-firewall') . ''; + } else { + $html_current_page = sprintf( + "%s", + '', + $current, + strlen($total_pages) + ); + } + + /* translators %s: Total pages. */ + $html_total_pages = sprintf("%s", number_format_i18n($total_pages)); + /* translators: 1: Current page, 2: Total pages */ + $page_links[] = $total_pages_before . sprintf(esc_html_x('%1$s of %2$s', 'paging', 'all-in-one-wp-security-and-firewall'), $html_current_page, $html_total_pages) . $total_pages_after; + + if ($disable_next) { + $page_links[] = ''; + } else { + $page_links[] = sprintf( + "%s", + esc_url(add_query_arg('paged', min($total_pages, $current + 1), $current_url)), + esc_html__('Next page', 'all-in-one-wp-security-and-firewall'), + '›' + ); + } + + if ($disable_last) { + $page_links[] = ''; + } else { + $page_links[] = sprintf( + "%s", + esc_url(add_query_arg('paged', $total_pages, $current_url)), + esc_html__('Last page', 'all-in-one-wp-security-and-firewall'), + '»' + ); + } + + $pagination_links_class = 'pagination-links'; + if (! empty($infinite_scroll)) { + $pagination_links_class .= ' hide-if-js'; + } + $output .= "\n" . join("\n", $page_links) . ''; + + if ($total_pages) { + $page_class = $total_pages < 2 ? ' one-page' : ''; + } else { + $page_class = ' no-pages'; + } + $this->_pagination = "
$output
"; + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Necessary escaping done above. + echo $this->_pagination; + } + + /** + * Get a list of columns. The format is: + * 'internal-name' => 'Title' + * + * @since 3.1.0 + * @abstract + * + * @return array + */ + public function get_columns() { + die('function AIOWPSecurity_List_Table::get_columns() must be over-ridden in a sub-class.'); + } + + /** + * Get a list of sortable columns. The format is: + * 'internal-name' => 'orderby' + * or + * 'internal-name' => array('orderby', true) + * + * The second format will make the initial sorting order be descending + * + * @since 3.1.0 + * + * @return array + */ + protected function get_sortable_columns() { + return array(); + } + + /** + * Gets the name of the default primary column. + * + * @since 4.3.0 + * + * @return string Name of the default primary column, in this case, an empty string. + */ + protected function get_default_primary_column_name() { + $columns = $this->get_columns(); + $column = ''; + + if (empty($columns)) { + return $column; + } + + // We need a primary defined so responsive views show something, + // so let's fall back to the first non-checkbox column. + foreach ($columns as $col => $column_name) { + if ('cb' === $col) { + continue; + } + + $column = $col; + break; + } + + return $column; + } + + /** + * Public wrapper for AIOWPSecurity_List_Table::get_default_primary_column_name(). + * + * @since 4.4.0 + * + * @return string Name of the default primary column. + */ + public function get_primary_column() { + return $this->get_primary_column_name(); + } + + /** + * Gets the name of the primary column. + * + * @since 4.3.0 + * + * @return string The name of the primary column. + */ + protected function get_primary_column_name() { + $columns = get_column_headers($this->screen); + $default = $this->get_default_primary_column_name(); + + // If the primary column doesn't exist fall back to the + // first non-checkbox column. + if (! isset($columns[$default])) { + $default = AIOWPSecurity_List_Table::get_default_primary_column_name(); + } + + /** + * Filters the name of the primary column for the current list table. + * + * @since 4.3.0 + * + * @param string $default Column name default for the specific list table, e.g. 'name'. + * @param string $context Screen ID for specific list table, e.g. 'plugins'. + */ + $column = apply_filters('list_table_primary_column', $default, $this->screen->id); + + if (empty($column) || ! isset($columns[$column])) { + $column = $default; + } + + return $column; + } + + /** + * Get a list of all, hidden and sortable columns, with filter applied + * + * @since 3.1.0 + * + * @return array + */ + protected function get_column_info() { + // $_column_headers is already set / cached + if (isset($this->_column_headers) && is_array($this->_column_headers)) { + // Back-compat for list tables that have been manually setting $_column_headers for horse reasons. + // In 4.3, we added a fourth argument for primary column. + $column_headers = array(array(), array(), array(), $this->get_primary_column_name()); + foreach ($this->_column_headers as $key => $value) { + $column_headers[$key] = $value; + } + + return $column_headers; + } + + $columns = get_column_headers($this->screen); + $hidden = get_hidden_columns($this->screen); + + $sortable_columns = $this->get_sortable_columns(); + /** + * Filters the list table sortable columns for a specific screen. + * + * The dynamic portion of the hook name, `$this->screen->id`, refers + * to the ID of the current screen, usually a string. + * + * @since 3.5.0 + * + * @param array $sortable_columns An array of sortable columns. + */ + $_sortable = apply_filters("manage_{$this->screen->id}_sortable_columns", $sortable_columns); + + $sortable = array(); + foreach ($_sortable as $id => $data) { + if (empty($data)) { + continue; + } + + $data = (array) $data; + if (! isset($data[1])) { + $data[1] = false; + } + + $sortable[$id] = $data; + } + + $primary = $this->get_primary_column_name(); + $this->_column_headers = array($columns, $hidden, $sortable, $primary); + + return $this->_column_headers; + } + + /** + * Return number of visible columns + * + * @since 3.1.0 + * + * @return int + */ + public function get_column_count() { + list ($columns, $hidden) = $this->get_column_info(); + $hidden = array_intersect(array_keys($columns), array_filter($hidden)); + return count($columns) - count($hidden); + } + + /** + * Print column headers, accounting for hidden and sortable columns. + * + * @since 3.1.0 + * + * @staticvar int $cb_counter + * + * @param bool $with_id Whether to set the id attribute or not + */ + public function print_column_headers($with_id = true) { + // phpcs:disable WordPress.Security.NonceVerification.Recommended -- No nonce. + list($columns, $hidden, $sortable, $primary) = $this->get_column_info(); + + $host = isset($_SERVER['HTTP_HOST']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'])) : ''; + $request = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : ''; + $current_url = set_url_scheme('http://' . $host . $request); + $current_url = remove_query_arg('paged', $current_url); + + if (isset($_GET['orderby'])) { + $current_orderby = sanitize_text_field(wp_unslash($_GET['orderby'])); + } else { + $current_orderby = ''; + } + + if (isset($_GET['order']) && 'desc' === $_GET['order']) { + $current_order = 'desc'; + } else { + $current_order = 'asc'; + } + + if (! empty($columns['cb'])) { + static $cb_counter = 1; + $columns['cb'] = '' + . ''; + $cb_counter++; + } + + foreach ($columns as $column_key => $column_display_name) { + $class = array('manage-column', "column-$column_key"); + + if (in_array($column_key, $hidden)) { + $class[] = 'hidden'; + } + + if ('cb' === $column_key) { + $class[] = 'check-column'; + } elseif (in_array($column_key, array('posts', 'comments', 'links'))) { + $class[] = 'num'; + } + + if ($column_key === $primary) { + $class[] = 'column-primary'; + } + + if (isset($sortable[$column_key])) { + list($orderby, $desc_first) = $sortable[$column_key]; + + if ($current_orderby === $orderby) { + $order = 'asc' === $current_order ? 'desc' : 'asc'; + $class[] = 'sorted'; + $class[] = $current_order; + } else { + $order = $desc_first ? 'desc' : 'asc'; + $class[] = 'sortable'; + $class[] = $desc_first ? 'asc' : 'desc'; + } + + $column_display_name = '' . $column_display_name . ''; + } + + $tag = ('cb' === $column_key) ? 'td' : 'th'; + $scope = ('th' === $tag) ? 'scope="col"' : ''; + $id = $with_id ? "id='$column_key'" : ''; + + if (! empty($class)) { + $class = "class='" . join(' ', $class) . "'"; + } + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped earlier in other functions. + echo "<$tag $scope $id $class>$column_display_name"; + } + // phpcs:enable WordPress.Security.NonceVerification.Recommended -- No nonce. + } + + /** + * Display the table + * + * @since 3.1.0 + */ + public function display() { + $singular = $this->_args['singular']; + + $this->display_tablenav('top'); + + $this->screen->render_screen_reader_content('heading_list'); + ?> + + + + print_column_headers(); ?> + + + + + > + display_rows_or_placeholder(); ?> + + + + + print_column_headers(false); ?> + + + +
+ display_tablenav('bottom'); + } + + /** + * Get a list of CSS classes for the AIOWPSecurity_List_Table table tag. + * + * @since 3.1.0 + * + * @return array List of CSS classes for the table tag. + */ + protected function get_table_classes() { + return array('widefat', 'fixed', 'striped', $this->_args['plural']); + } + + /** + * Generate the table navigation above or below the table + * + * @since 3.1.0 + * @param string $which + */ + protected function display_tablenav($which) { + if ('top' === $which) { + wp_nonce_field('bulk-' . $this->_args['plural']); + } + ?> +
+ + has_items()) : ?> +
+ bulk_actions($which); ?> +
+ extra_tablenav($which); + $this->pagination($which); + ?> + +
+
+ has_items()) { + $this->display_rows(); + } else { + echo ''; + $this->no_items(); + echo ''; + } + } + + /** + * Generate the table rows + * + * @since 3.1.0 + */ + public function display_rows() { + foreach ($this->items as $item) { + $this->single_row($item); + } + } + + /** + * Generates content for a single row of the table + * + * @since 3.1.0 + * + * @param object $item The current item + */ + public function single_row($item) { + echo ''; + $this->single_row_columns($item); + echo ''; + } + + /** + * This function renders a default column item + * + * @param array $item - Item object + * @param string $column_name - Column name to be rendered from item object + */ + protected function column_default($item, $column_name) {} // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable, Squiz.WhiteSpace.ScopeClosingBrace.ContentBefore, PEAR.WhiteSpace.ScopeClosingBrace.Line -- this is a protected function + + /** + * This function renders the checkbox column + * + * @param array $item - item object + */ + protected function column_cb($item) {} // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable, Squiz.WhiteSpace.ScopeClosingBrace.ContentBefore, PEAR.WhiteSpace.ScopeClosingBrace.Line -- this is a protected function + + /** + * Generates the columns for a single row of the table + * + * @since 3.1.0 + * + * @param object $item The current item + */ + protected function single_row_columns($item) { + list($columns, $hidden, $sortable, $primary) = $this->get_column_info(); // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Unused parameters are for future use. + + foreach ($columns as $column_name => $column_display_name) { + $classes = "$column_name column-$column_name"; + if ($primary === $column_name) { + $classes .= ' has-row-actions column-primary'; + } + + if (in_array($column_name, $hidden)) { + $classes .= ' hidden'; + } + + // Comments column uses HTML in the display name with screen reader text. + // Instead of using esc_attr(), we strip tags to get closer to a user-friendly string. + $data = 'data-colname="' . wp_strip_all_tags($column_display_name) . '"'; + + $attributes = "class='$classes' $data"; + + if ('cb' === $column_name) { + echo ''; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP Error. Escaped earlier in other functions. + echo $this->column_cb($item); + echo ''; + } elseif (method_exists($this, '_column_' . $column_name)) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP Error. Escaped earlier in other functions. + echo call_user_func( + array($this, '_column_' . $column_name), + $item, + $classes, + $data, + $primary + ); + } elseif (method_exists($this, 'column_' . $column_name)) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP Error. Escaped earlier in other functions. + echo ""; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP Error. Escaped earlier in other functions. + echo call_user_func(array($this, 'column_' . $column_name), $item); + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP Error. Escaped earlier in other functions. + echo $this->handle_row_actions($item, $column_name, $primary); + echo ''; + } else { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP Error. Escaped earlier in other functions. + echo ""; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP Error. Escaped earlier in other functions. + echo $this->column_default($item, $column_name); + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP Error. Escaped earlier in other functions. + echo $this->handle_row_actions($item, $column_name, $primary); + echo ''; + } + } + } + + /** + * Generates and display row actions links for the list table. + * + * @since 4.3.0 + * + * @param object $item The item being acted upon. + * @param string $column_name Current column name. + * @param string $primary Primary column name. + * @return string The row actions HTML, or an empty string if the current column is the primary column. + */ + protected function handle_row_actions($item, $column_name, $primary) { + return $column_name === $primary ? '' : ''; + } + + /** + * Handle an incoming ajax request (called from admin-ajax.php) + * + * @since 3.1.0 + */ + public function ajax_response() { + $this->prepare_items(); + + ob_start(); + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No nonce. + if (! empty($_REQUEST['no_placeholder'])) { + $this->display_rows(); + } else { + $this->display_rows_or_placeholder(); + } + + $rows = ob_get_clean(); + + $response = array('rows' => $rows); + + if (isset($this->_pagination_args['total_items'])) { + $response['total_items_i18n'] = sprintf( + /* translators: %s: Total items */ + _n('%s item', '%s items', $this->_pagination_args['total_items'], 'all-in-one-wp-security-and-firewall'), + number_format_i18n($this->_pagination_args['total_items']) + ); + } + if (isset($this->_pagination_args['total_pages'])) { + $response['total_pages'] = $this->_pagination_args['total_pages']; + $response['total_pages_i18n'] = number_format_i18n($this->_pagination_args['total_pages']); + } + + die(wp_json_encode($response)); + } + + /** + * Send required variables to JavaScript land + */ + public function js_vars() { + $args = array( + 'class' => get_class($this), + 'screen' => array( + 'id' => $this->screen->id, + 'base' => $this->screen->base, + ), + ); + + printf("\n", wp_json_encode($args)); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/index.html b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/index.html new file mode 100755 index 00000000..e69de29b diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/index.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/index.php new file mode 100755 index 00000000..a64ea405 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/index.php @@ -0,0 +1,4 @@ +admin_includes(); + add_action('admin_menu', array($this, 'setup_menu_items')); + add_action('admin_menu', array($this, 'create_admin_menus')); + add_action('admin_menu', array($this, 'premium_upgrade_submenu'), 40); + add_action('admin_init', array($this, 'aiowps_csv_download')); + } + + add_action('admin_init', array($this, 'hook_admin_notices')); + + // Make sure we are on our plugin's menu pages + if ($this->is_aiowps_admin_page()) { + add_action('admin_print_scripts', array($this, 'admin_menu_page_scripts')); + add_action('admin_print_styles', array($this, 'admin_menu_page_styles')); + add_action('init', array($this, 'init_hook_handler_for_admin_side')); + + if (class_exists('AIOWPS_PREMIUM')) { + add_filter('admin_footer_text', array($this, 'display_footer_review_message')); + } + } + } + + /** + * Sets up the menu items array which is used to build admin menus + * + * @return void + */ + public function setup_menu_items() { + $menu_items = array( + array( + 'page_title' => __('Dashboard', 'all-in-one-wp-security-and-firewall'), + 'menu_title' => __('Dashboard', 'all-in-one-wp-security-and-firewall'), + 'menu_slug' => AIOWPSEC_MAIN_MENU_SLUG, + 'render_callback' => array($this, 'handle_dashboard_menu_rendering'), + 'icon' => 'dashboard', + 'order' => 20, + ), + array( + 'page_title' => __('Settings', 'all-in-one-wp-security-and-firewall'), + 'menu_title' => __('Settings', 'all-in-one-wp-security-and-firewall'), + 'menu_slug' => AIOWPSEC_SETTINGS_MENU_SLUG, + 'render_callback' => array($this, 'handle_settings_menu_rendering'), + 'icon' => 'settings', + 'order' => 30, + ), + array( + 'page_title' => __('User Security', 'all-in-one-wp-security-and-firewall'), + 'menu_title' => __('User Security', 'all-in-one-wp-security-and-firewall'), + 'menu_slug' => AIOWPSEC_USER_SECURITY_MENU_SLUG, + 'render_callback' => array($this, 'handle_user_security_menu_rendering'), + 'icon' => 'user_security', + 'order' => 40, + ), + array( + 'page_title' => __('Database Security', 'all-in-one-wp-security-and-firewall'), + 'menu_title' => __('Database Security', 'all-in-one-wp-security-and-firewall'), + 'menu_slug' => AIOWPSEC_DB_SEC_MENU_SLUG, + 'render_callback' => array($this, 'handle_database_menu_rendering'), + 'icon' => 'database_security', + 'display_condition_callback' => 'is_super_admin', + 'order' => 50, + ), + array( + 'page_title' => __('File Security', 'all-in-one-wp-security-and-firewall'), + 'menu_title' => __('File Security', 'all-in-one-wp-security-and-firewall'), + 'menu_slug' => AIOWPSEC_FILESYSTEM_MENU_SLUG, + 'render_callback' => array($this, 'handle_filesystem_menu_rendering'), + 'icon' => 'filesystem_security', + 'order' => 60, + ), + array( + 'page_title' => __('Firewall', 'all-in-one-wp-security-and-firewall'), + 'menu_title' => __('Firewall', 'all-in-one-wp-security-and-firewall'), + 'menu_slug' => AIOWPSEC_FIREWALL_MENU_SLUG, + 'render_callback' => array($this, 'handle_firewall_menu_rendering'), + 'icon' => 'firewall', + 'order' => 70, + ), + array( + 'page_title' => __('Brute Force', 'all-in-one-wp-security-and-firewall'), + 'menu_title' => __('Brute Force', 'all-in-one-wp-security-and-firewall'), + 'menu_slug' => AIOWPSEC_BRUTE_FORCE_MENU_SLUG, + 'render_callback' => array($this, 'handle_brute_force_menu_rendering'), + 'icon' => 'brute_force', + 'order' => 80, + ), + array( + 'page_title' => __('Spam Prevention', 'all-in-one-wp-security-and-firewall'), + 'menu_title' => __('Spam Prevention', 'all-in-one-wp-security-and-firewall'), + 'menu_slug' => AIOWPSEC_SPAM_MENU_SLUG, + 'render_callback' => array($this, 'handle_spam_menu_rendering'), + 'icon' => 'spam_prevention', + 'order' => 90, + ), + array( + 'page_title' => __('Scanner', 'all-in-one-wp-security-and-firewall'), + 'menu_title' => __('Scanner', 'all-in-one-wp-security-and-firewall'), + 'menu_slug' => AIOWPSEC_FILESCAN_MENU_SLUG, + 'render_callback' => array($this, 'handle_filescan_menu_rendering'), + 'icon' => 'scanner', + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + 'order' => 100, + ), + array( + 'page_title' => __('Tools', 'all-in-one-wp-security-and-firewall'), + 'menu_title' => __('Tools', 'all-in-one-wp-security-and-firewall'), + 'menu_slug' => AIOWPSEC_TOOLS_MENU_SLUG, + 'render_callback' => array($this, 'handle_tools_menu_rendering'), + 'icon' => 'tools', + 'order' => 110, + ), + ); + $menu_items = apply_filters('aiowpsecurity_menu_items', $menu_items); + $this->menu_items = array_filter($menu_items, 'AIOWPSecurity_Utility::should_display_item'); + } + + /** + * Function to get the menu items array + * + * @return array + */ + public function get_menu_items() { + return $this->menu_items; + } + + /** + * This function creates and outputs the csv file for download + * + * @param array $items - the content + * @param array $export_keys - the keys for the content + * @param string $filename - the filename + * + * @return void + */ + public static function aiowps_output_csv($items, $export_keys, $filename = 'data.csv') { + header("Content-Type: text/csv; charset=utf-8"); + header("Content-Disposition: attachment; filename=".$filename); + header("Pragma: no-cache"); + header("Expires: 0"); + $output = fopen('php://output', 'w'); //open output stream + + fputcsv($output, $export_keys, ',', '"', '\\'); // let's put column names first + + foreach ($items as $item) { + $csv_line = array(); + + foreach ($export_keys as $key => $value) { + if (isset($item[$key])) { + $csv_line[] = ('created' == $key) ? AIOWPSecurity_Utility::convert_timestamp($item[$key]) : $item[$key]; + } + } + fputcsv($output, $csv_line, ',', '"', '\\'); + } + } + + /** + * This function will get the content that we want to export as CSV and send it to the download function + * + * @return void + */ + public function aiowps_csv_download() { + global $aio_wp_security; + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- PCP warning. Nonce check in two lines. + if (isset($_POST['aiowps_export_404_event_logs_to_csv'])) {//Export 404 event logs + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- It IS the nonce, so... + $nonce = isset($_REQUEST['_wpnonce']) ? sanitize_key(wp_unslash($_REQUEST['_wpnonce'])) : ''; + $result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($nonce, 'aiowpsec-export-404-event-logs-to-csv-nonce'); + if (is_wp_error($result)) { + $aio_wp_security->debug_logger->log_debug($result->get_error_message(), 4); + die(esc_html($result->get_error_message())); + } + include_once 'wp-security-list-404.php'; //For rendering the AIOWPSecurity_List_Table in tab1 + $event_list_404 = new AIOWPSecurity_List_404(); //For rendering the AIOWPSecurity_List_Table in tab1 + $event_list_404->prepare_items(true); + $export_keys = array( + 'id' => __('Id', 'all-in-one-wp-security-and-firewall'), + 'event_type' => __('Event Type', 'all-in-one-wp-security-and-firewall'), + 'ip_or_host' => __('IP Address', 'all-in-one-wp-security-and-firewall'), + 'url' => __('Attempted URL', 'all-in-one-wp-security-and-firewall'), + 'referer_info' => __('Referer', 'all-in-one-wp-security-and-firewall'), + 'created' => __('Date and time', 'all-in-one-wp-security-and-firewall'), + 'status' => __('Lock Status', 'all-in-one-wp-security-and-firewall'), + ); + AIOWPSecurity_Utility::output_csv($event_list_404->items, $export_keys, '404_event_logs.csv'); + exit(); + } + } + + /** + * Check whether current admin page is All In One WP Security admin page or not. + * + * @return boolean True if All In One WP Security admin page, Otherwise false. + */ + private function is_aiowps_admin_page() { + if (isset($this->is_aiowps_admin_page)) { + return $this->is_aiowps_admin_page; + } + global $pagenow; + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce on this _GET. + $this->is_aiowps_admin_page = (AIOWPSecurity_Utility_Permissions::has_manage_cap() && 'admin.php' == $pagenow && isset($_GET['page']) && false !== strpos(sanitize_title(wp_unslash($_GET['page'])), AIOWPSEC_MENU_SLUG_PREFIX)); + return $this->is_aiowps_admin_page; + } + + /** + * Hook admin notices on admin dashboard page and admin AIOS pages. + * + * @return void + */ + public function hook_admin_notices() { + if (!current_user_can('update_plugins')) { + return; + } + + // If none of the admin dashboard page or the AIOS page, Then bail + if (!$this->is_admin_dashboard_page() && !$this->is_aiowps_admin_page()) { + return; + } + + add_action('all_admin_notices', array($this, 'render_admin_notices')); + } + + /** + * Check whether current admin page is Admin Dashboard page or not. + * + * @return boolean True if Admin Dashboard page, Otherwise false. + */ + private function is_admin_dashboard_page() { + if (isset($this->is_admin_dashboard_page)) { + return $this->is_admin_dashboard_page; + } + global $pagenow; + $this->is_admin_dashboard_page = 'index.php' == $pagenow; + return $this->is_admin_dashboard_page; + } + + /** + * Render admin notices. + * + * @return void + */ + public function render_admin_notices() { + global $aio_wp_security; + + $custom_notice_ids = array_merge(AIOS_Abstracted_Ids::custom_admin_notice_ids(), AIOS_Abstracted_Ids::htaccess_to_php_feature_notice_ids()); + foreach ($custom_notice_ids as $custom_admin_notice_id) { + $aio_wp_security->notices->do_notice($custom_admin_notice_id, $custom_admin_notice_id); + } + + // Bail if the premium plugin is active and does not show ads. + if (AIOWPSecurity_Utility_Permissions::is_premium_installed()) return; + + $installed_at = $aio_wp_security->notices->get_aiowps_plugin_installed_timestamp(); + $time_now = $aio_wp_security->notices->get_time_now(); + $installed_for = $time_now - $installed_at; + + $dismissed_dash_notice_until = (int) $aio_wp_security->configs->get_value('dismissdashnotice'); + + if ($this->is_admin_dashboard_page() && ($installed_at && $time_now > $dismissed_dash_notice_until && $installed_for > (14 * 86400)) || (defined('AIOWPSECURITY_FORCE_DASHNOTICE') && AIOWPSECURITY_FORCE_DASHNOTICE)) { + $aio_wp_security->include_template('notices/thanks-for-using-main-dash.php'); + } elseif ($this->is_aiowps_admin_page() && $installed_at && $installed_for > 14*86400) { + $aio_wp_security->notices->do_notice(false, 'top'); + } + } + + /** + * This function will include any files needed for the admin dashboard + * + * @return void + */ + private function admin_includes() { + include_once('wp-security-admin-menu.php'); + } + + /** + * Enqueue admin JavaScripts. + * + * @return Void + */ + public function admin_menu_page_scripts() { + if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) { + return; + } + + wp_enqueue_script('jquery'); + wp_enqueue_script('postbox'); + wp_enqueue_script('dashboard'); + wp_enqueue_script('thickbox'); + wp_enqueue_script('media-upload'); + wp_enqueue_script('chart-bundle', AIO_WP_SECURITY_URL . '/includes/chartjs/Chart.bundle.min.js', array(), AIO_WP_SECURITY_VERSION, true); + wp_enqueue_script('chartjs-gauge', AIO_WP_SECURITY_URL . '/includes/chartjs/chartjs-gauge.min.js', array(), AIO_WP_SECURITY_VERSION, true); + wp_register_script('jquery-blockui', AIO_WP_SECURITY_URL.'/includes/blockui/jquery.blockUI.js', array('jquery'), AIO_WP_SECURITY_VERSION, true); + wp_enqueue_script('jquery-blockui'); + wp_register_script('aiowpsec-admin-js', AIO_WP_SECURITY_URL. '/js/wp-security-admin-script.js', array('jquery'), AIO_WP_SECURITY_VERSION, true); + wp_enqueue_script('aiowpsec-admin-js'); + wp_localize_script('aiowpsec-admin-js', + 'aios_data', + array( + 'ajax_nonce' => wp_create_nonce('wp-security-ajax-nonce'), + ) + ); + wp_localize_script('aiowpsec-admin-js', + 'aios_trans', + array( + 'unexpected_response' => __('Unexpected response:', 'all-in-one-wp-security-and-firewall'), + 'copied' => __('Copied', 'all-in-one-wp-security-and-firewall'), + 'no_import_file' => __('You have not yet selected a file to import.', 'all-in-one-wp-security-and-firewall'), + 'processing' => __('Processing...', 'all-in-one-wp-security-and-firewall'), + 'invalid_domain' => __('Please enter a valid IP address or domain name.', 'all-in-one-wp-security-and-firewall'), + 'logo' => AIO_WP_SECURITY_URL.'/images/plugin-logos/icon-aios-rgb.svg', + 'saving' => __('Saving...', 'all-in-one-wp-security-and-firewall'), + 'deleting' => __('Deleting...', 'all-in-one-wp-security-and-firewall'), + 'blocking' => __('Blocking...', 'all-in-one-wp-security-and-firewall'), + 'unlocking' => __('Unlocking...', 'all-in-one-wp-security-and-firewall'), + 'clearing' => __('Clearing...', 'all-in-one-wp-security-and-firewall'), + 'importing' => __('Importing...', 'all-in-one-wp-security-and-firewall'), + 'exporting' => __('Exporting...', 'all-in-one-wp-security-and-firewall'), + 'refreshing' => __('Refreshing...', 'all-in-one-wp-security-and-firewall'), + 'scanning' => __('Scanning...', 'all-in-one-wp-security-and-firewall'), + 'close' => __('Close', 'all-in-one-wp-security-and-firewall'), + 'completed' => __('Completed.', 'all-in-one-wp-security-and-firewall'), + 'refreshed' => __('Refreshed.', 'all-in-one-wp-security-and-firewall'), + 'deleted' => __('Deleted.', 'all-in-one-wp-security-and-firewall'), + 'show_info' => __('show more', 'all-in-one-wp-security-and-firewall'), + 'hide_info' => __('hide', 'all-in-one-wp-security-and-firewall'), + 'show_notices' => __('But the following notices have been raised', 'all-in-one-wp-security-and-firewall'), + 'disabling' => __('Disabling...', 'all-in-one-wp-security-and-firewall'), + 'setting_up_firewall' => __('Setting up firewall...', 'all-in-one-wp-security-and-firewall'), + 'downgrading_firewall' => __('Downgrading firewall...', 'all-in-one-wp-security-and-firewall'), + 'maintenance_mode_enabled' => __('Maintenance mode is currently enabled.', 'all-in-one-wp-security-and-firewall') . ' ' . __('Remember to disable it when you are done.', 'all-in-one-wp-security-and-firewall'), + 'maintenance_mode_disabled' => __('Maintenance mode is currently disabled.', 'all-in-one-wp-security-and-firewall'), + ) + ); + wp_register_script('aiowpsec-pw-tool-js', AIO_WP_SECURITY_URL. '/js/password-strength-tool.js', array('jquery'), AIO_WP_SECURITY_VERSION, true); // We will enqueue this in the user acct menu class + wp_localize_script('aiowpsec-pw-tool-js', + 'aios_pwtool_trans', + array( + 'years' => __('year(s)', 'all-in-one-wp-security-and-firewall'), + 'months' => __('month(s)', 'all-in-one-wp-security-and-firewall'), + 'days' => __('day(s)', 'all-in-one-wp-security-and-firewall'), + 'hours' => __('hour(s)', 'all-in-one-wp-security-and-firewall'), + 'minutes' => __('minute(s)', 'all-in-one-wp-security-and-firewall'), + 'seconds' => __('second(s)', 'all-in-one-wp-security-and-firewall'), + 'less_than_one_second' => __('less than one second', 'all-in-one-wp-security-and-firewall') + ) + ); + } + + /** + * Enqueue admin styles. + * + * @return Void + */ + public function admin_menu_page_styles() { + wp_enqueue_style('dashboard'); + wp_enqueue_style('thickbox'); + wp_enqueue_style('global'); + wp_enqueue_style('wp-admin'); + $admin_css_version = (defined('WP_DEBUG') && WP_DEBUG) ? time() : filemtime(AIO_WP_SECURITY_PATH. '/css/wp-security-admin-styles.css'); + wp_enqueue_style('aiowpsec-admin-css', AIO_WP_SECURITY_URL. '/css/wp-security-admin-styles.css', array(), $admin_css_version); + } + + /** + * Sets up various class and tasks needed for the admin dashboard + * + * @return void + */ + public function init_hook_handler_for_admin_side() { + $this->initialize_feature_manager(); + $this->do_other_admin_side_init_tasks(); + } + + /** + * Show footer review message and link. + * + * @return string + */ + public function display_footer_review_message() { + $message = sprintf( + /* translators: 1: Product Name, 2: Rating, 3: Trustpilot URL, 4: G2 URL */ + __('Enjoyed %1$s? Please leave us a %2$s rating on %3$s or %4$s', 'all-in-one-wp-security-and-firewall').' '.__('We really appreciate your support!', 'all-in-one-wp-security-and-firewall'), + '' . htmlspecialchars('All In One Security') . '', + '★★★★★', + 'Trustpilot', + 'G2.com' + ); + return $message; + } + + /** + * This function checks if the feature manager is initialized and initializes it if it is not then checks the feature status and recalculates the points + * + * @return void + */ + private function initialize_feature_manager() { + if (!isset($aiowps_feature_mgr)) { + $aiowps_feature_mgr = new AIOWPSecurity_Feature_Item_Manager(); + $aiowps_feature_mgr->check_feature_status_and_recalculate_points(); + $GLOBALS['aiowps_feature_mgr'] = $aiowps_feature_mgr; + } + } + + /** + * Other admin side init tasks. + * + * @return Void + */ + private function do_other_admin_side_init_tasks() { + global $aio_wp_security; + + //***New Feature improvement for Cookie Based Brute Force Protection***// + // The old "test cookie" used to be too easy to guess because someone could just read the code and get the value. + //So now we will drop a more secure test cookie using a 10 digit random string + + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention')) { + // This code is for users who had this feature saved using an older release. This will drop the new more secure test cookie to the browser + $test_cookie_name_saved = $aio_wp_security->configs->get_value('aiowps_cookie_brute_test'); + if (empty($test_cookie_name_saved)) { + $random_suffix = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(10); + $test_cookie_name = 'aiowps_cookie_test_'.$random_suffix; + $aio_wp_security->configs->set_value('aiowps_cookie_brute_test', $test_cookie_name, true); + AIOWPSecurity_Utility::set_cookie_value($test_cookie_name, '1'); + } + } + + // For cookie test form submission case + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- PCP warning. No nonce on this _GET. + if (isset($_GET['page']) && AIOWPSEC_BRUTE_FORCE_MENU_SLUG == $_GET['page'] && isset($_GET['tab']) && 'cookie-based-brute-force-prevention' == $_GET['tab']) { + if (isset($_POST['aiowps_do_cookie_test_for_bfla'])) { + $random_suffix = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(10); + $test_cookie_name = 'aiowps_cookie_test_'.$random_suffix; + $aio_wp_security->configs->set_value('aiowps_cookie_brute_test', $test_cookie_name, true); + AIOWPSecurity_Utility::set_cookie_value($test_cookie_name, '1'); + $cur_url = "admin.php?page=".AIOWPSEC_BRUTE_FORCE_MENU_SLUG."&tab=cookie-based-brute-force-prevention"; + $redirect_url = AIOWPSecurity_Utility::add_query_data_to_url($cur_url, 'aiowps_cookie_test', "1"); + AIOWPSecurity_Utility::redirect_to_url($redirect_url); + } + + if (isset($_REQUEST['aiowps_cookie_test'])) { + $test_cookie = $aio_wp_security->configs->get_value('aiowps_cookie_brute_test'); + $cookie_val = AIOWPSecurity_Utility::get_cookie_value($test_cookie); + if (empty($cookie_val)) { + $aio_wp_security->configs->set_value('aiowps_cookie_test_success', ''); + } else { + $aio_wp_security->configs->set_value('aiowps_cookie_test_success', '1'); + } + $aio_wp_security->configs->save_config();//save the value + } + } + } + + /** + * Adds admin menu page and all submenus to the WordPress dashboard + * + * @return void + */ + public function create_admin_menus() { + $menu_icon_url = AIO_WP_SECURITY_URL.'/images/aios-plugin-icon.svg'; + $this->main_menu_page = add_menu_page(__('AIOS', 'all-in-one-wp-security-and-firewall'), __('AIOS', 'all-in-one-wp-security-and-firewall'), apply_filters('aios_management_permission', 'manage_options'), AIOWPSEC_MAIN_MENU_SLUG, array($this, 'handle_dashboard_menu_rendering'), $menu_icon_url); + + foreach ($this->menu_items as $menu_item) { + add_submenu_page(AIOWPSEC_MAIN_MENU_SLUG, $menu_item['page_title'], $menu_item['menu_title'], apply_filters('aios_management_permission', 'manage_options'), $menu_item['menu_slug'], $menu_item['render_callback'], $menu_item['order']); + } + + do_action('aiowpsecurity_admin_menu_created'); + } + + /** + * Adds submenu link for premium upgrade tab. + * + * @return Void + */ + public function premium_upgrade_submenu() { + if (!AIOWPSecurity_Utility_Permissions::is_premium_installed()) { + global $submenu; + $submenu[AIOWPSEC_MAIN_MENU_SLUG][] = array(__('Premium Upgrade', 'all-in-one-wp-security-and-firewall'), apply_filters('aios_management_permission', 'manage_options'), 'admin.php?page='.AIOWPSEC_MAIN_MENU_SLUG.'&tab=premium-upgrade'); + } + } + + /** + * Renders 'Dashboard' submenu page. + * + * @return Void + */ + public function handle_dashboard_menu_rendering() { + include_once('wp-security-dashboard-menu.php'); + new AIOWPSecurity_Dashboard_Menu(); + } + + /** + * Renders 'Settings' submenu page. + * + * @return Void + */ + public function handle_settings_menu_rendering() { + include_once('wp-security-settings-menu.php'); + new AIOWPSecurity_Settings_Menu(); + } + + /** + * Renders 'User Security' submenu page. + * + * @return Void + */ + public function handle_user_security_menu_rendering() { + include_once('wp-security-user-security-menu.php'); + new AIOWPSecurity_User_Security_Menu(); + } + + /** + * Renders 'Database Security' submenu page. + * + * @return Void + */ + public function handle_database_menu_rendering() { + include_once('wp-security-database-menu.php'); + new AIOWPSecurity_Database_Menu(); + } + + /** + * Renders 'Filesystem Security' submenu page. + * + * @return Void + */ + public function handle_filesystem_menu_rendering() { + include_once('wp-security-filesystem-menu.php'); + new AIOWPSecurity_Filesystem_Menu(); + } + + /** + * Renders 'Firewall' submenu page. + * + * @return Void + */ + public function handle_firewall_menu_rendering() { + include_once('wp-security-firewall-menu.php'); + new AIOWPSecurity_Firewall_Menu(); + } + + /** + * Renders 'Brute Force' submenu page. + * + * @return Void + */ + public function handle_brute_force_menu_rendering() { + include_once('wp-security-brute-force-menu.php'); + new AIOWPSecurity_Brute_Force_Menu(); + } + + /** + * Renders 'Spam Prevention' submenu page. + * + * @return Void + */ + public function handle_spam_menu_rendering() { + include_once('wp-security-spam-menu.php'); + new AIOWPSecurity_Spam_Menu(); + } + + /** + * Renders 'Scanner' submenu page. + * + * @return Void + */ + public function handle_filescan_menu_rendering() { + include_once('wp-security-filescan-menu.php'); + new AIOWPSecurity_Filescan_Menu(); + } + + /** + * Renders 'Tools' submenu page. + * + * @return Void + */ + public function handle_tools_menu_rendering() { + include_once('wp-security-tools-menu.php'); + new AIOWPSecurity_Tools_Menu(); + } + +} // End of class diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-admin-menu.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-admin-menu.php new file mode 100755 index 00000000..23e003ad --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-admin-menu.php @@ -0,0 +1,280 @@ +setup_menu_tabs(); + $this->render_page($title); + } + + /** + * Render the menu page + * + * @param string $title - the page title + * + * @return void + */ + protected function render_page($title) { + $current_tab = $this->get_current_tab(); + ?> +
+

+ render_tabs($current_tab); ?> +
+
+ menu_tabs[$current_tab]['render_callback']); ?> +
+
+
+ '; + foreach ($this->menu_tabs as $tab_key => $tab_info) { + $active = $current_tab == $tab_key ? 'nav-tab-active' : ''; + echo '' . esc_html($tab_info['title']) . ''; + } + echo ''; + } + + /** + * Get valid current tab slug. + * + * @return string - current valid tab slug or empty string + */ + protected function get_current_tab() { + if (is_array($this->menu_tabs) && !empty($this->menu_tabs)) { + $tab_keys = array_keys($this->menu_tabs); + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce available. + if (empty($_GET['tab'])) { + return $tab_keys[0]; + } else { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce available. + $current_tab = sanitize_text_field(wp_unslash($_GET['tab'])); + return in_array($current_tab, $tab_keys) ? $current_tab : $tab_keys[0]; + } + } else { + return ''; + } + } + + /** + * This function checks to see if there is a display condition for the tab and if so runs it otherwise it returns true to display the tab + * + * @param array $tab_info - the tab information array contains keys like title, render_callback and display_condition_callback + * + * @return boolean - true if the tab should be displayed or false to hide it + */ + protected function should_display_tab($tab_info) { + return AIOWPSecurity_Utility::apply_callback_filter($tab_info, 'display_condition_callback'); + } + + /** + * Shows postbox for settings menu + * + * @param string $id - css ID for postbox + * @param string $title - title of the postbox section + * @param string $content - the content of the postbox + **/ + protected function postbox_toggle($id, $title, $content) { + //Always send string with translation markers in it + ?> +
+

+

+
+ +
+
+ +
+

+
+ +
+
+

'; + $message .= esc_html__('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall'); + $message .= '

'; + if ($return_instead_of_echo) return $message; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variable contains escaped HTML. + echo $message; + } + + /** + * Render settings successfully updated message + * + * @param bool $return_instead_of_echo - This is used for when the function needs to return the message + * + * @return string|void + */ + public static function show_msg_settings_updated_st($return_instead_of_echo = false) { + $message = '

'; + $message .= esc_html__('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall'); + $message .= '

'; + if ($return_instead_of_echo) return $message; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variable contains escaped HTML. + echo $message; + } + + /** + * Renders record(s) successfully deleted message at top of page. + * + * @param bool $return_instead_of_echo - This is used for when the function needs to return the message + * @return mixed + */ + public static function show_msg_record_deleted_st($return_instead_of_echo = false) { + return AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected record(s) has been deleted successfully.', 'all-in-one-wp-security-and-firewall'), $return_instead_of_echo); + } + + /** + * Renders record(s) unsuccessfully deleted message at top of page. + * + * @param bool $return_instead_of_echo - This is used for when the function needs to return the message + * @return mixed + */ + public static function show_msg_record_not_deleted_st($return_instead_of_echo = false) { + return AIOWPSecurity_Admin_Menu::show_msg_error_st(__('The selected record(s) have failed to delete.', 'all-in-one-wp-security-and-firewall'), $return_instead_of_echo); + } + + /** + * Render successfully updated message + * + * @param string $msg - This contains the message to show + * @param bool $return_instead_of_echo - This is used for when the function needs to return the message + * + * @return string|void + */ + public function show_msg_updated($msg, $return_instead_of_echo = false) { + $message = '

'; + $message .= wp_kses_post($msg); + $message .= '

'; + if ($return_instead_of_echo) return $message; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variable contains escaped HTML. + echo $message; + } + + /** + * Render successfully updated message + * + * @param string $msg - This contains the message to show + * @param bool $return_instead_of_echo - This is used for when the function needs to return the message + * + * @return string|void + */ + public static function show_msg_updated_st($msg, $return_instead_of_echo = false) { + $message = '

'; + $message .= wp_kses_post($msg); + $message .= '

'; + if ($return_instead_of_echo) return $message; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variable contains escaped HTML. + echo $message; + } + + /** + * Render error message + * + * @param string $error_msg - This contains the message to show + * @param bool $return_instead_of_echo - This is used for when the function needs to return the message + * + * @return string|void + */ + public function show_msg_error($error_msg, $return_instead_of_echo = false) { + $message = '

'; + $message .= wp_kses_post($error_msg); + $message .= '

'; + if ($return_instead_of_echo) return $message; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variable contains escaped HTML. + echo $message; + } + + /** + * Render error message + * + * @param string $error_msg - This contains the message to show + * @param bool $return_instead_of_echo - This is used for when the function needs to return the message + * + * @return string|void + */ + public static function show_msg_error_st($error_msg, $return_instead_of_echo = false) { + $message = '

'; + $message .= wp_kses_post($error_msg); + $message .= '

'; + if ($return_instead_of_echo) return $message; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variable contains escaped HTML. + echo $message; + } + + protected function start_buffer() { + ob_start(); + } + + protected function end_buffer_and_collect() { + $output = ob_get_contents(); + ob_end_clean(); + return $output; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-brute-force-menu.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-brute-force-menu.php new file mode 100755 index 00000000..a6c16995 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-brute-force-menu.php @@ -0,0 +1,176 @@ + array( + 'title' => __('Rename login page', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_rename_login'), + ), + 'cookie-based-brute-force-prevention' => array( + 'title' => __('Cookie based brute force prevention', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_cookie_based_brute_force_prevention'), + 'display_condition_callback' => 'is_main_site', + ), + 'captcha-settings' => array( + 'title' => __('CAPTCHA settings', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_captcha_settings'), + ), + 'login-whitelist' => array( + 'title' => __('Login whitelist', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_login_whitelist'), + ), + '404-detection' => array( + 'title' => __('404 detection', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_404_detection'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ), + 'honeypot' => array( + 'title' => __('Honeypot', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_honeypot'), + ), + ); + + $this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab')); + } + + /** + * Rename login page tab. + * + * @global $aio_wp_security + * @global $aiowps_feature_mgr + */ + protected function render_rename_login() { + global $aio_wp_security, $aiowps_feature_mgr; + + if (get_option('permalink_structure')) { + $home_url = trailingslashit(home_url()); + } else { + $home_url = trailingslashit(home_url()) . '?'; + } + + $aio_wp_security->include_template('wp-admin/brute-force/rename-login.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr, 'home_url' => $home_url)); + } + + /** + * Cookie based brute force prevention tab. + * + * @global $aio_wp_security + * @global $aiowps_feature_mgr + * + * @return void + */ + protected function render_cookie_based_brute_force_prevention() { + global $aio_wp_security; + global $aiowps_feature_mgr; + + $aio_wp_security->include_template('wp-admin/brute-force/cookie-based-brute-force-prevention.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr)); + } + + /** + * Login captcha tab. + * + * @global $aio_wp_security + * @global $aiowps_feature_mgr + * + * @return void + */ + protected function render_captcha_settings() { + global $aio_wp_security, $aiowps_feature_mgr; + + $supported_captchas = $aio_wp_security->captcha_obj->get_supported_captchas(); + $captcha_themes = $aio_wp_security->captcha_obj->get_captcha_themes(); + + $captcha_theme = 'auto'; + if ('cloudflare-turnstile' == $aio_wp_security->configs->get_value('aiowps_default_captcha')) $captcha_theme = $aio_wp_security->configs->get_value('aiowps_turnstile_theme'); + + if ('cloudflare-turnstile' == $aio_wp_security->configs->get_value('aiowps_default_captcha') && false === $aio_wp_security->captcha_obj->cloudflare_turnstile_verify_configuration($aio_wp_security->configs->get_value('aiowps_turnstile_site_key'), $aio_wp_security->configs->get_value('aiowps_turnstile_secret_key'))) { + echo '

' . esc_html__('Your Cloudflare Turnstile configuration is invalid.', 'all-in-one-wp-security-and-firewall').' ' . esc_html__('Please enter the correct Cloudflare Turnstile keys below to use the Turnstile feature.', 'all-in-one-wp-security-and-firewall').'

'; + } + + if ('1' == $aio_wp_security->configs->get_value('aios_google_recaptcha_invalid_configuration')) { + echo '

' . esc_html__('Your Google reCAPTCHA configuration is invalid.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('Please enter the correct reCAPTCHA keys below to use the reCAPTCHA feature.', 'all-in-one-wp-security-and-firewall').'

'; + } + + $default_captcha = $aio_wp_security->configs->get_value('aiowps_default_captcha'); + $aio_wp_security->include_template('wp-admin/brute-force/captcha-settings.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr, 'supported_captchas' => $supported_captchas, 'default_captcha' => $default_captcha, 'captcha_themes' => $captcha_themes, 'captcha_theme' => $captcha_theme)); + } + + /** + * Login whitelist tab. + * + * @return void + * @global $aio_wp_security + * @global $aiowps_feature_mgr + */ + protected function render_login_whitelist() { + global $aio_wp_security, $aiowps_feature_mgr; + $ip_v4 = false; + $your_ip_address = AIOWPSecurity_Utility_IP::get_user_ip_address(); + if (filter_var($your_ip_address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) $ip_v4 = true; + + $aiowps_allowed_ip_addresses = $aio_wp_security->configs->get_value('aiowps_allowed_ip_addresses'); + $aio_wp_security->include_template('wp-admin/brute-force/login-whitelist.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr, 'your_ip_address' => $your_ip_address, 'ip_v4' => $ip_v4, 'aiowps_allowed_ip_addresses' => $aiowps_allowed_ip_addresses)); + } + + /** + * Renders the 404 Detection tab + * + * @return void + */ + protected function render_404_detection() { + global $aio_wp_security; + + include_once 'wp-security-list-404.php'; // For rendering the AIOWPSecurity_List_Table in basic-firewall tab + $event_list_404 = new AIOWPSecurity_List_404(); // For rendering the AIOWPSecurity_List_Table in basic-firewall tab + + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce available. + $page = isset($_REQUEST['page']) ? sanitize_text_field(wp_unslash($_REQUEST['page'])) : ''; + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce available. + $tab = isset($_REQUEST["tab"]) ? sanitize_text_field(wp_unslash($_REQUEST["tab"])) : ''; + $aio_wp_security->include_template('wp-admin/brute-force/404-detection.php', false, array('event_list_404' => $event_list_404, 'page' => $page, 'tab' => $tab)); + } + + /** + * Honeypot tab. + * + * @global $aio_wp_security + * @global $aiowps_feature_mgr + * + * @return void + */ + protected function render_honeypot() { + global $aio_wp_security, $aiowps_feature_mgr; + + $aio_wp_security->include_template('wp-admin/brute-force/honeypot.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr)); + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-dashboard-menu.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-dashboard-menu.php new file mode 100755 index 00000000..e997bd8f --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-dashboard-menu.php @@ -0,0 +1,653 @@ + array( + 'title' => __('Dashboard', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_dashboard'), + ), + 'locked-ip' => array( + 'title' => __('Locked IP addresses', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_locked_ip'), + ), + 'permanent-block' => array( + 'title' => __('Permanent block list', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_permanent_block'), + ), + 'audit-logs' => array( + 'title' => __('Audit logs', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_audit_logs'), + ), + 'debug-logs' => array( + 'title' => __('Debugging', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_debug_logs'), + ), + 'premium-upgrade' => array( + 'title' => __('Premium upgrade', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_premium_upgrade_tab'), + 'display_condition_callback' => function() { + return !AIOWPSecurity_Utility_Permissions::is_premium_installed(); + } + ), + ); + + $this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab')); + } + + /** + * Renders the submenu's dashboard tab + * + * @return Void + */ + protected function render_dashboard() { + /** + * Load WordPress dashboard API + */ + require_once(ABSPATH . 'wp-admin/includes/dashboard.php'); + $this->wp_dashboard_setup(); + + wp_enqueue_script('dashboard'); + if (wp_is_mobile()) wp_enqueue_script('jquery-touch-punch'); + + ?> + + +
+ wp_dashboard(); ?> +
+ include_template('wp-admin/dashboard/locked-ip.php', false, array('locked_ip_list' => $locked_ip_list, 'page' => $page, 'tab' => $tab)); + } + + /** + * Renders the submenu's permanent block tab + * + * @return Void + */ + protected function render_permanent_block() { + global $aio_wp_security; + include_once 'wp-security-list-permanent-blocked-ip.php'; // For rendering the AIOWPSecurity_List_Table + $blocked_ip_list = new AIOWPSecurity_List_Blocked_IP(); // For rendering the AIOWPSecurity_List_Table + $tab = isset($_REQUEST["tab"]) ? sanitize_text_field(wp_unslash($_REQUEST["tab"])) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce for tab. + $page = isset($_REQUEST['page']) ? sanitize_text_field(wp_unslash($_REQUEST['page'])) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce for page. + + $aio_wp_security->include_template('wp-admin/dashboard/permanent-block.php', false, array('blocked_ip_list' => $blocked_ip_list, 'page' => $page, 'tab' => $tab)); + } + + /** + * Renders the submenu's audit logs tab + * + * @return void + */ + protected function render_audit_logs() { + global $aio_wp_security; + + // Needed for rendering the audit log table + include_once 'wp-security-list-audit.php'; + $data = array(); + // phpcs:disable WordPress.Security.NonceVerification.Recommended -- PCP warning. Processing form data without nonce verification. No nonce. + if (isset($_GET['event-filter'])) $data['event-filter'] = sanitize_text_field(wp_unslash($_GET['event-filter'])); // Failed logins and logins only to show as audit log + $audit_log_list = new AIOWPSecurity_List_Audit_Log($data); + $tab = isset($_REQUEST["tab"]) ? sanitize_text_field(wp_unslash($_REQUEST["tab"])) : ''; + $page = isset($_REQUEST['page']) ? sanitize_text_field(wp_unslash($_REQUEST['page'])) : ''; + // phpcs:enable WordPress.Security.NonceVerification.Recommended -- PCP warning. Processing form data without nonce verification. No nonce. + + $aio_wp_security->include_template('wp-admin/dashboard/audit-logs.php', false, array('audit_log_list' => $audit_log_list, 'page' => $page, 'tab' => $tab)); + } + + /** + * Renders the submenu's debug logs tab + * + * @return void + */ + protected function render_debug_logs() { + // Needed for rendering the debug log table + include_once 'wp-security-list-debug.php'; + $debug_log_list = new AIOWPSecurity_List_Debug_Log(); + global $aio_wp_security; + $aio_wp_security->include_template('wp-admin/dashboard/debug-logs.php', false, array('debug_log_list' => $debug_log_list)); + } + + /** + * Renders the submenu's premium-upgrade tab body. + * + * @return Void + */ + protected function render_premium_upgrade_tab() { + global $aio_wp_security; + $enqueue_version = (defined('WP_DEBUG') && WP_DEBUG) ? AIO_WP_SECURITY_VERSION.'.'.time() : AIO_WP_SECURITY_VERSION; + wp_enqueue_style('aiowpsec-admin-premium-upgrade-css', AIO_WP_SECURITY_URL.'/css/wp-security-premium-upgrade.css', array(), $enqueue_version); + + echo '
'; + + $aio_wp_security->include_template('wp-admin/dashboard/may-also-like.php'); + + echo '
'; + } + + /** + * Function to customize the layout of the WordPress dashboard. + * Organizes meta-boxes into different containers based on screen columns. + */ + private function wp_dashboard() { + $screen = get_current_screen(); + $columns = absint($screen->get_columns()); + $columns_css = ''; + if ($columns) { + $columns_css = " columns-$columns"; + } + + ?> +
+
+ id, 'normal', ''); ?> +
+
+ id, 'side', ''); ?> +
+
+ id, 'column3', ''); ?> +
+
+ id, 'column4', ''); ?> +
+
+ + configs->get_value('aiowps_enable_brute_force_attack_prevention') + || '1' == $aio_wp_security->configs->get_value('aiowps_enable_rename_login_page') + ) { + wp_add_dashboard_widget('brute_force', __('Brute force prevention login page', 'all-in-one-wp-security-and-firewall'), array($this, 'widget_brute_force')); + } + wp_add_dashboard_widget('logged_in_users', __('Logged in users', 'all-in-one-wp-security-and-firewall'), array($this, 'widget_logged_in_users')); + wp_add_dashboard_widget('locked_ip_addresses', __('Locked IP addresses', 'all-in-one-wp-security-and-firewall'), array($this, 'widget_locked_ip_addresses')); + + do_action('aiowps_dashboard_setup'); + $dashboard_widgets = apply_filters('aiowps_dashboard_widgets', array()); + + foreach ($dashboard_widgets as $widget_id) { + $name = empty($wp_registered_widgets[$widget_id]['all_link']) ? $wp_registered_widgets[$widget_id]['name'] : $wp_registered_widgets[$widget_id]['name'] . " " . __('View all', 'all-in-one-wp-security-and-firewall') . ''; + wp_add_dashboard_widget($widget_id, $name, $wp_registered_widgets[$widget_id]['callback'], $wp_registered_widget_controls[$widget_id]['callback']); + } + } + + public function widget_security_strength_meter() { + global $aiowps_feature_mgr; + $total_site_security_points = $aiowps_feature_mgr->get_total_site_points(); + $total_security_points_achievable = $aiowps_feature_mgr->get_total_achievable_points(); + ?> + + +
+ +
+ +

' . esc_html($total_site_security_points) . ''; ?>

+ +
+ + feature_items; + $pt_src_chart_data = ""; + $pt_src_chart_data .= "['Feature Name', 'Points'],"; + foreach ($feature_items as $item) { + if ($item->is_active()) { + $pt_src_chart_data .= "['" . esc_html($item->feature_name) . "', " . esc_html($item->item_points) . "],"; + } + } + + ?> + + + +
+ +

+

X +

+

+ +

+

+ +

+ +

+

Team UpdraftPlus

+ array( + 'name' => __('Admin username', 'all-in-one-wp-security-and-firewall'), + 'url' => AIOWPSEC_USER_SECURITY_MENU_SLUG, + ), + 'user-login-login-lockdown' => array( + 'name' => __('Login lockout', 'all-in-one-wp-security-and-firewall'), + 'url' => AIOWPSEC_USER_SECURITY_MENU_SLUG . '&tab=login-lockout', + ), + 'filesystem-file-permissions' => array( + 'name' => __('File permission', 'all-in-one-wp-security-and-firewall'), + 'url' => AIOWPSEC_FILESYSTEM_MENU_SLUG, + 'feature_callback' => 'is_main_site' + ), + 'firewall-basic-rules' => array( + 'name' => __('Basic firewall', 'all-in-one-wp-security-and-firewall'), + 'url' => AIOWPSEC_FIREWALL_MENU_SLUG . '&tab=htaccess-rules', + 'feature_callback' => array('AIOWPSecurity_Utility', 'allow_to_write_to_htaccess') + ), + 'db-security-db-prefix' => array( + 'name' => __('Database prefix', 'all-in-one-wp-security-and-firewall'), + 'url' => AIOWPSEC_DB_SEC_MENU_SLUG, + 'feature_callback' => 'is_main_site' + ), + 'filesystem-file-editing' => array( + 'name' => __('PHP file editing', 'all-in-one-wp-security-and-firewall'), + 'url' => AIOWPSEC_FILESYSTEM_MENU_SLUG . '&tab=file-protection', + 'feature_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin') + ), + 'bf-rename-login-page' => array( + 'name' => __('Renamed login page', 'all-in-one-wp-security-and-firewall'), + 'url' => AIOWPSEC_BRUTE_FORCE_MENU_SLUG, + ), + 'wp-generator-meta-tag' => array( + 'name' => __('Hidden WP meta info', 'all-in-one-wp-security-and-firewall'), + 'url' => AIOWPSEC_SETTINGS_MENU_SLUG . '&tab=wp-version-info', + ), + ); + + $critical_features = apply_filters('aiowps_filter_critical_features_array', $critical_features); + $critical_features = array_filter($critical_features, array($this, 'should_add_feature')); + + esc_html_e('Below is the current status of the critical features that you should activate on your site to achieve a minimum level of recommended security', 'all-in-one-wp-security-and-firewall'); + echo '
'; + foreach ($critical_features as $key => $feature) { + $feature_item = $aiowps_feature_mgr->get_feature_item_by_id($key); + + if (!$feature_item) continue; + + echo ''; + echo '
'; + echo '
' . esc_html($feature['name']) . '
'; + echo '
'; + if ($feature_item->is_active()) { + echo '
'; + } else { + echo '
'; + } + echo '
'; + echo '
'; + echo '
'; + } + echo "
"; + } + + /** + * This outputs the latest logins dashboard widget + * + * @return void + */ + public function widget_last_5_logins() { + global $wpdb; + $audit_log_table = AIOWPSEC_TBL_AUDIT_LOG; + $where_sql = (is_super_admin()) ? '' : ' and site_id = '.get_current_blog_id().' '; + + $last_days = 7; + $days_before_time = strtotime('-'.$last_days.' days', time()); + + // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- PCP warning. Direct query necessary. + $login_data_lastx_days = $wpdb->get_results( + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- pcp Warning. Ignore. + $wpdb->prepare("SELECT id,created FROM $audit_log_table WHERE event_type = %s $where_sql and created > %s", 'successful_login', $days_before_time), + ARRAY_A + ); // Get the last x days records + + if (!empty($login_data_lastx_days)) { + $chart_data = array(); + $chart_data['columns'] = array(__('Date', 'all-in-one-wp-security-and-firewall'), __('Logins', 'all-in-one-wp-security-and-firewall')); + $chart_data['data'] = $login_data_lastx_days; + $chart_data['last_days'] = $last_days; + $chart_data['id'] = 'logins_last_'.$last_days.'days'; + $this->dashboard_widget_chart($chart_data, 'bar'); + } + + // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- PCP Error. Ignore. + $data = $wpdb->get_results( + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- PCP error. Ignore. + $wpdb->prepare("SELECT * FROM $audit_log_table WHERE event_type = %s ORDER BY created DESC LIMIT %d", 'successful_login', 5), + ARRAY_A + ); //Get the last 5 records + + if (null == $data) { + echo '

' . esc_html__('No data found.', 'all-in-one-wp-security-and-firewall') . '

'; + } else { + $login_summary_table_data = array(); + //$login_summary_table_data['title'] = __('Last 5 login summary:', 'all-in-one-wp-security-and-firewall'); + $login_summary_table_data['columns'] = array(__('User', 'all-in-one-wp-security-and-firewall'), __('Date', 'all-in-one-wp-security-and-firewall'), 'IP'); + foreach ($data as $entry) { + $login_summary_table_data['data'][] = array($entry['username'], gmdate('Y-m-d H:i:s', $entry['created']), $entry['ip']); + } + $login_summary_table_data = apply_filters('aios_last5_logins_summary', $login_summary_table_data, $data); + $this->dashboard_widget($login_summary_table_data); + + // View all login logs + echo '

' . esc_html__('View all', 'all-in-one-wp-security-and-firewall') . '

'; + } + + echo '
'; + } + + public function widget_maintenance_mode_status() { + global $aio_wp_security; + ?> +

+ configs->get_value('aiowps_site_lockout')) { + echo esc_html__('Maintenance mode is currently enabled.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('Remember to disable it when you are done.', 'all-in-one-wp-security-and-firewall'); + } else { + echo esc_html__('Maintenance mode is currently disabled.', 'all-in-one-wp-security-and-firewall'); + } + ?> +

+ + + + + + +
: +
+ configs->get_value('aiowps_site_lockout')); ?> +
+
+ ' . esc_html__('Configure', 'all-in-one-wp-security-and-firewall') . ''; + } + + public function widget_brute_force() { + global $aio_wp_security; + if ($aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention') == '1') { + $brute_force_login_feature_link = '' . __('Cookie-based brute force', 'all-in-one-wp-security-and-firewall') . ''; + $brute_force_feature_secret_word = $aio_wp_security->configs->get_value('aiowps_brute_force_secret_word'); + echo '
'; + /* translators: %s: Brute Force Login URL */ + echo '

' . sprintf(esc_html__('The %s feature is currently active.', 'all-in-one-wp-security-and-firewall'), $brute_force_login_feature_link) . '

'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped above. + echo '

' . esc_html__('Your new WordPress login URL is now:', 'all-in-one-wp-security-and-firewall') . '

'; + echo '

' . esc_url(AIOWPSEC_WP_URL) . '/?' . esc_html($brute_force_feature_secret_word) . '=1

'; + echo '
'; //yellow box div + echo '
'; + }// End if statement for Cookie Based Brute Prevention box + + // Insert Rename Login Page feature box if this feature is active + if ($aio_wp_security->configs->get_value('aiowps_enable_rename_login_page') == '1') { + if (get_option('permalink_structure')) { + $home_url = trailingslashit(home_url()); + } else { + $home_url = trailingslashit(home_url()) . '?'; + } + + $rename_login_feature_link = '' . esc_html__('Rename login page', 'all-in-one-wp-security-and-firewall') . ''; + echo '
'; + /* translators: %s: Rename Login URL */ + echo '

' . sprintf(esc_html__('The %s feature is currently active.', 'all-in-one-wp-security-and-firewall'), $rename_login_feature_link) . '

'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped above. + echo '

' . esc_html__('Your new WordPress login URL is now:', 'all-in-one-wp-security-and-firewall') . '

'; + echo '

' . esc_url($home_url) . esc_html($aio_wp_security->configs->get_value('aiowps_login_page_slug')) . '

'; + echo '
'; //yellow box div + echo '
'; + } // End if statement for Rename Login box + } + + /** + * This outputs the logged in users dashboard widget + * + * @return void + */ + public function widget_logged_in_users() { + $users_online_link = ''.esc_html__('Logged in users', 'all-in-one-wp-security-and-firewall').''; + // default display messages + $multiple_users_info_msg = esc_html__('Number of users currently logged into your site (including you) is:', 'all-in-one-wp-security-and-firewall'); + $single_user_info_msg = esc_html__('There are no other users currently logged in.', 'all-in-one-wp-security-and-firewall'); + + if (is_multisite()) { + $current_blog_id = get_current_blog_id(); + $is_main = is_main_site($current_blog_id); + + if (empty($is_main)) { + // Subsite - only get logged in users for this blog_id + $logged_in_users = AIOWPSecurity_User_Login::get_logged_in_users(false); + } else { + // Main site - get sitewide users + $logged_in_users = AIOWPSecurity_User_Login::get_logged_in_users(); + + // If viewing AIOS from multisite main network dashboard, then display a different message + $multiple_users_info_msg = __('Number of users currently logged in site-wide (including you) is:', 'all-in-one-wp-security-and-firewall'); + $single_user_info_msg = __('There are no other site-wide users currently logged in.', 'all-in-one-wp-security-and-firewall'); + } + } else { + $logged_in_users = AIOWPSecurity_User_Login::get_logged_in_users(); + } + + if (empty($logged_in_users)) { + $num_users = 0; + } else { + $num_users = count($logged_in_users); + } + if ($num_users > 1) { + echo '

' . esc_html($multiple_users_info_msg) . ' ' . esc_html($num_users) . '

'; + /* translators: %s: Users Online URL */ + $info_msg = '

' . sprintf(esc_html__('Go to the %s menu to see more details', 'all-in-one-wp-security-and-firewall'), $users_online_link) . '

'; + echo $info_msg . '
'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped above. + } else { + echo '

' . esc_html($single_user_info_msg) . '

'; + } + } + + public function widget_locked_ip_addresses() { + $locked_ips_link = ''. esc_html__('Locked IP addresses', 'all-in-one-wp-security-and-firewall').''; + + $locked_ips = AIOWPSecurity_Utility::get_locked_ips(); + if (false === $locked_ips) { + echo '

' . esc_html__('There are no IP addresses currently locked out.', 'all-in-one-wp-security-and-firewall') . '

'; + } else { + $num_ips = count($locked_ips); + echo '

' . esc_html__('Number of temporarily locked out IP addresses:', 'all-in-one-wp-security-and-firewall') . ' ' . ' ' . esc_html($num_ips) . '

'; + /* translators: %s: Number of locked out IPs */ + $info_msg = '

' . sprintf(esc_html__('Go to the %s menu to see more details', 'all-in-one-wp-security-and-firewall'), $locked_ips_link) . '

'; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped above. + echo $info_msg . '
'; + } + } + + /** + * Determines whether a security feature should be activated based on its callback. + * + * This method checks if a feature should be added by evaluating its callback function. + * If no callback is set, the feature is added by default. If a callback is set, + * it must be callable and return a boolean value. + * + * @param array $feature An array containing feature details with the following keys: + * 'name' => (string) Name of the feature + * 'feature_callback' => (callable|null) Optional callback to determine if feature should be added + * + * @return bool True if the feature should be added, false otherwise + */ + public static function should_add_feature($feature) { + if (empty($feature['feature_callback'])) { + return true; + } elseif (is_callable($feature['feature_callback'])) { + return call_user_func($feature['feature_callback']); + } else { + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Part of internal error reporting system. + error_log("Callback function set but not callable (coding error). Feature: " . $feature['name']); + return false; + } + } + + /** + * This function creates summary for dashboard widget in table format + * + * @param array $widget_data title, column names and row data + * + * @return void + */ + private function dashboard_widget($widget_data) { + global $aio_wp_security; + $aio_wp_security->include_template('wp-admin/dashboard/widget-summary.php', false, array('widget_data' => $widget_data)); + } + + /** + * This function creates chart for dashboard widget + * + * @param array $chart_data column names, chart data, last_days and id + * @param string $type bar chart + * + * @return void + */ + private function dashboard_widget_chart($chart_data, $type = 'bar') { + global $aio_wp_security; + $aio_wp_security->include_template('wp-admin/dashboard/widget-'.$type.'-chart.php', false, array('chart_data' => $chart_data)); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-database-menu.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-database-menu.php new file mode 100755 index 00000000..43b07c89 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-database-menu.php @@ -0,0 +1,408 @@ +get_updraftplus_plugin_file_rel_to_plugins_dir(); + + // If UpdraftPlus is installed but not activated, then return activate link. + if ($updraftplus_plugin_file_rel_to_plugins_dir) { + $activate_url = add_query_arg(array( + '_wpnonce' => wp_create_nonce('activate-plugin_'.$updraftplus_plugin_file_rel_to_plugins_dir), + 'action' => 'activate', + 'plugin' => $updraftplus_plugin_file_rel_to_plugins_dir, + ), network_admin_url('plugins.php')); + + // If is network admin then add to link network activation. + if (is_network_admin()) { + $activate_url = add_query_arg(array('networkwide' => 1), $activate_url); + } + return sprintf('%s', + $activate_url, + __('UpdraftPlus is installed but currently not active.', 'all-in-one-wp-security-and-firewall') .' '. __('Follow this link to activate UpdraftPlus, to take a backup.', 'all-in-one-wp-security-and-firewall') + ); + } + + // If UpdraftPlus is not activated or installed, then return the installation link + return ''.__('Follow this link to install UpdraftPlus, to take a database backup.', 'all-in-one-wp-security-and-firewall').''; + } + + /** + * Get path to the UpdraftPlus plugin file relative to the plugins directory. + * + * @return String|false path to the UpdraftPlus plugin file relative to the plugins directory + */ + private function get_updraftplus_plugin_file_rel_to_plugins_dir() { + if (!function_exists('get_plugins')) { + include_once ABSPATH . '/wp-admin/includes/plugin.php'; + } + + $installed_plugins = get_plugins(); + $installed_plugins_keys = array_keys($installed_plugins); + foreach ($installed_plugins_keys as $plugin_file_rel_to_plugins_dir) { + $temp_plugin_file_name = substr($plugin_file_rel_to_plugins_dir, strpos($plugin_file_rel_to_plugins_dir, '/') + 1); + if ('updraftplus.php' == $temp_plugin_file_name) { + return $plugin_file_rel_to_plugins_dir; + } + } + return false; + } + + /** + * This function will setup the menus tabs by setting the array $menu_tabs + * + * @return void + */ + protected function setup_menu_tabs() { + $menu_tabs = array( + 'database-prefix' => array( + 'title' => __('Database prefix', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_database_prefix'), + 'display_condition_callback' => 'is_main_site', + ), + 'database-backup' => array( + 'title' => __('Database backup', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_database_backup'), + ), + ); + + $this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab')); + } + + /** + * Renders the submenu's database prefix tab + * + * @return Void + */ + protected function render_database_prefix() { + global $wpdb, $aio_wp_security, $aiowps_feature_mgr; + $old_db_prefix = $wpdb->prefix; + $new_db_prefix = ''; + $perform_db_change = false; + + if (isset($_POST['aiowps_db_prefix_change'])) { // Do form submission tasks + $nonce = $_REQUEST['_wpnonce']; + if (!wp_verify_nonce($nonce, 'aiowpsec-db-prefix-change-nonce')) { + $aio_wp_security->debug_logger->log_debug("Nonce check failed for DB prefix change operation.", 4); + die(__('Nonce check failed for DB prefix change operation.', 'all-in-one-wp-security-and-firewall')); + } + + // Let's first check if user's system allows writing to wp-config.php file. If plugin cannot write to wp-config we will not do the prefix change. + $config_file = AIOWPSecurity_Utility_File::get_wp_config_file_path(); + $file_write = AIOWPSecurity_Utility_File::is_file_writable($config_file); + if (!$file_write) { + $this->show_msg_error(__('The plugin has detected that it cannot write to the wp-config.php file.', 'all-in-one-wp-security-and-firewall') . ' ' . __('This feature can only be used if the plugin can successfully write to the wp-config.php file.', 'all-in-one-wp-security-and-firewall')); + } else { + if (isset($_POST['aiowps_enable_random_prefix'])) { // User has elected to generate a random DB prefix + $string = AIOWPSecurity_Utility::generate_alpha_random_string('5'); + $new_db_prefix = $string . '_'; + $perform_db_change = true; + } else { + if (empty($_POST['aiowps_new_manual_db_prefix'])) { + $this->show_msg_error(__('Please enter a value for the DB prefix.', 'all-in-one-wp-security-and-firewall')); + } else { + // User has chosen their own DB prefix value + $new_db_prefix = wp_strip_all_tags(trim($_POST['aiowps_new_manual_db_prefix'])); + if ($new_db_prefix !== $_POST['aiowps_new_manual_db_prefix']) { + wp_die("".__('Error:', 'all-in-one-wp-security-and-firewall')." ".__('prefix contains HTML tags', 'all-in-one-wp-security-and-firewall')); + } + if (preg_match('|[^a-z0-9_]|i', $new_db_prefix)) { + wp_die("".__('Error:', 'all-in-one-wp-security-and-firewall')." ".__('prefix contains invalid characters, the prefix should only contain alphanumeric and underscore characters.', 'all-in-one-wp-security-and-firewall')); + } + $error = $wpdb->set_prefix($new_db_prefix); // validate the user chosen prefix + if (is_wp_error($error)) { + wp_die("".__('Error:', 'all-in-one-wp-security-and-firewall')." (".$error->get_error_code()."): ".$error->get_error_message()); + } + $wpdb->set_prefix($old_db_prefix); + $perform_db_change = true; + } + } + } + } + + if ($perform_db_change) { + // Do the DB prefix change operations + $this->change_db_prefix($old_db_prefix, $new_db_prefix); + } + + $aio_wp_security->include_template('wp-admin/database-security/database-prefix.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr, 'old_db_prefix' => $old_db_prefix)); + } + + /** + * Renders the submenu's database backup tab + * + * @return Void + */ + protected function render_database_backup() { + global $aio_wp_security; + + $updraftplus_admin = !empty($GLOBALS['updraftplus_admin']) ? $GLOBALS['updraftplus_admin'] : null; + + if ($updraftplus_admin) { + $updraftplus_admin->add_backup_scaffolding(__('Take a database backup using UpdraftPlus', 'all-in-one-wp-security-and-firewall'), array($updraftplus_admin, 'backupnow_modal_contents')); + + } + $install_activate_link = $this->get_install_activate_link_of_updraft_plugin(); + + $aio_wp_security->include_template('wp-admin/database-security/database-backup.php', false, array('install_activate_link' => $install_activate_link)); + } + + /* + * Changes the DB prefix + */ + /** + * This function will change the DB prefix + * + * @param string $table_old_prefix - the old table prefix + * @param string $table_new_prefix - the new table prefix + * + * @return void + */ + private function change_db_prefix($table_old_prefix, $table_new_prefix) { + global $wpdb, $aio_wp_security; + $old_prefix_length = strlen($table_old_prefix); + $error = 0; + + // Config file path + $config_file = AIOWPSecurity_Utility_File::get_wp_config_file_path(); + + // Get the table resource + // $result = mysql_list_tables(DB_NAME); + $result = $this->get_mysql_tables(DB_NAME); //Fix for deprecated php mysql_list_tables function + + // Count the number of tables + if (is_array($result) && count($result) > 0) { + $num_rows = count($result); + } else { + echo '

'.__('Error - Could not get tables or no tables found!', 'all-in-one-wp-security-and-firewall').'

'; + return; + } + $table_count = 0; + $info_msg_string = '

'.__('Starting DB prefix change operations.....', 'all-in-one-wp-security-and-firewall').'

'; + + $info_msg_string .= '

'.sprintf(__('Your WordPress system has a total of %s tables and your new DB prefix will be: %s', 'all-in-one-wp-security-and-firewall'), ''.$num_rows.'', ''.$table_new_prefix.'').'

'; + echo $info_msg_string; + + // Do a back of the config file + if (!AIOWPSecurity_Utility_File::backup_and_rename_wp_config($config_file)) { + echo '

'.__('Failed to make a backup of the wp-config.php file.', 'all-in-one-wp-security-and-firewall') . ' ' .__('This operation will not go ahead.', 'all-in-one-wp-security-and-firewall').'

'; + return; + } else { + echo '

'.__('A backup copy of your wp-config.php file was created successfully!', 'all-in-one-wp-security-and-firewall').'

'; + } + + // Get multisite blog_ids if applicable + if (is_multisite()) { + $blog_ids = AIOWPSecurity_Utility::get_blog_ids(); + } + + // Rename all the table names + foreach ($result as $db_table) { + // Get table name with old prefix + $table_old_name = $db_table; + + if (strpos($table_old_name, $table_old_prefix) === 0) { + // Get table name with new prefix + $table_new_name = AIOWPSecurity_Utility::backquote($table_new_prefix . substr($table_old_name, $old_prefix_length)); + $table_old_name = AIOWPSecurity_Utility::backquote($table_old_name); + + // Write query to rename tables name + $sql = "RENAME TABLE ".$table_old_name." TO ".$table_new_name; + // $sql = "RENAME TABLE %s TO %s"; + + // Execute the query + if (false === $wpdb->query($sql)) { + $error = 1; + echo '

'.sprintf(__('%s table name update failed', 'all-in-one-wp-security-and-firewall'), ''.$table_old_name.'').'

'; + $aio_wp_security->debug_logger->log_debug("DB Security Feature - Unable to change prefix of table ".$table_old_name, 4); + } else { + $table_count++; + } + } else { + continue; + } + } + if (1 == $error) { + echo '

'.sprintf(__('Please change the prefix manually for the above tables to: %s', 'all-in-one-wp-security-and-firewall'), ''.$table_new_prefix.'').'

'; + } else { + echo '

'.sprintf(__('%s tables had their prefix updated successfully!', 'all-in-one-wp-security-and-firewall'), ''.$table_count.'').'

'; + } + + // Let's check for mysql tables of type "view" + $this->alter_table_views($table_old_prefix, $table_new_prefix); + + // Get wp-config.php file contents and modify it with new info + $config_contents = file($config_file); + $prefix_match_string = '$table_prefix='; //this is our search string for the wp-config.php file + foreach ($config_contents as $line_num => $line) { + $no_ws_line = preg_replace('/\s+/', '', $line); //Strip white spaces + if (false !== strpos($no_ws_line, $prefix_match_string)) { + $prefix_parts = explode("=", $line); + $prefix_parts[1] = str_replace($table_old_prefix, $table_new_prefix, $prefix_parts[1]); + $config_contents[$line_num] = implode("=", $prefix_parts); + break; + } + } + // Now let's modify the wp-config.php file + if (AIOWPSecurity_Utility_File::write_content_to_file($config_file, $config_contents)) { + echo '

'. __('wp-config.php file was updated successfully!', 'all-in-one-wp-security-and-firewall').'

'; + } else { + echo '

'.sprintf(__('The "wp-config.php" file was not able to be modified.', 'all-in-one-wp-security-and-firewall').' '.__('Please modify this file manually using your favourite editor and search for variable "$table_prefix" and assign the following value to that variable: %s', 'all-in-one-wp-security-and-firewall'), ''.$table_new_prefix.'').'

'; + $aio_wp_security->debug_logger->log_debug("DB Security Feature - Unable to modify wp-config.php", 4); + } + + // Now let's update the options table + $update_option_table_query = $wpdb->prepare("UPDATE " . $table_new_prefix . "options SET option_name = '".$table_new_prefix ."user_roles' WHERE option_name = %s LIMIT 1", $table_old_prefix."user_roles"); + + if (false === $wpdb->query($update_option_table_query)) { + echo '

'.sprintf(__('Update of table %s failed: unable to change %s to %s', 'all-in-one-wp-security-and-firewall'), $table_new_prefix.'options', $table_old_prefix.'user_roles', $table_new_prefix.'user_roles').'

'; + $aio_wp_security->debug_logger->log_debug("DB Security Feature - Error when updating the options table", 4);//Log the highly unlikely event of DB error + } else { + echo '

'. __('The options table records which had references to the old DB prefix were updated successfully!', 'all-in-one-wp-security-and-firewall') .'

'; + } + + // Now let's update the options tables for the multisite subsites if applicable + if (is_multisite()) { + if (!empty($blog_ids)) { + $main_site_id = get_main_site_id(); + foreach ($blog_ids as $blog_id) { + if ($blog_id == $main_site_id) continue; + $new_pref_and_site_id = $table_new_prefix.$blog_id.'_'; + $old_pref_and_site_id = $table_old_prefix.$blog_id.'_'; + $update_ms_option_table_query = $wpdb->prepare("UPDATE " . $new_pref_and_site_id . "options SET option_name = '".$new_pref_and_site_id."user_roles' WHERE option_name = %s LIMIT 1", $old_pref_and_site_id."user_roles"); + if (false === $wpdb->query($update_ms_option_table_query)) { + echo '

'.sprintf(__('Update of table %s failed: unable to change %s to %s', 'all-in-one-wp-security-and-firewall'), $new_pref_and_site_id.'options', $old_pref_and_site_id.'user_roles', $new_pref_and_site_id.'user_roles').'

'; + $aio_wp_security->debug_logger->log_debug("DB change prefix feature - Error when updating the subsite options table: ".$new_pref_and_site_id.'options', 4);//Log the highly unlikely event of DB error + } else { + echo '

'.sprintf(__('The %s table records which had references to the old DB prefix were updated successfully!', 'all-in-one-wp-security-and-firewall'), $new_pref_and_site_id.'options').'

'; + } + } + } + } + + //Now let's update the user meta table + $custom_sql = "SELECT user_id, meta_key FROM " . $table_new_prefix . "usermeta WHERE meta_key LIKE '" . $table_old_prefix . "%'"; + + $meta_keys = $wpdb->get_results($custom_sql); + + $error_update_usermeta = ''; + + // Update all meta_key field values which have the old table prefix in user_meta table + foreach ($meta_keys as $meta_key) { + // Create new meta key + $new_meta_key = $table_new_prefix . substr($meta_key->meta_key, $old_prefix_length); + + $update_user_meta_sql = $wpdb->prepare("UPDATE " . $table_new_prefix . "usermeta SET meta_key='" . $new_meta_key . "' WHERE meta_key=%s AND user_id=%s", $meta_key->meta_key, $meta_key->user_id); + + if (false === $wpdb->query($update_user_meta_sql)) { + $error_update_usermeta .= '

'.sprintf(__('Error updating user_meta table where new meta_key = %s, old meta_key = %s and user_id = %s.', 'all-in-one-wp-security-and-firewall'), $new_meta_key, $meta_key->meta_key, $meta_key->user_id).'

'; + echo $error_update_usermeta; + $aio_wp_security->debug_logger->log_debug("DB Security Feature - Error updating user_meta table where new meta_key = ".$new_meta_key." old meta_key = ".$meta_key->meta_key." and user_id = ".$meta_key->user_id, 4);//Log the highly unlikely event of DB error + } + } + echo '

'.__('The usermeta table records which had references to the old DB prefix were updated successfully!', 'all-in-one-wp-security-and-firewall').'

'; + // Display tasks finished message + $tasks_finished_msg_string = '

'. __('The database prefix change tasks have been completed.', 'all-in-one-wp-security-and-firewall').'

'; + echo $tasks_finished_msg_string; + } + + /** + * This is an alternative to the deprecated "mysql_list_tables + * + * @param string $database - database name + * + * @returns array - an array of table names + */ + public function get_mysql_tables($database = '') { + global $aio_wp_security; + $tables = array(); + $list_tables_sql = "SHOW TABLES FROM `{$database}`;"; + $mysqli = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); + + if ($mysqli->connect_errno) { + $aio_wp_security->debug_logger->log_debug("AIOWPSecurity_Database_Menu->get_mysql_tables() - DB connection error.", 4); + return false; + } + + $result = $mysqli->query($list_tables_sql, MYSQLI_USE_RESULT); + if ($result) { + //Alternative way to get the tables + while ($row = $result->fetch_assoc()) { + foreach ($row as $value) { + $tables[] = $value; + } + } + $result->close(); + } + $mysqli->close(); + return $tables; + } + + /** + * Will modify existing table view definitions to reflect the new DB prefix change + * + * @param string $old_db_prefix - old database prefix + * @param string $new_db_prefix - new database prefix + * + * @returns void + */ + private function alter_table_views($old_db_prefix, $new_db_prefix) { + global $wpdb, $aio_wp_security; + $db_name = $wpdb->dbname; + $info_msg_string = '

'.__('Checking for MySQL tables of type "view".....', 'all-in-one-wp-security-and-firewall').'

'; + echo $info_msg_string; + + // get tables which are views + $query = "SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA LIKE '".$db_name."'"; + $res = $wpdb->get_results($query); + if (empty($res)) return; + $view_count = 0; + foreach ($res as $item) { + $old_def = $item->VIEW_DEFINITION; + $new_def = AIOWPSecurity_Utility::str_replace_once($old_db_prefix, $new_db_prefix, $old_def); + $new_def = AIOWPSecurity_Utility::backquote($new_def); + + $view_name = AIOWPSecurity_Utility::backquote($item->TABLE_NAME); + $chg_view_sql = "ALTER VIEW $view_name AS $new_def"; + $view_res = $wpdb->query($chg_view_sql); + if (false === $view_res) { + echo '

'.sprintf(__('Update of the following MySQL view definition failed: %s', 'all-in-one-wp-security-and-firewall'), $old_def).'

'; + $aio_wp_security->debug_logger->log_debug("Update of the following MySQL view definition failed: ".$old_def, 4);//Log the highly unlikely event of DB error + } else { + $view_count++; + } + } + if ($view_count > 0) { + echo '

'.sprintf(__('%s view definitions were updated successfully.', 'all-in-one-wp-security-and-firewall'), ''.$view_count.'').'

'; + } + + return; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-filescan-menu.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-filescan-menu.php new file mode 100755 index 00000000..73dc811c --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-filescan-menu.php @@ -0,0 +1,75 @@ + array( + 'title' => __('File change detection', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_file_change_detect'), + ), + 'malware-scan' => array( + 'title' => __('Malware scan', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_malware_scan'), + ), + ); + + $this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab')); + } + + /** + * File change detection on your system files. + * + * @global $wpdb + * @global $aio_wp_security + * @global $aiowps_feature_mgr + */ + protected function render_file_change_detect() { + global $aio_wp_security; + + $aios_commands = new AIOWPSecurity_Commands(); + + $scanner_data = $aios_commands->get_scanner_data(); + + $aio_wp_security->include_template('wp-admin/scanner/file-change-detect.php', false, $scanner_data); + } + + /** + * Malware code scan on your system files. + * + * @return void + */ + protected function render_malware_scan() { + global $aio_wp_security; + + $aio_wp_security->include_template('wp-admin/scanner/malware-scan.php', false, array()); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-filesystem-menu.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-filesystem-menu.php new file mode 100755 index 00000000..bfc86518 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-filesystem-menu.php @@ -0,0 +1,144 @@ + array( + 'title' => __('File permissions', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_file_permissions'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ), + 'file-protection' => array( + 'title' => __('File protection', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_file_protection'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ), + 'host-system-logs' => array( + 'title' => __('Host system logs', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_host_system_logs'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ), + 'copy-protection' => array( + 'title' => __('Copy protection', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_copy_protection'), + ), + 'frames' => array( + 'title' => __('Frames', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_frames'), + ), + ); + + $this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab')); + } + + /** + * Renders the submenu's file permissions tab + * + * @return Void + */ + protected function render_file_permissions() { + // if this is the case there is no need to display a "fix permissions" button + global $aio_wp_security, $aiowps_feature_mgr; + + $files_dirs_to_check = AIOWPSecurity_Utility_File::get_files_and_dirs_to_check(); + + + $aio_wp_security->include_template('wp-admin/filesystem-security/file-permissions.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr, 'files_dirs_to_check' => $files_dirs_to_check, 'file_utility' => new AIOWPSecurity_Utility_File())); + } + + /** + * Renders the submenu's 'File protection' tab + * + * @return void + */ + protected function render_file_protection() { + global $aio_wp_security; + + $show_disallow_file_edit_warning = defined('DISALLOW_FILE_EDIT') && DISALLOW_FILE_EDIT && '1' != $aio_wp_security->configs->get_value('aiowps_disable_file_editing'); + + $aio_wp_security->include_template('wp-admin/filesystem-security/file-protection.php', false, array('show_disallow_file_edit_warning' => $show_disallow_file_edit_warning)); + } + + /** + * Renders the submenu's copy protection tab + * + * @return Void + */ + protected function render_copy_protection() { + global $aio_wp_security; + + $aio_wp_security->include_template('wp-admin/filesystem-security/copy-protection.php', false, array()); + } + + /** + * Renders the submenu's render frames tab + * + * @return Void + */ + protected function render_frames() { + global $aio_wp_security; + + $aio_wp_security->include_template('wp-admin/filesystem-security/frames.php', false, array()); + } + + /** + * Renders the submenu's host system logs tab + * + * @return Void + */ + protected function render_host_system_logs() { + global $aio_wp_security; + $sys_log_file = basename($aio_wp_security->configs->get_value('aiowps_system_log_file')); + $aio_wp_security->include_template('wp-admin/filesystem-security/host-system-logs.php', false, array('sys_log_file' => $sys_log_file)); + } + + /** + * Called via filter admin_footer, this adds the needed javascript to page + * + * @return void + */ + public function filesystem_menu_footer_code() { + ?> + + array( + 'title' => __('PHP rules', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_php_rules'), + ), + 'htaccess-rules' => array( + 'title' => __('.htaccess rules', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_htaccess_rules'), + 'display_condition_callback' => array('AIOWPSecurity_Utility', 'allow_to_write_to_htaccess'), + ), + '6g-firewall' => array( + 'title' => __('6G firewall rules', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_6g_firewall'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ), + '5g-firewall' => array( + 'title' => __('5G legacy rules', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_5g_firewall'), + 'display_condition_callback' => array('AIOWPSecurity_Utility', 'render_5g_legacy_tab'), + ), + 'internet-bots' => array( + 'title' => __('Internet bots', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_internet_bots'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ), + 'block-and-allow-lists' => array( + 'title' => __('Block & allow lists', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_block_and_allow_lists'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ), + 'advanced-settings' => array( + 'title' => __('Advanced settings', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_advanced_settings'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ) + ); + + $this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab')); + } + + /** + * Renders the PHP Firewall settings tab + * + * @return void + */ + protected function render_php_rules() { + global $aio_wp_security; + + $aios_commands = new AIOWPSecurity_Commands(); + + $php_firewall_data = $aios_commands->get_php_firewall_data(); + + $aio_wp_security->include_template('wp-admin/firewall/php-firewall-rules.php', false, compact('php_firewall_data')); + } + + /** + * Renders the Htaccess Firewall tab + * + * @return void + */ + protected function render_htaccess_rules() { + global $aio_wp_security; + + $aios_commands = new AIOWPSecurity_Commands(); + + $htaccess_rules_data = $aios_commands->get_htaccess_rules_data(); + + $aio_wp_security->include_template('wp-admin/firewall/htaccess-firewall-rules.php', false, compact('htaccess_rules_data')); + } + + /** + * Renders the 6G Blacklist Firewall Rules tab + * + * @return void + */ + protected function render_6g_firewall() { + global $aio_wp_security; + + $aio_wp_security->include_template('wp-admin/general/moved.php', false, array('key' => '6g')); + } + + /** + * Renders the 5G Blacklist Firewall Rules tab + * + * @return void + */ + protected function render_5g_firewall() { + global $aio_wp_security; + + $aio_wp_security->include_template('wp-admin/firewall/5g.php'); + } + + /** + * Renders the Internet Bots tab + * + * @return void + */ + protected function render_internet_bots() { + global $aio_wp_security; + + $aio_wp_security->include_template('wp-admin/general/moved.php', false, array('key' => 'internet-bots')); + } + + + /** + * Renders the Advanced settings tab. + * + * @return void + */ + protected function render_advanced_settings() { + global $aio_wp_security; + + $aios_commands = new AIOWPSecurity_Commands(); + + $advanced_settings_data = $aios_commands->get_firewall_advanced_settings_data(); + + $aio_wp_security->include_template('wp-admin/firewall/advanced-settings.php', false, compact('advanced_settings_data')); + } + + /** + * Renders ban user tab for blacklist IPs and user agents + * + * @global $aio_wp_security + * @global $aiowps_feature_mgr + * + * @return void + */ + protected function render_block_and_allow_lists() { + global $aio_wp_security; + + $aios_commands = new AIOWPSecurity_Commands(); + + $block_allowlist_data = $aios_commands->get_block_allow_lists_data(); + + $aio_wp_security->include_template('wp-admin/firewall/block-and-allow-lists.php', false, $block_allowlist_data); + } + + /** + * Validates posted user agent list and set, save as config. + * + * @global $aio_wp_security + * @global $aiowps_firewall_config + * + * @param string $banned_user_agents + * + * @return int + */ + private function validate_user_agent_list($banned_user_agents) { + global $aio_wp_security; + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + $submitted_agents = AIOWPSecurity_Utility::splitby_newline_trim_filter_empty($banned_user_agents); + $agents = array_unique(array_filter(array_map('sanitize_text_field', $submitted_agents), 'strlen')); + $aio_wp_security->configs->set_value('aiowps_banned_user_agents', implode("\n", $agents)); + $aiowps_firewall_config->set_value('aiowps_blacklist_user_agents', $agents); + $_POST['aiowps_banned_user_agents'] = ''; // Clear the post variable for the banned address list + return 1; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-firewall-setup-notice.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-firewall-setup-notice.php new file mode 100755 index 00000000..17326037 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-firewall-setup-notice.php @@ -0,0 +1,646 @@ +bootstrap = AIOWPSecurity_Utility_Firewall::get_bootstrap_file(); + $this->wpconfig = AIOWPSecurity_Utility_Firewall::get_wpconfig_file(); + $this->muplugin = AIOWPSecurity_Utility_Firewall::get_muplugin_file(); + AIOWPSecurity_Utility_Firewall::get_firewall_rules_path(true); // Creates the needed directories for the first time. + } + + /** + * Entry point for the dashboard notice + * + * @return void + */ + public function start_firewall_setup() { + + global $aio_wp_security; + + $firewall_files = array( + 'server' => AIOWPSecurity_Utility_Firewall::get_server_file(), + 'bootstrap' => $this->bootstrap, + 'wpconfig' => $this->wpconfig, + 'muplugin' => $this->muplugin, + ); + + //Check each file and update the contents if necessary + foreach ($firewall_files as $name => $file) { + ${'is_firewall_in_'.$name} = false; + + if (AIOWPSecurity_Utility_Firewall::MANUAL_SETUP === $file) { + continue; + } + + ${'is_firewall_in_'.$name} = $file->contains_contents(); + + if (true === ${'is_firewall_in_'.$name}) { + $file->update_contents(); + } + } + + if (!$aio_wp_security->is_aiowps_admin_page()) { + return; + } + + if (AIOWPSecurity_Utility_Firewall::is_firewall_setup()) { + if (true !== $is_firewall_in_server) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- variable is set in the foreach loop + $this->render_upgrade_protection_notice(); + } + } else { + $this->render_automatic_setup_notice(); + } + + $this->render_notices(); + } + + /** + * Will execute when the user presses 'Set up now' button + * + * @return void + */ + public function do_setup() { + + $is_inserted_firewall_file = false; + + $is_inserted_bootstrap_file = $this->bootstrap->contains_contents(); + if (true !== $is_inserted_bootstrap_file) { + $is_inserted_bootstrap_file = $this->bootstrap->insert_contents(); + + if (true !== $is_inserted_bootstrap_file) { + $this->log_wp_error($is_inserted_bootstrap_file); + $this->show_notice(self::NOTICE_BOOTSTRAP); + return; + } + + } + + $firewall_file = AIOWPSecurity_Utility_Firewall::get_server_file(); + + if ($firewall_file instanceof AIOWPSecurity_Block_Userini) { + + $directive = AIOWPSecurity_Utility_Firewall::get_already_set_directive($firewall_file); + + if (!empty($directive)) { + + if (AIOWPSecurity_Utility_Firewall::get_bootstrap_path() === $directive) { + $is_inserted_firewall_file = true; + } else { + $this->show_notice(self::NOTICE_DIRECTIVE_SET, array('directive' => $directive)); + } + + } else { + $is_inserted_firewall_file = $firewall_file->insert_contents(); + } + + } else { + + if (AIOWPSecurity_Utility_Firewall::MANUAL_SETUP !== $firewall_file) { + $is_inserted_firewall_file = $firewall_file->insert_contents(); // attempts to insert firewall into required file + } + } + + //Set up the firewall in the wp-config file + $is_inserted_wpconfig = $this->wpconfig->contains_contents(); + if (true !== $is_inserted_wpconfig) { + $is_inserted_wpconfig = $this->wpconfig->insert_contents(); + } + $this->log_wp_error($is_inserted_wpconfig); + + //Set up the firewall in the mu-plugin + $is_inserted_muplugin = $this->muplugin->contains_contents(); + if (true !== $is_inserted_muplugin) { + $is_inserted_muplugin = $this->muplugin->insert_contents(); + } + if (false === $is_inserted_muplugin) { + $this->log_wp_error(new \WP_Error( + 'file-mu-plugin-failed', + 'Unable to create the mu-plugin', + $this->muplugin + )); + } + $this->log_wp_error($is_inserted_muplugin); + + if (true === $is_inserted_firewall_file) { + $this->show_notice(self::NOTICE_INSTALLED); + } else { + $this->log_wp_error($is_inserted_firewall_file); + $this->show_notice(self::NOTICE_MANUAL); + } + + } + + /** + * Dismisses the notice. + * + * @return void + */ + private function do_dismiss() { + global $aio_wp_security; + + $aio_wp_security->configs->set_value('aios_firewall_dismiss', true, true); + } + + /** + * Checks whether the notice is dismissed + * + * @return boolean + */ + private function is_dismissed() { + global $aio_wp_security; + return (true === $aio_wp_security->configs->get_value('aios_firewall_dismiss')); + + } + + /** + * Handles the form submission for the 'Set up now' notice + * + * @return void + */ + public function handle_setup_form() { + $nonce = isset($_POST['_wpnonce']) ? $_POST['_wpnonce'] : ''; + $result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($nonce, 'aiowpsec-firewall-setup'); + if (!is_wp_error($result)) { + $this->do_setup(); + $this->do_redirect(); + } + } + + /** + * Handles the dismiss form + * + * @return void + */ + public function handle_dismiss_form() { + $nonce = isset($_POST['_wpnonce']) ? $_POST['_wpnonce'] : ''; + $result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($nonce, 'aiowpsec-firewall-setup-dismiss'); + if (!is_wp_error($result)) { + $this->do_dismiss(); + $this->do_redirect(); + } + } + + /** + * Handles the form that downgrades the firewall's protection. + * + * @return void + */ + public function handle_downgrade_protection_form() { + $nonce = isset($_POST['_wpnonce']) ? $_POST['_wpnonce'] : ''; + $result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($nonce, 'aiowpsec-firewall-downgrade'); + if (!is_wp_error($result)) { + AIOWPSecurity_Utility_Firewall::remove_firewall(); + $this->do_redirect(); + } + } + + /** + * Handles the redirect + * + * @return void + */ + private function do_redirect() { + + // Go back to the previous page and tab if set + if (isset($_POST['_wp_http_referer'])) { + + $matches = array(); + if (preg_match('/\?page='.AIOWPSEC_MENU_SLUG_PREFIX.'(?.*)(&tab=(?.*))?$/m', $_POST['_wp_http_referer'], $matches)) { + $url = 'admin.php?page='.AIOWPSEC_MENU_SLUG_PREFIX; + + if (isset($matches['page'])) { + $url .= sanitize_text_field($matches['page']); + + if (isset($matches['tab'])) { + $url .= '&tab='.sanitize_text_field($matches['tab']); + } + } + + AIOWPSecurity_Utility::redirect_to_url(admin_url(sanitize_url($url))); + } + + } + + AIOWPSecurity_Utility::redirect_to_url(admin_url('admin.php?page='.AIOWPSEC_MENU_SLUG_PREFIX)); + } + + /** + * Wrapper function to log WP_Errors to debug log + * + * @param WP_Error $wp_error - Our error which gets logged + * @return void + */ + private function log_wp_error($wp_error) { + + if (is_wp_error($wp_error)) { + global $aio_wp_security; + + $error_message = $wp_error->get_error_message(); + $error_message .= ' - '; + $error_message .= $wp_error->get_error_data(); + $aio_wp_security->debug_logger->log_debug($error_message, 4); + } + } + + /** + * Sets the flags to show notices + * + * @param string $type - the type of notice we want to set + * @param array $values - any values that need to be passed + * @return void + */ + private function show_notice($type, $values = array()) { + global $aio_wp_security; + + $aio_wp_security->configs->set_value('firewall_notice_'.$type, true); + + if (!empty($values)) { + $aio_wp_security->configs->set_value('firewall_notice_values', $values); + } + + $aio_wp_security->configs->save_config(); + } + + /** + * Renders any necessary notices + * + * @return void + */ + public function render_notices() { + global $aio_wp_security; + + $notices = array( + self::NOTICE_BOOTSTRAP, + self::NOTICE_MANUAL, + self::NOTICE_INSTALLED, + self::NOTICE_DIRECTIVE_SET, + ); + + foreach ($notices as $notice) { + if ($aio_wp_security->configs->get_value('firewall_notice_'.$notice)) { + + switch ($notice) { + case self::NOTICE_BOOTSTRAP: + $this->render_bootstrap_notice(); + break; + case self::NOTICE_MANUAL: + if (!$this->any_pending_notices(self::NOTICE_MANUAL)) { + $this->render_manual_setup_notice(); + } + break; + case self::NOTICE_INSTALLED: + $this->render_firewall_installed_notice(); + break; + case self::NOTICE_DIRECTIVE_SET: + $values = $aio_wp_security->configs->get_value('firewall_notice_values'); + $this->render_userini_directive_set_notice($values['directive']); + $aio_wp_security->configs->delete_value('firewall_notice_values'); + break; + } + + $aio_wp_security->configs->delete_value('firewall_notice_'.$notice); + } + } + + $aio_wp_security->configs->save_config(); + } + + /** + * Detects if we have any notices pending to display + * + * @param string ...$exclude - do not check the status of these notices + * + * @return boolean + */ + private function any_pending_notices(...$exclude) { + global $aio_wp_security; + + $notices = array( + self::NOTICE_BOOTSTRAP, + self::NOTICE_MANUAL, + self::NOTICE_INSTALLED, + self::NOTICE_DIRECTIVE_SET, + ); + $notices = array_diff($notices, $exclude); + + foreach ($notices as $notice) { + if (true === $aio_wp_security->configs->get_value('firewall_notice_'.$notice)) { + return true; + } + } + + return false; + } + + /** + * Notice is shown if we are unable to write to the bootstrap file + * + * @return void + */ + private function render_bootstrap_notice() { + ?> +
+

+ +

+

+

+

+

+ bootstrap, PATHINFO_BASENAME)); + ?> +

+
bootstrap); ?>
+

+
bootstrap->get_contents()); ?>
+

+ render_try_again_button(); + $this->render_manual_notice_footer(); + } + + /** + * Notice is shown if auto_prepend_file directive is already set in user.ini + * + * @param string $directive_value + * @return void + */ + private function render_userini_directive_set_notice($directive_value) { + + $firewall_file = AIOWPSecurity_Utility_Firewall::get_server_file(); + + $this->render_manual_notice_header(); + ?> +

+ +

+

+ + +

+ +

+ +

+ +

+
+ + +

+ +

+
get_contents()); ?>
+

+ +

+ render_try_again_button(); + $this->render_manual_notice_footer(); + } + + /** + * Shows when the firewall has successfully installed + * + * @return void + */ + private function render_firewall_installed_notice() { + global $aio_wp_security; + + $aio_wp_security->include_template('notices/firewall-installed-notice.php', false); + } + + /** + * Renders the 'manual setup' dashboard notice + * + * @return void + */ + private function render_manual_setup_notice() { + + $firewall_file = AIOWPSecurity_Utility_Firewall::get_server_file(); + + if (AIOWPSecurity_Utility_Firewall::MANUAL_SETUP === $firewall_file) { + //Show users how to manually add the firewall via php.ini if we can't detect their server + $bootstrap_path = AIOWPSecurity_Utility_Firewall::get_bootstrap_path(); + + $this->render_manual_notice_header(); + ?> +

+ +

+

+ +

+
+

+ +

+ render_manual_notice_footer(); + } else { + //Show users how to manually add the firewall via their own server file + $this->render_manual_notice_header(); + $firewall_file_name = pathinfo($firewall_file, PATHINFO_BASENAME); + ?> +

+ +

+

+

+ +

+
get_contents()); ?>
+

+ +

+ render_try_again_button(); + $this->render_manual_notice_footer(); + } + } + + /** + * The header for notices that require manual intervention + * + * @return void + */ + private function render_manual_notice_header() { + ?> +
+

+ +

+

+ +

+

+ +

+ +

+ +

+
+ +
+ + +
+ +
+
+ should_not_show_notice()) { + return; + } + ?> +
+
+ + +

+ + +

+ +
+

+
+ +
+ + is_dismissed() && !AIOWPSecurity_Utility_Firewall::is_firewall_page()) { + return true; + } + + if ($this->any_pending_notices()) { + return true; //only display if there are no other notices waiting to be displayed + } + + return false; + } + + /** + * Renders the 'Set up now' dashboard notice + * + * @return void + */ + private function render_automatic_setup_notice() { + global $aio_wp_security; + + if ($this->should_not_show_notice()) { + return; + } + $aio_wp_security->include_template('notices/firewall-setup-notice.php', false, array('show_dismiss' => !AIOWPSecurity_Utility_Firewall::is_firewall_page())); + } + + /** + * Ensures only one instance of the class can be created (singleton) + * + * @return AIOWPSecurity_Firewall_Setup_Notice|null + */ + public static function get_instance() { + + if (null === self::$instance) { + self::$instance = new self(); + } + + return self::$instance; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-404.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-404.php new file mode 100755 index 00000000..2780ad93 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-404.php @@ -0,0 +1,362 @@ + 'item', //singular name of the listed records + 'plural' => 'items', //plural name of the listed records + 'ajax' => false //does this table support ajax? + )); + } + + /** + * Returns created column in datetime format as per user setting time zone. + * + * @param array $item - data for the columns on the current row + * + * @return string - the datetime + */ + public function column_created($item) { + return AIOWPSecurity_Utility::convert_timestamp($item['created']); + } + + public function column_default($item, $column_name) { + return $item[$column_name]; + } + + /** + * Returns id column html to be rendered. + * + * @param array $item - data for the columns on the current row + * + * @return string - html string for column rendered + */ + public function column_id($item) { + $ip = $item['ip_or_host']; + + $is_locked = AIOWPSecurity_Utility::check_locked_ip($ip, '404'); + $blacklist_tab = 'blacklist'; + $is_blacklist = AIOWPSecurity_Utility::check_blacklist_ip($ip); + $actions = array(); + $actions['delete'] = '' . __('Delete', 'all-in-one-wp-security-and-firewall') . ''; + + if ($is_locked) { + // Build row actions for locked items + $actions['unblock'] = '' . __('Unblock', 'all-in-one-wp-security-and-firewall') . ''; + } elseif ($is_blacklist) { + $unblock_url_nonce = wp_nonce_url(sprintf('admin.php?page=%s&tab=%s', AIOWPSEC_FIREWALL_MENU_SLUG, $blacklist_tab), "404_log_item_action", "aiowps_nonce"); + $actions = array( + 'unblock' => ''.__('Unblock', 'all-in-one-wp-security-and-firewall').'', + ); + } else { + // Build row actions for other items + $actions['temp_block'] = '' . __('Temporarily block', 'all-in-one-wp-security-and-firewall') . ''; + $actions['blacklist_ip'] = '' . __('Blacklist IP', 'all-in-one-wp-security-and-firewall') . ''; + } + + //Return the user_login contents + return sprintf('%1$s %2$s', + /* $1%s */ $item['id'], + /* $2%s */ $this->row_actions($actions) + ); + } + + /** + * Returns status column html to be rendered. + * + * @param array $item - data for the columns on the current row + * + * @return string - html string for column rendered + */ + public function column_status($item) { + global $aio_wp_security; + $ip = $item['ip_or_host']; + //Check if this IP address is locked + $is_locked = AIOWPSecurity_Utility::check_locked_ip($ip, '404'); + $blacklisted_string = $aio_wp_security->configs->get_value('aiowps_banned_ip_addresses'); + $banned = strpos($blacklisted_string, $ip); + + if (false !== $banned) { + return 'blacklisted'; + } elseif ($is_locked) { + return 'temporarily blocked'; + } else { + return ''; + } + } + + /** + * Returns checkbox column html to be rendered. + * + * @param array $item - data for the columns on the current row + * + * @return string - html string for column rendered + */ + public function column_cb($item) { + return sprintf('', + /* $1%s */ $this->_args['singular'], //Let's simply repurpose the table's singular label + /* $2%s */ $item['id'] //The value of the checkbox should be the record's id + ); + } + + public function get_columns() { + $columns = array( + 'cb' => '', //Render a checkbox + 'id' => 'ID', + 'event_type' => __('Event type', 'all-in-one-wp-security-and-firewall'), + 'ip_or_host' => __('IP address', 'all-in-one-wp-security-and-firewall'), + 'url' => __('Attempted URL', 'all-in-one-wp-security-and-firewall'), + 'referer_info' => __('Referer', 'all-in-one-wp-security-and-firewall'), + 'created' => __('Date and time', 'all-in-one-wp-security-and-firewall'), + 'status' => __('Lock status', 'all-in-one-wp-security-and-firewall'), + ); + $columns = apply_filters('list_404_get_columns', $columns); + return $columns; + } + + public function get_sortable_columns() { + $sortable_columns = array( + 'id' => array('id', false), + 'event_type' => array('event_type', false), + 'ip_or_host' => array('ip_or_host', false), + 'url' => array('url', false), + 'referer_info' => array('referer_info', false), + 'created' => array('created', false), + ); + $sortable_columns = apply_filters('list_404_get_sortable_columns', $sortable_columns); + return $sortable_columns; + } + + /** + * Get bulk actions for the current WordPress screen. + * + * @return array An associative array of bulk actions where the keys are action names + * and the values are the corresponding action labels. + */ + public function get_bulk_actions() { + return array( + //'unlock' => 'Unlock', + 'bulk_block_ip' => __('Temporarily block IP', 'all-in-one-wp-security-and-firewall'), + 'bulk_blacklist_ip' => __('Blacklist IP', 'all-in-one-wp-security-and-firewall'), + 'delete' => __('Delete', 'all-in-one-wp-security-and-firewall') + ); + } + + /** + * Process bulk actions for the current WordPress screen. + * + * This method checks for the presence of a valid nonce and user capabilities, + * then performs the appropriate action based on the selected bulk action. + * + * @return void + */ + private function process_bulk_action() { + // phpcs:disable WordPress.Security.NonceVerification.Recommended -- PCP warning. This is the nonce. + if (empty($_REQUEST['_wpnonce']) || !isset($_REQUEST['_wp_http_referer'])) return; + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- PCP warning. Ignore. + $result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($_REQUEST['_wpnonce'], 'bulk-items'); + if (is_wp_error($result)) return; + + if ('bulk_block_ip' === $this->current_action()) {//Process delete bulk actions + if (!isset($_REQUEST['item'])) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall')); + } else { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- PCP warning, ignore. Sanitized later. + $this->block_ip(wp_unslash($_REQUEST['item'])); + } + } + + if ('bulk_blacklist_ip' === $this->current_action()) {//Process delete bulk actions + if (!isset($_REQUEST['item'])) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall')); + } else { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- PCP warning, ignore. Sanitized later. + $this->blacklist_ip_address(wp_unslash($_REQUEST['item'])); + } + } + if ('delete' === $this->current_action()) {//Process delete bulk actions + if (!isset($_REQUEST['item'])) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall')); + } else { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- PCP warning, ignore. Sanitized later. + $this->delete_404_event_records(wp_unslash($_REQUEST['item'])); + } + } + // phpcs:enable WordPress.Security.NonceVerification.Recommended -- PCP warning. This is the nonce. + } + + /** + * Locks an IP address by adding it to the AIOWPSEC_TBL_LOGIN_LOCKOUT table. + * + * @param array|string $entries - ids that correspond to ip addresses in the AIOWPSEC_TBL_EVENTS table or a single ip address + * @param string $username - (optional)username of user being locked + * + * @return boolean|void + */ + public function block_ip($entries, $username = '') { + global $wpdb; + if (is_array($entries)) { + //lock multiple records + $entries = array_filter($entries, 'is_numeric'); //discard non-numeric ID values + $id_list = "(" .implode(",", $entries) .")"; //Create comma separate list for DB operation + $events_table = AIOWPSEC_TBL_EVENTS; + // phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $results = $wpdb->get_col("SELECT ip_or_host FROM $events_table WHERE ID IN " . $id_list); + if (empty($results)) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Could not process the request because the IP addresses for the selected entries could not be found.', 'all-in-one-wp-security-and-firewall')); + return false; + } else { + foreach ($results as $entry) { + if (filter_var($entry, FILTER_VALIDATE_IP)) { + AIOWPSecurity_Utility::lock_IP($entry, '404', $username); + } + } + } + AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected IP addresses are now temporarily blocked.', 'all-in-one-wp-security-and-firewall')); + } + } + + /** + * Permanently blocks an IP address by adding it to the blacklist and writing rules to the htaccess file. + * + * @param array|string $entries - ids that correspond to ip addresses in the AIOWPSEC_TBL_EVENTS table or a single ip address + * + * @return boolean|void + */ + public function blacklist_ip_address($entries) { + global $wpdb, $aio_wp_security; + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + $bl_ip_addresses = $aio_wp_security->configs->get_value('aiowps_banned_ip_addresses'); //get the currently saved blacklisted IPs + $ip_list_array = AIOWPSecurity_Utility_IP::create_ip_list_array_from_string_with_newline($bl_ip_addresses); + + if (is_array($entries)) { + //Get the selected IP addresses + $entries = array_filter($entries, 'is_numeric'); //discard non-numeric ID values + $id_list = "(" .implode(",", $entries) .")"; //Create comma separate list for DB operation + $events_table = AIOWPSEC_TBL_EVENTS; + // phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $results = $wpdb->get_col("SELECT ip_or_host FROM $events_table WHERE ID IN " . $id_list); + if (empty($results)) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Could not process the request because the IP addresses for the selected entries could not be found.', 'all-in-one-wp-security-and-firewall')); + return false; + } else { + foreach ($results as $entry) { + $ip_list_array[] = $entry; + } + } + } + + $validated_ip_list_array = AIOWPSecurity_Utility_IP::validate_ip_list($ip_list_array, 'blacklist'); + if (is_wp_error($validated_ip_list_array)) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(nl2br($validated_ip_list_array->get_error_message())); + } else { + $banned_ip_data = implode("\n", $validated_ip_list_array); + $aio_wp_security->configs->set_value('aiowps_enable_blacklisting', '1'); // Force blacklist feature to be enabled. + $aio_wp_security->configs->set_value('aiowps_banned_ip_addresses', $banned_ip_data); + $aio_wp_security->configs->save_config(); + + $aiowps_firewall_config->set_value('aiowps_blacklist_ips', $validated_ip_list_array); + AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected IP addresses have been added to the blacklist and will be permanently blocked.', 'all-in-one-wp-security-and-firewall')); + } + } + + /** + * Deletes one or more records from the AIOWPSEC_TBL_EVENTS table. + * + * @param array|string|integer $entries - ids or a single id + * + * @return void|string + */ + public function delete_404_event_records($entries) { + global $wpdb, $aio_wp_security; + $events_table = AIOWPSEC_TBL_EVENTS; + if (is_array($entries)) { + //Delete multiple records + $entries = array_map('esc_sql', $entries); //escape every array element + $entries = array_filter($entries, 'is_numeric'); //discard non-numeric ID values + $id_list = "(" . implode(",", $entries) . ")"; //Create comma separate list for DB operation + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $result = $wpdb->query("DELETE FROM " . $events_table . " WHERE id IN " . $id_list); + if ($result) { + AIOWPSecurity_Admin_Menu::show_msg_record_deleted_st(); + } else { + // Error on bulk delete + $aio_wp_security->debug_logger->log_debug('Database error occurred when deleting rows from Events table. Database error: '.$wpdb->last_error, 4); + AIOWPSecurity_Admin_Menu::show_msg_record_not_deleted_st(); + } + } + } + + /** + * Retrieves all items from AIOWPSEC_TBL_EVENTS according to a search term inside $_REQUEST['s'] and only '404' events if there is no search term. It then assigns to $this->items. + * + * @param Boolean $ignore_pagination - whether to not paginate + * + * @return Void + */ + public function prepare_items($ignore_pagination = false) { + /** + * First, lets decide how many records per page to show + */ + $per_page = 100; + $columns = $this->get_columns(); + $hidden = array(); + $sortable = $this->get_sortable_columns(); + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. Nonce checked in previous function. + $search_term = isset($_REQUEST['s']) ? sanitize_text_field(wp_unslash($_REQUEST['s'])) : ''; + + $this->_column_headers = array($columns, $hidden, $sortable); + + $this->process_bulk_action(); + + global $wpdb; + $events_table_name = AIOWPSEC_TBL_EVENTS; + + // Ordering parameters + // Parameters that are going to be used to order the result + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce. + $orderby = isset($_GET['orderby']) ? sanitize_text_field(wp_unslash($_GET['orderby'])) : ''; + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce. + $order = isset($_GET['order']) ? sanitize_text_field(wp_unslash($_GET['order'])) : ''; + + $orderby = !empty($orderby) ? esc_sql($orderby) : 'id'; + $order = !empty($order) ? esc_sql($order) : 'DESC'; + + $orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable); + $order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1')); + + if (empty($search_term)) { + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $data = $wpdb->get_results("SELECT * FROM $events_table_name WHERE `event_type` = '404' ORDER BY $orderby $order", ARRAY_A); + } else { + // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.LikeWildcardsInQueryWithPlaceholder, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $data = $wpdb->get_results($wpdb->prepare("SELECT * FROM $events_table_name WHERE `ip_or_host` LIKE '%%%s%%' OR `url` LIKE '%%%s%%' OR `referer_info` LIKE '%%%s%%' ORDER BY $orderby $order", $wpdb->esc_like($search_term), $wpdb->esc_like($search_term), $wpdb->esc_like($search_term)), ARRAY_A); + } + + if (!$ignore_pagination) { + $current_page = $this->get_pagenum(); + $total_items = count($data); + $data = array_slice($data, (($current_page - 1) * $per_page), $per_page); + $this->set_pagination_args(array( + 'total_items' => $total_items, //WE have to calculate the total number of items + 'per_page' => $per_page, //WE have to determine how many items to show on a page + 'total_pages' => ceil($total_items / $per_page) //WE have to calculate the total number of pages + )); + } + + foreach ($data as $index => $row) { + // Insert an empty status column - we will use later + $data[$index]['status'] = ''; + } + + $this->items = $data; + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-audit.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-audit.php new file mode 100755 index 00000000..4c5c1702 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-audit.php @@ -0,0 +1,527 @@ + 'item', // singular name of the listed records + 'plural' => 'items', // plural name of the listed records + 'ajax' => true, // does this table support ajax? + 'data' => $data // Request data + )); + + } + + /** + * Returns the default column item + * + * @param object $item - item from which column data is returned + * @param string $column_name - column name to be fetched from item + * @return string + */ + public function column_default($item, $column_name) { + return $item[$column_name]; + } + + /** + * Returns cb column html to be rendered. + * + * @param array $item - data for the columns on the current row + * + * @return string - the html to be rendered + */ + public function column_cb($item) { + return sprintf( + '', + /* $1%s */ $this->_args['singular'], // Let's simply repurpose the table's singular label + /* $2%s */ $item['id'] // The value of the checkbox should be the record's id + ); + } + + /** + * Returns created column html to be rendered. + * + * @param array $item Data for the columns on the current row. + * + * @return string The html to be rendered. + */ + public function column_created($item) { + $actions = array( + 'delete' => '' . esc_html__('Delete', 'all-in-one-wp-security-and-firewall') . '' + ); + + return AIOWPSecurity_Utility::convert_timestamp($item['created']) . '' . $this->row_actions($actions); + } + + /** + * Returns ip column html to be rendered. + * + * @param array $item Data for the columns on the current row. + * + * @return string The html to be rendered. + */ + public function column_ip($item) { + $ip = $item['ip']; + + $unblacklist_ip_warning_translation = __('Are you sure you want to unblacklist this IP address?', 'all-in-one-wp-security-and-firewall'); + $unlock_ip_warning_translation = __('Are you sure you want to unlock this IP address?', 'all-in-one-wp-security-and-firewall'); + $lock_ip_warning_translation = __('Are you sure you want to temporarily lock this IP address?', 'all-in-one-wp-security-and-firewall'); + $blacklist_ip_warning_translation = __('Are you sure you want to blacklist this IP address?', 'all-in-one-wp-security-and-firewall'); + + // Build row actions. + if (AIOWPSecurity_Utility_Permissions::is_main_site_and_super_admin() && AIOWPSecurity_Utility::check_blacklist_ip($ip)) { + $actions = array( + 'unblacklist' => '' . esc_html__('Unblacklist', 'all-in-one-wp-security-and-firewall') . '', + ); + } elseif (AIOWPSecurity_Utility::check_locked_ip($ip, 'audit-log')) { + $actions = array( + 'unlock' => '' . esc_html__('Unlock', 'all-in-one-wp-security-and-firewall') . '', + ); + } else { + $actions = array( + 'lock_ip' => '' . esc_html__('Lock IP', 'all-in-one-wp-security-and-firewall') . '', + ); + + if (AIOWPSecurity_Utility_Permissions::is_main_site_and_super_admin()) { + $actions['blacklist_ip'] = '' . esc_html__('Blacklist IP', 'all-in-one-wp-security-and-firewall') . ''; + } + } + + return $ip . '' . $this->row_actions($actions); + } + + /** + * Returns event type column html to be rendered. + * + * @param array $item - data for the columns on the current row + * + * @return string - the html to be rendered + */ + public function column_event_type($item) { + if (empty($item['event_type'])) return __('No event type available.', 'all-in-one-wp-security-and-firewall'); + + $output = isset(AIOWPSecurity_Audit_Events::$event_types[$item['event_type']]) ? AIOWPSecurity_Audit_Events::$event_types[$item['event_type']] : $item['event_type']; + + return $output; + } + + /** + * Returns details column html to be rendered. + * + * @param array $item - data for the columns on the current row + * + * @return string - the html to be rendered + */ + public function column_details($item) { + $details = json_decode($item['details'], true); + + if (!is_array($details)) return $item['details']; + + $key = array_keys($details)[0]; + + if (method_exists("AIOWPSecurity_Audit_Text_Handler", "{$key}_to_text")) { + return call_user_func("AIOWPSecurity_Audit_Text_Handler::{$key}_to_text", $details[$key]); + } + + return $item['details']; + } + + /** + * Returns stack trace column html to be rendered. + * + * @param array $item - data for the columns on the current row + * + * @return string - the html to be rendered + */ + public function column_stacktrace($item) { + if (empty($item['stacktrace'])) return __('No stack trace available.', 'all-in-one-wp-security-and-firewall'); + + if (is_serialized($item['stacktrace'])) { + $stacktrace = AIOWPSecurity_Utility::unserialize($item['stacktrace']); + } else { + $stacktrace = $item['stacktrace']; + } + ob_start(); + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_dump -- Part of error reporting system. + var_dump($stacktrace); + $stacktrace_output = ob_get_contents(); + ob_end_clean(); + + $output = sprintf('%s', $item['id'], esc_html__('Stack trace', 'all-in-one-wp-security-and-firewall'), esc_html__('Show trace', 'all-in-one-wp-security-and-firewall')); + $output .= sprintf('', $item['id'], htmlspecialchars($stacktrace_output)); + + return $output; + } + + /** + * Sets the columns for the table + * + * @return array + */ + public function get_columns() { + $columns = array( + 'cb' => '', //Render a checkbox + 'created' => __('Date and time', 'all-in-one-wp-security-and-firewall'), + 'level' => __('Level', 'all-in-one-wp-security-and-firewall'), + 'network_id' => __('Network ID', 'all-in-one-wp-security-and-firewall'), + 'site_id' => __('Site ID', 'all-in-one-wp-security-and-firewall'), + 'username' => __('Username', 'all-in-one-wp-security-and-firewall'), + 'ip' => __('IP', 'all-in-one-wp-security-and-firewall'), + 'event_type' => __('Event', 'all-in-one-wp-security-and-firewall'), + 'details' => __('Details', 'all-in-one-wp-security-and-firewall'), + 'stacktrace' => __('Stack trace', 'all-in-one-wp-security-and-firewall') + ); + $columns = apply_filters('list_auditlogs_get_columns', $columns); + return $columns; + } + + /** + * Sets which of the columns the table data can be sorted by + * + * @return array + */ + public function get_sortable_columns() { + $sortable_columns = array( + 'created' => array('created', false), + 'network_id' => array('network_id', false), + 'site_id' => array('site_id', false), + 'level' => array('level', false), + 'username' => array('username', false), + 'ip' => array('ip', false), + 'event_type' => array('event_type', false), + 'details' => array('details', false), + 'stacktrace' => array('stacktrace', false) + ); + $sortable_columns = apply_filters('list_auditlogs_get_sortable_columns', $sortable_columns); + return $sortable_columns; + } + + /** + * This function will display a list of bulk actions for the list table + * + * @return array + */ + public function get_bulk_actions() { + $actions = array( + 'delete_all' => __('Delete all', 'all-in-one-wp-security-and-firewall'), + 'delete_selected' => __('Delete selected', 'all-in-one-wp-security-and-firewall'), + 'delete_filtered' => __('Delete filtered', 'all-in-one-wp-security-and-firewall') + ); + return $actions; + } + + /** + * This function will process the bulk action request, $search_term and $filters are only used if the user is trying to bulk delete the filtered items + * + * @param string $search_term - The search term used for filtering records. + * @param array $filters - An array containing filters applied to the records. + * @param string $action - The bulk action to be performed. + * @param array $items - An array of record IDs on which the action will be performed. Default is an empty array. + * + * @return void + */ + private function process_bulk_action($search_term, $filters, $action, $items = array()) { + global $wpdb; + + if ('delete_selected' === $action) { // Process delete bulk actions + if (!isset($items)) { + AIOS_Helper::set_message('aios_list_message', __('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall'), 'error'); + } else { + $this->delete_audit_event_records($items); + } + } elseif ('delete_filtered' === $action) { + if (!empty($filters) || '' !== $search_term) { + $audit_log_tbl = AIOWPSEC_TBL_AUDIT_LOG; + $where_sql = $this->get_audit_list_where_sql($search_term, $filters); + // phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $results = $wpdb->get_results("SELECT id FROM {$audit_log_tbl} {$where_sql}", 'ARRAY_A'); + $items = array_column($results, 'id'); + $this->delete_audit_event_records($items); + } else { + AIOS_Helper::set_message('aios_list_message', __('Please select the level or the event type filter or filter by a search term', 'all-in-one-wp-security-and-firewall'), 'error'); + } + } elseif ('delete_all' === $action) { + $this->delete_audit_event_records(null, true); + } + } + + /** + * Outputs extra controls to be displayed between bulk actions and pagination + * + * @param string $which - where we are outputting content (top or bottom) + * + * @return void + */ + protected function extra_tablenav($which) { + switch ($which) { + case 'top': + ?> +
+ + + +
+ query($delete_command); + } elseif (is_array($entries)) { + // Delete multiple records + $entries = array_map('esc_sql', $entries); // Escape every array element + $entries = array_filter($entries, 'is_numeric'); // Discard non-numeric ID values + $chunks = array_chunk($entries, 1000); + + $site_id_where_sql = (!is_super_admin()) ? ' AND site_id = ' . get_current_blog_id() : ''; + + // Processing each chunk + foreach ($chunks as $chunk) { + $id_list = "(" . implode(",", $chunk) . ")"; // Create comma separate list for DB operation + $delete_command = "DELETE FROM " . $audit_log_tbl . " WHERE id IN " . $id_list . $site_id_where_sql; + // phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $result = $wpdb->query($delete_command); + if (!$result) { + $aio_wp_security->debug_logger->log_debug('Database error occurred when deleting rows from Audit log table. Database error: '.$wpdb->last_error, 4); + AIOS_Helper::set_message('aios_list_message', __('The selected record(s) have failed to delete.', 'all-in-one-wp-security-and-firewall'), 'error'); + return; + } + } + } elseif (!empty($entries)) { + // Delete single record + $site_id_where_sql = (!is_super_admin()) ? ' AND site_id = ' . get_current_blog_id() : ''; + $delete_command = "DELETE FROM " . $audit_log_tbl . " WHERE id = '" . absint($entries) . "'" . $site_id_where_sql; + // phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $result = $wpdb->query($delete_command); + } + + if ($result || 0 < $result) { + $aios_list_message = __('The selected record(s) has been deleted successfully.', 'all-in-one-wp-security-and-firewall'); + AIOS_Helper::set_message('aios_list_message', $aios_list_message); + } else { + $aios_list_message = __('The selected record(s) have failed to delete.', 'all-in-one-wp-security-and-firewall'); + $aio_wp_security->debug_logger->log_debug('Database error occurred when deleting rows from Audit log table. Database error: '.$wpdb->last_error, 4); + AIOS_Helper::set_message('aios_list_message', $aios_list_message, 'error'); + } + + return $aios_list_message; + } + + /** + * This function will build and return the SQL WHERE statement + * + * @param string $search_term - the search term applied + * @param array $filters - the filters applied + * + * @return string - the SQL WHERE statement + */ + private function get_audit_list_where_sql($search_term, $filters) { + + $where_sql = ''; + + if ('' == $search_term) { + $where_sql = (!is_super_admin()) ? 'WHERE site_id = '.get_current_blog_id() : ''; + $extra_where = ''; + + if (!empty($filters)) { + $where_sql = empty($where_sql) ? 'WHERE ' : $where_sql . ' AND '; + foreach ($filters as $filter => $value) { + if (!empty($extra_where)) $extra_where .= ' AND '; + $extra_where .= "`{$filter}` = '".esc_sql($value)."'"; + } + } + + $where_sql .= $extra_where; + } else { + $where_sql = (!is_super_admin()) ? 'WHERE site_id = '.get_current_blog_id().' AND ' : 'WHERE '; + $extra_where = ''; + + if (!empty($filters)) { + foreach ($filters as $filter => $value) { + if (!empty($extra_where)) $extra_where .= ' AND '; + $extra_where .= "`{$filter}` = '".esc_sql($value)."'"; + } + $where_sql .= $extra_where . ' AND ('; + $extra_where = ''; + } + + // We don't use FILTER_VALIDATE_IP here as we want to be able to search for partial IP's + if (preg_match('/^[0-9a-f:\.]+$/i', $search_term)) { + $extra_where .= "`ip` LIKE '".esc_sql($search_term)."%'"; + } + + if (in_array($search_term, AIOWPSecurity_Audit_Events::$log_levels) && !isset($filters['level'])) { + if (!empty($extra_where)) $extra_where .= ' OR '; + $extra_where .= "`level` = '".esc_sql($search_term)."'"; + } + + if (!empty($extra_where)) $extra_where .= ' OR '; + if (isset($filters['event_type'])) { + $extra_where .= "`username` LIKE '".esc_sql($search_term)."%'"; + } else { + $extra_where .= "(`username` LIKE '".esc_sql($search_term)."%' or `event_type` LIKE '%".esc_sql($search_term)."%')"; + } + if (!empty($filters)) $extra_where .= ')'; + + $where_sql .= $extra_where; + } + + return $where_sql; + } + + /** + * Grabs the data from database and handles the pagination + * + * @param boolean $ignore_pagination - whether to not paginate + * + * @return void + */ + public function prepare_items($ignore_pagination = false) { + /** + * First, lets decide how many records per page to show + */ + $no_action = -1; + $per_page = defined('AIOWPSEC_AUDIT_LOG_PER_PAGE') ? absint(AIOWPSEC_AUDIT_LOG_PER_PAGE) : 100; + $per_page = empty($per_page) ? 100 : $per_page; + $current_page = $this->get_pagenum(); + $offset = (!$ignore_pagination && $per_page > 0) ? ($current_page - 1) * $per_page : 0; + $columns = $this->get_columns(); + $hidden = array('id'); // we really don't need the IDs of the log entries displayed + if (!is_multisite()) { + $hidden[] = 'network_id'; + $hidden[] = 'site_id'; + } + $sortable = $this->get_sortable_columns(); + $filters = array(); + if (isset($this->_args['data']['level-filter']) && $no_action != $this->_args['data']['level-filter']) $filters['level'] = sanitize_text_field($this->_args['data']['level-filter']); + if (isset($this->_args['data']['event-filter']) && $no_action != $this->_args['data']['event-filter']) $filters['event_type'] = sanitize_text_field($this->_args['data']['event-filter']); + $search_term = isset($this->_args['data']['s']) ? sanitize_text_field(stripslashes($this->_args['data']['s'])) : ''; + + $this->_column_headers = array($columns, $hidden, $sortable); + + $items = array(); + + if (isset($this->_args['data']['items'])) { + if (is_array($this->_args['data']['items'])) { + foreach ($this->_args['data']['items'] as $item) { + $sanitized_item = sanitize_text_field($item); + $items[] = $sanitized_item; + } + } else { + $sanitized_item = sanitize_text_field($this->_args['data']['items']); + $items[] = $sanitized_item; + } + } else { + $items = null; + } + + if (isset($this->_args['data']['action'])) $action = sanitize_text_field($this->_args['data']['action']); + else $action = $no_action; + + if (isset($action) && $no_action !== $action) { + $this->process_bulk_action($search_term, $filters, $action, $items); + } + + global $wpdb; + + $audit_log_tbl = AIOWPSEC_TBL_AUDIT_LOG; + + // Parameters that are going to be used to order the result + isset($this->_args['data']["orderby"]) ? $orderby = wp_strip_all_tags($this->_args['data']["orderby"]) : $orderby = ''; + isset($this->_args['data']["order"]) ? $order = wp_strip_all_tags($this->_args['data']["order"]) : $order = ''; + // By default show the most recent audit log entries. + $orderby = !empty($orderby) ? esc_sql($orderby) : 'created'; + $order = !empty($order) ? esc_sql($order) : 'DESC'; + + $orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable); + $order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1')); + + $orderby = sanitize_sql_orderby($orderby); + $order = sanitize_sql_orderby($order); + + $where_sql = $this->get_audit_list_where_sql($search_term, $filters); + + // phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $total_items = $wpdb->get_var("SELECT COUNT(*) FROM {$audit_log_tbl} {$where_sql}"); + if ($ignore_pagination) { + // phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $data = $wpdb->get_results("SELECT * FROM {$audit_log_tbl} {$where_sql} ORDER BY {$orderby} {$order}", 'ARRAY_A'); + } else { + // phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $data = $wpdb->get_results("SELECT * FROM {$audit_log_tbl} {$where_sql} ORDER BY {$orderby} {$order} LIMIT {$per_page} OFFSET {$offset}", 'ARRAY_A'); + } + + // Filter the 'details' section + foreach ($data as $key => $entry) { + $details = json_decode($entry['details'], true); + $details = is_null($details) ? $entry['details'] : $details; // check if the decode worked, if not pass the json string + $data[$key]['details'] = wp_json_encode(apply_filters('aios_audit_filter_details', $details, $entry['event_type'])); + } + + $this->items = $data; + + if ($ignore_pagination) return; + + $this->set_pagination_args(array( + 'total_items' => $total_items, // We have to calculate the total number of items + 'per_page' => $per_page, // We have to determine how many items to show on a page + 'total_pages' => ceil($total_items / $per_page) // We have to calculate the total number of pages + )); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-comment-spammer-ip.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-comment-spammer-ip.php new file mode 100755 index 00000000..1c48ccc9 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-comment-spammer-ip.php @@ -0,0 +1,221 @@ + 'item', // singular name of the listed records + 'plural' => 'items', // plural name of the listed records + 'ajax' => false // does this table support ajax? + )); + + } + + public function column_default($item, $column_name) { + return $item[$column_name]; + } + + public function column_comment_author_IP($item) { + //Build row actions + if (!is_main_site() || 'blocked' === $item['status']) { + //Suppress the block link if site is a multi site AND not the main site or the status is blocked + $actions = array(); //blank array + } else { + //Add IP to block URL + $ip = $item['comment_author_IP']; + $actions = array( + 'block' => ''.__('Block', 'all-in-one-wp-security-and-firewall').'', + ); + } + + //Return the user_login contents + return sprintf('%1$s %2$s', + /*$1%s*/ $item['comment_author_IP'], + /*$2%s*/ $this->row_actions($actions) + ); + } + + + public function column_cb($item) { + return sprintf( + '', + /*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label + /*$2%s*/ esc_attr($item['comment_author_IP']) //The value of the checkbox should be the record's id + ); + } + + public function get_columns() { + $columns = array( + 'cb' => '', //Render a checkbox + 'comment_author_IP' => __('Spammer IP', 'all-in-one-wp-security-and-firewall'), + 'amount' => __('Number of spam comments from this IP', 'all-in-one-wp-security-and-firewall'), + 'status' => __('Status', 'all-in-one-wp-security-and-firewall'), + ); + return $columns; + } + + public function get_sortable_columns() { + $sortable_columns = array( + 'comment_author_IP' => array('comment_author_IP',false), + 'amount' => array('amount',false), + 'status' => array('status',false), + ); + return $sortable_columns; + } + + public function get_bulk_actions() { + if (!is_main_site()) { + //Suppress the block link if site is a multi site AND not the main site + $actions = array(); //blank array + } else { + $actions = array( + 'block' => __('Block', 'all-in-one-wp-security-and-firewall') + ); + } + return $actions; + } + + /** + * This function handles bulk actions on the table + * + * @return void + */ + private function process_bulk_action() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This IS the nonce check. + if (empty($_REQUEST['_wpnonce']) || !isset($_REQUEST['_wp_http_referer'])) return; + // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput -- This IS the nonce check. + $result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($_REQUEST['_wpnonce'], 'bulk-items'); + if (is_wp_error($result)) return; + + + if ('block' === $this->current_action()) { + //Process block bulk actions + if (!isset($_REQUEST['item'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce already checked above. + $error_msg = '

'; + $error_msg .= esc_html__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall'); + $error_msg .= '

'; + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. Output already escaped. + echo $error_msg; + } else { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce already checked above. + $this->block_spammer_ip_records((filter_var(wp_unslash($_REQUEST['item']), FILTER_VALIDATE_IP))); + } + } + } + + + + /** + * This function will add the selected IP addresses to the blacklist. + * + * @param int|array $entries - either an array of IDs or a single ID of ip to be blocked + * + * @return void + */ + public function block_spammer_ip_records($entries) { + if (is_array($entries)) { + $entries = array_map('esc_sql', $entries); // Escape every array element + //Bulk selection using checkboxes were used + foreach ($entries as $ip_add) { + AIOWPSecurity_Blocking::add_ip_to_block_list($ip_add, 'spam'); + } + } + + AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected IP addresses are now permanently blocked.', 'all-in-one-wp-security-and-firewall')); + } + + /** + * This function prepare the items rendered on the table + * + * @return void + */ + public function prepare_items() { + //First, lets decide how many records per page to show + $per_page = 100; + $columns = $this->get_columns(); + $hidden = array(); + $sortable = $this->get_sortable_columns(); + + $this->_column_headers = array($columns, $hidden, $sortable); + + $this->process_bulk_action(); + + global $wpdb; + global $aio_wp_security; + $minimum_comments_per_ip = $aio_wp_security->configs->get_value('aiowps_spam_ip_min_comments'); + if (empty($minimum_comments_per_ip)) { + $minimum_comments_per_ip = 5; + } + // Ordering parameters + //Parameters that are going to be used to order the result + isset($_GET["orderby"]) ? $orderby = wp_strip_all_tags(wp_unslash($_GET["orderby"])) : $orderby = ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No nonce to check. + isset($_GET["order"]) ? $order = wp_strip_all_tags(wp_unslash($_GET["order"])) : $order = ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No nonce to check. + + $orderby = !empty($orderby) ? esc_sql($orderby) : 'amount'; + $order = !empty($order) ? esc_sql($order) : 'DESC'; + + $orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable); + $order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1')); + + // status is not a key in the database so we don't want to sort the database results, but sort the array later + if ('status' == $orderby) { + $sql = $wpdb->prepare("SELECT comment_author_IP, COUNT(*) AS amount + FROM $wpdb->comments + WHERE comment_approved = 'spam' + GROUP BY comment_author_IP + HAVING amount >= %d + ", $minimum_comments_per_ip); + } else { + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $orderby cannot be prepared. + $sql = $wpdb->prepare("SELECT comment_author_IP, COUNT(*) AS amount + FROM $wpdb->comments + WHERE comment_approved = 'spam' + GROUP BY comment_author_IP + HAVING amount >= %d + ORDER BY $orderby $order + ", $minimum_comments_per_ip); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $orderby cannot be prepared. + } + + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- Preparing done in conditional above. + $data = $wpdb->get_results($sql, ARRAY_A); + + // Get all permanently blocked IP addresses + $block_list = AIOWPSecurity_Blocking::get_list_blocked_ips(); + + foreach ($data as $key => $value) { + if (in_array($value['comment_author_IP'], $block_list)) { + $data[$key]['status'] = 'blocked'; + } else { + $data[$key]['status'] = 'not blocked'; + } + } + + if ('status' == $orderby) { + $keys = array_column($data, 'status'); + if ('asc' == $order) { + array_multisort($keys, SORT_ASC, SORT_STRING, $data); + } else { + array_multisort($keys, SORT_DESC, SORT_STRING, $data); + } + } + + $current_page = $this->get_pagenum(); + $total_items = count($data); + $data = array_slice($data, (($current_page - 1) * $per_page), $per_page); + $this->items = $data; + $this->set_pagination_args(array( + 'total_items' => $total_items, //WE have to calculate the total number of items + 'per_page' => $per_page, //WE have to determine how many items to show on a page + 'total_pages' => ceil($total_items / $per_page) //WE have to calculate the total number of pages + )); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-debug.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-debug.php new file mode 100755 index 00000000..4b3d221d --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-debug.php @@ -0,0 +1,149 @@ + 'entry', //singular name of the listed records + 'plural' => 'entries', //plural name of the listed records + 'ajax' => false //does this table support ajax? + )); + + } + + /** + * Returns logtime column in datetime format as per user setting time zone. + * + * @param array $item - data for the columns on the current row + * + * @return string - the datetime + */ + public function column_logtime($item) { + return AIOWPSecurity_Utility::convert_timestamp($item['logtime']); + } + + /** + * This function renders a default column item + * + * @param array $item - Item object + * @param string $column_name - Column name to be rendered from item object + * + * @return mixed - data to be rendered for column + */ + public function column_default($item, $column_name) { + return $item[$column_name]; + } + + /** + * Sets the columns for the table + * + * @return array + */ + public function get_columns() { + return array( + 'logtime' => __('Date and time', 'all-in-one-wp-security-and-firewall'), + 'level' => __('Level', 'all-in-one-wp-security-and-firewall'), + 'network_id' => __('Network ID', 'all-in-one-wp-security-and-firewall'), + 'site_id' => __('Site ID', 'all-in-one-wp-security-and-firewall'), + 'message' => __('Message', 'all-in-one-wp-security-and-firewall'), + 'type' => __('Type', 'all-in-one-wp-security-and-firewall') + ); + } + + /** + * Sets which of the columns the table data can be sorted by + * + * @return array + */ + public function get_sortable_columns() { + return array( + 'logtime' => array('logtime', false), + 'level' => array('level', false), + 'network_id' => array('network_id', false), + 'site_id' => array('site_id', false), + 'message'=>array('message', false), + 'type' => array('type', false) + ); + } + + /** + * Grabs the data from database and handles the pagination + * + * @param boolean $ignore_pagination - whether to not paginate + * + * @return void + */ + public function prepare_items($ignore_pagination = false) { + /** + * First, lets decide how many records per page to show + */ + if (defined('AIOWPSEC_DEBUG_LOG_PER_PAGE')) { + $per_page = absint(AIOWPSEC_DEBUG_LOG_PER_PAGE); + } + + $per_page = empty($per_page) ? 15 : $per_page; + $current_page = $this->get_pagenum(); + $offset = ($current_page - 1) * $per_page; + $columns = $this->get_columns(); + $hidden = array('id'); // we really don't need the IDs of the log entries displayed + if (!is_multisite()) { + $hidden[] = 'network_id'; + $hidden[] = 'site_id'; + } + $sortable = $this->get_sortable_columns(); + + $this->_column_headers = array($columns, $hidden, $sortable); + + global $wpdb; + + $debug_log_tbl = AIOWPSEC_TBL_DEBUG_LOG; + + /* -- Ordering parameters -- */ + + //Parameters that are going to be used to order the result + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce. + isset($_GET["orderby"]) ? $orderby = sanitize_text_field(wp_unslash($_GET["orderby"])) : $orderby = ''; + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce. + isset($_GET["order"]) ? $order = sanitize_text_field(wp_unslash($_GET["order"])) : $order = ''; + + // By default show the most recent debug log entries. + $orderby = !empty($orderby) ? esc_sql($orderby) : 'logtime'; + $order = !empty($order) ? esc_sql($order) : 'DESC'; + + $orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable); + $order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1')); + + $orderby = sanitize_sql_orderby($orderby); + $order = sanitize_sql_orderby($order); + + $where_sql = (!is_super_admin()) ? 'WHERE site_id = '.get_current_blog_id() : ''; + + if ($ignore_pagination) { + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $data = $wpdb->get_results("SELECT * FROM {$debug_log_tbl}$where_sql ORDER BY $orderby $order", 'ARRAY_A'); + } else { + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $data = $wpdb->get_results("SELECT * FROM {$debug_log_tbl} $where_sql ORDER BY $orderby $order LIMIT $per_page OFFSET $offset", 'ARRAY_A'); + } + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $total_items = $wpdb->get_var("SELECT COUNT(*) FROM {$debug_log_tbl} $where_sql"); + $this->items = $data; + + if ($ignore_pagination) return; + + $this->set_pagination_args(array( + 'total_items' => $total_items, //WE have to calculate the total number of items + 'per_page' => $per_page, //WE have to determine how many items to show on a page + 'total_pages' => ceil($total_items / $per_page) //WE have to calculate the total number of pages + )); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-locked-ip.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-locked-ip.php new file mode 100755 index 00000000..a0d92106 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-locked-ip.php @@ -0,0 +1,318 @@ + 'item', //singular name of the listed records + 'plural' => 'items', //plural name of the listed records + 'ajax' => false //does this table support ajax? + )); + + } + + /** + * Returns created column in datetime format as per user setting time zone. + * + * @param array $item - data for the columns on the current row + * + * @return string - the datetime + */ + public function column_created($item) { + return AIOWPSecurity_Utility::convert_timestamp($item['created']); + } + + /** + * Returns released column in datetime format as per user setting time zone. + * + * @param array $item - data for the columns on the current row + * + * @return string - the datetime + */ + public function column_released($item) { + return AIOWPSecurity_Utility::convert_timestamp($item['released']); + } + + /** + * This function renders a column + * + * @param array $item - Item object + * @param string $column_name - Column name to be rendered from item object + * + * @return string - data to be rendered for column_name + */ + public function column_default($item, $column_name) { + return $item[$column_name]; + } + + /** + * Function to populate the locked ip actions column in the table + * + * @param array $item - Contains the current item data + * + * @return string + */ + public function column_failed_login_ip($item) { + $actions = array( + 'unlock' => ''.esc_html__('Unlock', 'all-in-one-wp-security-and-firewall').'', + 'delete' => ''.esc_html__('Delete', 'all-in-one-wp-security-and-firewall').'', + ); + + //Return the user_login contents + return sprintf('%1$s %2$s', + /*$1%s*/ $item['failed_login_ip'], + /*$2%s*/ $this->row_actions($actions) + ); + } + + + /** + * This function renders the checkbox column + * + * @param array $item - item object + * + * @return string + */ + public function column_cb($item) { + return sprintf( + '', + /*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label + /*$2%s*/ $item['id'] //The value of the checkbox should be the record's id + ); + } + + /** + * Returns ip_lookup_result column html to be rendered. + * + * @param array $item - data for the columns on the current row + * + * @return string - the html to be rendered + */ + public function column_ip_lookup_result($item) { + if (empty($item['ip_lookup_result'])) return __('There is no IP lookup result available.', 'all-in-one-wp-security-and-firewall'); + + $ip_lookup_result = json_decode($item['ip_lookup_result'], true); + + // check that the json decode worked + if (null === $ip_lookup_result) return __('There is no IP lookup result available.', 'all-in-one-wp-security-and-firewall'); + + foreach ($ip_lookup_result as $key => $value) { + $ip_lookup_result[$key] = empty($value) ? __('Not Found', 'all-in-one-wp-security-and-firewall') : $value; + } + + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r -- PCP warning. Part of error reporting system. + $ip_lookup_result = print_r($ip_lookup_result, true); + + $output = sprintf('%s', esc_attr($item['id']), esc_html__('IP lookup result', 'all-in-one-wp-security-and-firewall'), esc_html__('Show result', 'all-in-one-wp-security-and-firewall')); + $output .= sprintf('', esc_attr($item['id']), esc_html($ip_lookup_result)); + + return $output; + } + + /** + * Sets the columns for the table + * + * @return array + */ + public function get_columns() { + return array( + 'cb' => '', //Render a checkbox + 'failed_login_ip' => __('Locked IP/range', 'all-in-one-wp-security-and-firewall'), + 'user_id' => __('User ID', 'all-in-one-wp-security-and-firewall'), + 'user_login' => __('Username', 'all-in-one-wp-security-and-firewall'), + 'lock_reason' => __('Reason', 'all-in-one-wp-security-and-firewall'), + 'created' => __('Date locked', 'all-in-one-wp-security-and-firewall'), + 'released' => __('Release date', 'all-in-one-wp-security-and-firewall'), + 'ip_lookup_result' => __('IP lookup result', 'all-in-one-wp-security-and-firewall') + ); + } + + /** + * This function returns sortable columns + * + * @return array[] + */ + public function get_sortable_columns() { + return array( + 'failed_login_ip' => array('failed_login_ip',false), + 'user_id' => array('user_id',false), + 'user_login' => array('user_login',false), + 'lock_reason' => array('lock_reason',false), + 'created' => array('created',false), + 'released' => array('released',false) + ); + } + + /** + * This returns the bulk actions for the table + * + * @return array + */ + public function get_bulk_actions() { + return array( + 'unlock' => __('Unlock', 'all-in-one-wp-security-and-firewall'), + 'delete' => __('Delete', 'all-in-one-wp-security-and-firewall'), + ); + } + + /** + * Process bulk actions. + * + * @return void + */ + private function process_bulk_action() { + // phpcs:disable WordPress.Security.NonceVerification.Recommended -- PCP warning. This is the nonce. + if (empty($_REQUEST['_wpnonce']) || !isset($_REQUEST['_wp_http_referer'])) return; + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- PCP warning. This is the nonce. + $result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($_REQUEST['_wpnonce'], 'bulk-items'); + if (is_wp_error($result)) return; + + if ('delete' == $this->current_action()) { // Process delete bulk actions + if (!isset($_REQUEST['item'])) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall')); + } else { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- PCP warning. Sanitized later. + $this->delete_lockout_records(wp_unslash($_REQUEST['item'])); + } + } + + if ('unlock' == $this->current_action()) { //Process unlock bulk actions + if (!isset($_REQUEST['item'])) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall')); + } else { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- PCP warning. Sanitized later. + $this->unlock_ips((wp_unslash($_REQUEST['item']))); + } + } + // phpcs:enable WordPress.Security.NonceVerification.Recommended -- PCP warning. This is the nonce. + } + + /** + * Unlocks multiple IP addresses by modifying the released column of records in the AIOWPSEC_TBL_LOGIN_LOCKOUT table. + * + * @param array $entries IDs that correspond to IP addresses in the AIOWPSEC_TBL_LOGIN_LOCKOUT table. + * + * @return void + */ + public function unlock_ips($entries) { + global $wpdb; + + $lockout_table = AIOWPSEC_TBL_LOGIN_LOCKOUT; + + // Unlock multiple records + $entries = array_filter($entries, 'is_numeric'); // Discard non-numeric ID values + $id_list = '(' .implode(',', $entries) .')'; // Create comma separate list for DB operation + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $result = $wpdb->query("UPDATE $lockout_table SET `released` = UNIX_TIMESTAMP() WHERE `id` IN $id_list"); + + if (null != $result) { + AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected IP entries were unlocked successfully.', 'all-in-one-wp-security-and-firewall')); + } + } + + /** + * Deletes one or more records from the AIOWPSEC_TBL_LOGIN_LOCKOUT table. + * + * @param array|string|integer $entries - ids or a single id + * + * @return void|string + */ + public function delete_lockout_records($entries) { + global $wpdb, $aio_wp_security; + $lockout_table = AIOWPSEC_TBL_LOGIN_LOCKOUT; + if (is_array($entries)) { + // Delete multiple records + $entries = array_filter($entries, 'is_numeric'); //discard non-numeric ID values + $id_list = "(" .implode(",", $entries) .")"; //Create comma separate list for DB operation + $delete_command = "DELETE FROM ".$lockout_table." WHERE id IN ".$id_list; + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $result = $wpdb->query($delete_command); + if ($result) { + AIOWPSecurity_Admin_Menu::show_msg_record_deleted_st(); + } else { + // Error on bulk delete + $aio_wp_security->debug_logger->log_debug('Database error occurred when deleting rows from login lockout table. Database error: '.$wpdb->last_error, 4); + AIOWPSecurity_Admin_Menu::show_msg_record_not_deleted_st(); + } + } elseif (null != $entries) { + // Delete single record + $delete_command = "DELETE FROM ".$lockout_table." WHERE id = '".absint($entries)."'"; + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $result = $wpdb->query($delete_command); + if ($result) { + return AIOWPSecurity_Admin_Menu::show_msg_record_deleted_st(true); + } elseif (false === $result) { + // Error on single delete + $aio_wp_security->debug_logger->log_debug('Database error occurred when deleting rows from login lockout table. Database error: '.$wpdb->last_error, 4); + return AIOWPSecurity_Admin_Menu::show_msg_record_not_deleted_st(true); + } + } + } + + /** + * Retrieves all items from AIOWPSEC_TBL_LOGIN_LOCKOUT. It may paginate and then assigns to $this->items. + * + * @param Boolean $ignore_pagination - whether to not paginate + * + * @return Void + */ + public function prepare_items($ignore_pagination = false) { + global $wpdb; + + $lockout_table = AIOWPSEC_TBL_LOGIN_LOCKOUT; + + $this->process_bulk_action(); + + // How many records per page to show + $per_page = 100; + $columns = $this->get_columns(); + $hidden = array(); + $sortable = $this->get_sortable_columns(); + + $this->_column_headers = array($columns, $hidden, $sortable); + + // Parameters that are going to be used to order the result + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce. + $orderby = isset($_GET['orderby']) ? sanitize_text_field(wp_unslash($_GET['orderby'])) : ''; + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce. + $order = isset($_GET['order']) ? sanitize_text_field(wp_unslash($_GET['order'])) : ''; + + $orderby = !empty($orderby) ? esc_sql($orderby) : 'created'; + $order = !empty($order) ? esc_sql($order) : 'DESC'; + + $orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable); + $order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1')); + + $current_page = $this->get_pagenum(); + $offset = ($current_page - 1) * $per_page; + + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $total_items = $wpdb->get_var("SELECT COUNT(*) FROM {$lockout_table} WHERE `released` > UNIX_TIMESTAMP()"); + + if ($ignore_pagination) { + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $data = $wpdb->get_results("SELECT * FROM {$lockout_table} WHERE `released` > UNIX_TIMESTAMP() ORDER BY {$orderby} {$order}", 'ARRAY_A'); + } else { + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $data = $wpdb->get_results("SELECT * FROM {$lockout_table} WHERE `released` > UNIX_TIMESTAMP() ORDER BY {$orderby} {$order} LIMIT {$per_page} OFFSET {$offset}", 'ARRAY_A'); + } + + $this->items = $data; + + if ($ignore_pagination) return; + + $this->set_pagination_args(array( + 'total_items' => $total_items, // WE have to calculate the total number of items + 'per_page' => $per_page, // WE have to determine how many items to show on a page + 'total_pages' => ceil($total_items / $per_page) // WE have to calculate the total number of pages + )); + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-logged-in-users.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-logged-in-users.php new file mode 100755 index 00000000..284608e2 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-logged-in-users.php @@ -0,0 +1,260 @@ + 'item', //singular name of the listed records + 'plural' => 'items', //plural name of the listed records + 'ajax' => false //does this table support ajax? + )); + + } + + public function column_default($item, $column_name) { + return $item[$column_name]; + } + + /** + * Returns user id column html to be rendered. + * + * @param array $item - data for the columns on the current row + * + * @return string - the html to be rendered + */ + public function column_user_id($item) { + //Build row actions + $actions = array( + 'logout' => ''.__('Force logout', 'all-in-one-wp-security-and-firewall').'', + ); + + //Return the user_login contents + return sprintf('%1$s %2$s', + /*$1%s*/ $item['user_id'], + /*$2%s*/ $this->row_actions($actions) + ); + } + + /** + * Sets the columns for the table + * + * @return array + */ + public function get_columns() { + $columns = array( + 'cb' => '', + 'user_id' => __('User ID', 'all-in-one-wp-security-and-firewall'), + 'username' => __('Login name', 'all-in-one-wp-security-and-firewall'), + 'ip_address' => __('IP address', 'all-in-one-wp-security-and-firewall'), + 'site_id' => __('Site ID', 'all-in-one-wp-security-and-firewall'), + ); + return $columns; + } + + /** + * Returns cb column html to be rendered. + * + * @param array $item - data for the columns on the current row + * + * @return string - the html to be rendered + */ + public function column_cb($item) { + return sprintf( + '', + /* $1%s */ $this->_args['singular'], // Let's simply repurpose the table's singular label + /* $2%s */ $item['user_id'] // The value of the checkbox should be the record's id and its ip address + ); + } + + /** + * Sets which of the columns the table data can be sorted by + * + * @return array + */ + public function get_sortable_columns() { + return array( + 'user_id' => array('user_id',false), + 'username' => array('username',false), + 'ip_address' => array('ip_address',false), + 'site_id' => array('site_id',false), + ); + } + + /** + * Adds a bulk action user interface + * + * @return array + */ + public function get_bulk_actions() { + return array( + 'force_logout_all' => __('Logout all', 'all-in-one-wp-security-and-firewall'), + 'force_logout_selected' => __('Logout selected', 'all-in-one-wp-security-and-firewall'), + ); + } + + /** + * Process Bulk action from menu + * + * @return void + */ + private function process_bulk_action() { + // phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput -- PCP warning. Nonce used. + if (empty($_REQUEST['_wpnonce']) || !isset($_REQUEST['_wp_http_referer'])) return; + $result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($_REQUEST['_wpnonce'], 'bulk-items'); + if (is_wp_error($result)) return; + + if ('force_logout_all' === $this->current_action()) { + $this->force_user_logout(array(), true); + } elseif ('force_logout_selected' === $this->current_action()) { + if (isset($_REQUEST['item'])) { + + if (is_array($_REQUEST['item'])) $this->force_user_logout(wp_unslash($_REQUEST['item'])); + } + } + // phpcs:enable WordPress.Security.NonceVerification.Recommended -- PCP warning. Nonce used. + } + + /** + * This function will force selected user(s) to be logged out. + * + * @param int|array $users - id of selected user or array of user ids to be logged out + * @param bool $logout_all - Boolean to show if all users should be logged out + * + * @return void|string + */ + public function force_user_logout($users, $logout_all = false) { + global $wpdb, $aio_wp_security; + + $logged_in_users_table = AIOWPSEC_TBL_LOGGED_IN_USERS; + + if ($logout_all) { + // get all user_id(except for the admin) in the table and make it an array for users + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $users = $wpdb->get_col("SELECT user_id FROM $logged_in_users_table"); + } + + if (is_array($users)) { + + if (empty($users)) { + AIOWPSecurity_Admin_Menu::show_msg_record_not_deleted_st(); + return; + } + + $errors = 0; + + // Escape the user IDs for security + $users = array_map('esc_sql', $users); + + foreach ($users as $user_id) { + if (is_numeric($user_id) && !is_super_admin($user_id) && AIOWPSecurity_Utility::is_user_member_of_blog($user_id)) { + if ($aio_wp_security->user_login_obj->delete_logged_in_user($user_id)) { + $this->logout_user($user_id); + continue; + } + } + $errors++; + } + + if ($errors > 0) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__("Some users were not logged out due to the ID being invalid, or them being a super admin or a member of a different subsite on a multisite", 'all-in-one-wp-security-and-firewall')); + return; + } + + AIOWPSecurity_Admin_Menu::show_msg_record_deleted_st(); + } + } + + + /** + * This function handles logging out a user using user_id + * + * @param int $user_id - id of user being logged out + * + * @return void + */ + public function logout_user($user_id) { + $user_id = absint($user_id); + $manager = WP_Session_Tokens::get_instance($user_id); + $manager->destroy_all(); + } + + /** + * Prepares the items for the logged in users table + * + * @param bool $ignore_pagination - this is to check if data should be paginated or not + * + * @return void + */ + public function prepare_items($ignore_pagination = false) { + global $wpdb; + + //First, lets decide how many records per page to show + $per_page = 100; + $columns = $this->get_columns(); + $hidden = array(); + $sortable = $this->get_sortable_columns(); + $logged_in_users_table = AIOWPSEC_TBL_LOGGED_IN_USERS; + $current_page = $this->get_pagenum(); + $offset = ($current_page - 1) * $per_page; + + // Parameters that are going to be used to order the result + // phpcs:disable -- Rule won't be silenced any other way. No nonce. + $orderby = isset($_GET["orderby"]) ? sanitize_text_field(wp_unslash($_GET["orderby"])) : ''; + $order = isset($_GET["order"]) ? sanitize_text_field(wp_unslash($_GET["order"])) : ''; + // phpcs:enable -- Rule won't be silenced any other way. No nonce. + + // By default show the most recent logged in user entries. + $orderby = empty($orderby) ? 'created' : esc_sql($orderby); + $order = empty($order) ? 'DESC' : esc_sql($order); + + $orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable); + $order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1')); + + $orderby = sanitize_sql_orderby($orderby); + $order = sanitize_sql_orderby($order); + + $this->_column_headers = array($columns, $hidden, $sortable); + + $this->process_bulk_action(); // Process bulk actions + + $where_sql = $this->get_where_sql(); + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $total_items = $wpdb->get_var("SELECT COUNT(*) FROM `{$logged_in_users_table}` $where_sql"); + + if ($ignore_pagination) { + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $data = $wpdb->get_results("SELECT * FROM `{$logged_in_users_table}` $where_sql ORDER BY $orderby $order", 'ARRAY_A'); + } else { + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $data = $wpdb->get_results("SELECT * FROM `{$logged_in_users_table}` $where_sql ORDER BY $orderby $order LIMIT $per_page OFFSET $offset", 'ARRAY_A'); + } + + $this->items = $data; + + if ($ignore_pagination) return; + + $this->set_pagination_args(array( + 'total_items' => $total_items, //WE have to calculate the total number of items + 'per_page' => $per_page, //WE have to determine how many items to show on a page + 'total_pages' => ceil($total_items/$per_page) //WE have to calculate the total number of pages + )); + } + + /** + * This function will build and return the SQL WHERE statement + * + * @return string - the SQL WHERE statement + */ + private function get_where_sql() { + if (is_main_site() && is_super_admin()) return ''; + + return is_multisite() ? sprintf("WHERE site_id = %d", get_current_blog_id()) : ''; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-permanent-blocked-ip.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-permanent-blocked-ip.php new file mode 100755 index 00000000..2e5c4753 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-permanent-blocked-ip.php @@ -0,0 +1,238 @@ + 'item', //singular name of the listed records + 'plural' => 'items', //plural name of the listed records + 'ajax' => false //does this table support ajax? + )); + + } + + /** + * Returns created column in datetime format as per user setting time zone. + * + * @param array $item - data for the columns on the current row + * + * @return string - the datetime + */ + public function column_created($item) { + return AIOWPSecurity_Utility::convert_timestamp($item['created']); + } + + public function column_default($item, $column_name) { + return $item[$column_name]; + } + + /** + * Function to populate the permanent blocked ip actions column in the table + * + * @param array $item - Contains the current item data + * + * @return string + */ + public function column_id($item) { + $actions = array( + 'unblock' => 'Unblock', + ); + + //Return the user_login contents + return sprintf('%1$s %2$s', + /*$1%s*/ + $item['id'], + /*$2%s*/ + $this->row_actions($actions) + ); + } + + + public function column_cb($item) { + return sprintf( + '', + /*$1%s*/ + $this->_args['singular'], //Let's simply repurpose the table's singular label + /*$2%s*/ + $item['id'] //The value of the checkbox should be the record's id + ); + } + + public function get_columns() { + return array( + 'cb' => '', //Render a checkbox + 'id' => 'ID', + 'blocked_ip' => __('Blocked IP', 'all-in-one-wp-security-and-firewall'), + 'block_reason' => __('Reason', 'all-in-one-wp-security-and-firewall'), + 'created' => __('Date and Time', 'all-in-one-wp-security-and-firewall') + ); + } + + public function get_sortable_columns() { + return array( + 'id' => array('id', false), + 'blocked_ip' => array('blocked_ip', false), + 'block_reason' => array('block_reason', false), + 'created' => array('created', false) + ); + } + + public function get_bulk_actions() { + return array( + 'unblock' => __('Unblock', 'all-in-one-wp-security-and-firewall') + ); + } + + private function process_bulk_action() { + // phpcs:disable WordPress.Security.NonceVerification.Recommended -- PCP warning. It IS the nonce. Ignore. + if (empty($_REQUEST['_wpnonce']) || !isset($_REQUEST['_wp_http_referer'])) return; + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- PCP warning. Ignore. + $result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($_REQUEST['_wpnonce'], 'bulk-items'); + if (is_wp_error($result)) return; + + if ('unblock' === $this->current_action()) { // Process unlock bulk actions + if (!isset($_REQUEST['item'])) { + AIOS_Helper::set_message('aios_list_message', __('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall'), 'error'); + } else { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitized later + $this->unblock_ip_address(wp_unslash($_REQUEST['item'])); + } + } + // phpcs:enable WordPress.Security.NonceVerification.Recommended -- PCP warning. It IS the nonce. Ignore. + } + + /** + * Deletes one or more records from the AIOWPSEC_TBL_PERM_BLOCK table. + * + * @param array|string|integer $entries - ids or a single id + * + * @return void|string + */ + public function unblock_ip_address($entries) { + global $wpdb, $aio_wp_security; + if (is_array($entries)) { + // multiple records + + $entries = array_filter($entries, 'is_numeric'); //discard non-numeric ID values + $id_list = "(" . implode(",", $entries) . ")"; //Create comma separate list for DB operation + $delete_command = "DELETE FROM " . AIOWPSEC_TBL_PERM_BLOCK . " WHERE id IN " . $id_list; // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- $id_list cannot be prepared. + $result = $wpdb->query($delete_command); + if ($result) { + AIOS_Helper::set_message('aios_list_message', __('Successfully unblocked and deleted the selected record(s).', 'all-in-one-wp-security-and-firewall')); + } else { + // Error on bulk delete + $aio_wp_security->debug_logger->log_debug('Database error occurred when deleting rows from Perm Block table. Database error: '.$wpdb->last_error, 4); + AIOS_Helper::set_message('aios_list_message', __('Failed to unblock and delete the selected record(s).', 'all-in-one-wp-security-and-firewall'), 'error'); + } + } elseif (!empty($entries)) { + //Delete single record + $delete_command = "DELETE FROM " . AIOWPSEC_TBL_PERM_BLOCK . " WHERE id = %d"; + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $result = $wpdb->query($wpdb->prepare($delete_command, absint($entries))); + if (false === $result) { + // Error on single delete + $aio_wp_security->debug_logger->log_debug('Database error occurred when deleting rows from Perm Block table. Database error: '.$wpdb->last_error, 4); + } + + return $result; + } + } + + /** + * This function will build and return the SQL WHERE statement + * + * @param string $search_term - the search term applied + * + * @return string - the SQL WHERE statement + */ + private function get_permanent_blocked_ip_list_where_sql($search_term) { + $where = ''; + if (!empty($search_term)) { + $where = " WHERE"; + + // We don't use FILTER_VALIDATE_IP here as we want to be able to search for partial IP's + if (preg_match('/^[0-9a-f:\.]+$/i', $search_term)) { + $where .= " `blocked_ip` LIKE '%".esc_sql($search_term)."%' OR"; + } + + $where .= " `block_reason` LIKE '%".esc_sql($search_term)."%'"; + $where .= " OR `country_origin` LIKE '%".esc_sql($search_term)."%'"; + } + + return $where; + } + + /** + * Grabs the data from database and handles the pagination + * + * @param boolean $ignore_pagination - whether to not paginate + * + * @return void + */ + public function prepare_items($ignore_pagination = false) { + /** + * First, lets decide how many records per page to show + */ + $per_page = 100; + $columns = $this->get_columns(); + $hidden = array(); + $sortable = $this->get_sortable_columns(); + + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce. + $search = isset($_REQUEST['s']) ? sanitize_text_field(wp_unslash($_REQUEST['s'])) : ''; + + $this->_column_headers = array($columns, $hidden, $sortable); + + $this->process_bulk_action(); + + global $wpdb; + $block_table_name = AIOWPSEC_TBL_PERM_BLOCK; + + // Ordering parameters + // Parameters that are going to be used to order the result + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce. + $orderby = isset($_GET["orderby"]) ? sanitize_text_field(wp_unslash($_GET["orderby"])) : ''; + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce. + $order = isset($_GET["order"]) ? sanitize_text_field(wp_unslash($_GET["order"])) : ''; + + $orderby = !empty($orderby) ? esc_sql($orderby) : 'id'; + $order = !empty($order) ? esc_sql($order) : 'DESC'; + + $orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable); + $order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1')); + + $current_page = $this->get_pagenum(); + $offset = ($current_page - 1) * $per_page; + + + $search_query = $this->get_permanent_blocked_ip_list_where_sql($search); + + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $total_items = $wpdb->get_var("SELECT COUNT(*) FROM {$block_table_name}{$search_query}"); + + if ($ignore_pagination) { + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $data = $wpdb->get_results("SELECT * FROM {$block_table_name} {$search_query} ORDER BY $orderby$order", 'ARRAY_A'); + } else { + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $data = $wpdb->get_results("SELECT * FROM {$block_table_name}{$search_query} ORDER BY $orderby $order LIMIT $per_page OFFSET $offset", 'ARRAY_A'); + } + + $this->items = $data; + + if ($ignore_pagination) return; + + $this->set_pagination_args(array( + 'total_items' => $total_items, //WE have to calculate the total number of items + 'per_page' => $per_page, //WE have to determine how many items to show on a page + 'total_pages' => ceil($total_items / $per_page) //WE have to calculate the total number of pages + )); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-registered-users.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-registered-users.php new file mode 100755 index 00000000..992eda21 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-registered-users.php @@ -0,0 +1,355 @@ + 'item', //singular name of the listed records + 'plural' => 'items', //plural name of the listed records + 'ajax' => false //does this table support ajax? + )); + + } + + public function column_default($item, $column_name) { + return $item[$column_name]; + } + + /** + * Returns ID column html to be rendered. + * + * @param array $item - data for the columns on the current row + * + * @return string - the html to be rendered + */ + public function column_ID($item) { + //Build row actions + $actions = array( + 'view' => ''.__('View', 'all-in-one-wp-security-and-firewall').'', + 'approve_acct' => ''. __('Approve', 'all-in-one-wp-security-and-firewall') . '', + 'delete_acct' => ''. __('Delete', 'all-in-one-wp-security-and-firewall') . '', + 'block_ip' => ''. __('Block IP', 'all-in-one-wp-security-and-firewall') . '', + ); + + //Return the user_login contents + return sprintf('%1$s %2$s', + /*$1%s*/ $item['ID'], + /*$2%s*/ $this->row_actions($actions) + ); + } + + /** + * Returns IP address column html to be rendered. + * + * @param array $item - data for the columns on the current row + * + * @return string - the html to be rendered + */ + public function column_ip_address($item) { + if (AIOWPSecurity_Blocking::is_ip_blocked($item['ip_address'])) { + return $item['ip_address'].'
'.__('blocked', 'all-in-one-wp-security-and-firewall').''; + } else { + return $item['ip_address']; + } + } + + public function column_cb($item) { + return sprintf( + '', + /*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label + /*$2%s*/ $item['ID'] //The value of the checkbox should be the record's id + ); + } + + + /** + * Returns array of columns to be rendered. + * + * @return array + */ + public function get_columns() { + $columns = array( + 'cb' => '', // Render a checkbox + 'ID' => __('User ID', 'all-in-one-wp-security-and-firewall'), + 'user_login' => __('Login name', 'all-in-one-wp-security-and-firewall'), + 'user_email' => __('Email', 'all-in-one-wp-security-and-firewall'), + 'user_registered' => __('Register date', 'all-in-one-wp-security-and-firewall'), + 'account_status' => __('Account status', 'all-in-one-wp-security-and-firewall'), + 'ip_address' => __('IP address', 'all-in-one-wp-security-and-firewall') + ); + return $columns; + } + + public function get_sortable_columns() { + $sortable_columns = array( + // 'ID' => array('ID',false), + // 'user_login' => array('user_login',false), + // 'user_email' => array('user_email',false), + // 'user_registered' => array('user_registered',false), + // 'account_status' => array('account_status',false), + ); + return $sortable_columns; + } + + public function get_bulk_actions() { + $actions = array( + 'approve' => __('Approve', 'all-in-one-wp-security-and-firewall'), + 'delete' => __('Delete', 'all-in-one-wp-security-and-firewall'), + 'block' => __('Block IP', 'all-in-one-wp-security-and-firewall') + ); + return $actions; + } + + /** + * Process bulk actions. + * + * @return void + */ + private function process_bulk_action() { + if (empty($_REQUEST['_wpnonce']) || !isset($_REQUEST['_wp_http_referer'])) return; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- pcp check ingore this + $result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap(sanitize_text_field(wp_unslash($_REQUEST['_wpnonce'])), 'bulk-items'); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- pcp check ingore this + if (is_wp_error($result)) return; + + if ('approve' == $this->current_action()) { //Process approve bulk actions + if (!isset($_REQUEST['item'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- pcp check ingore this + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall')); + } else { + $this->approve_selected_accounts(array_map('sanitize_text_field', wp_unslash($_REQUEST['item']))); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- pcp check ingore this + } + } + + if ('delete' == $this->current_action()) { //Process delete bulk actions + if (!isset($_REQUEST['item'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- pcp check ingore this + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall')); + } else { + $this->delete_selected_accounts(array_map('sanitize_text_field', wp_unslash($_REQUEST['item']))); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- pcp check ingore this + } + } + + if ('block' == $this->current_action()) { //Process block bulk actions + if (!isset($_REQUEST['item'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- pcp check ingore this + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall')); + } else { + $this->block_selected_ips(array_map('sanitize_text_field', wp_unslash($_REQUEST['item']))); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- pcp check ingore this + } + } + + } + + /** + * This function approves selected user accounts + * + * @param array|int $entries - this is an array of users or user_id to be approved + * + * @return void|string + */ + public function approve_selected_accounts($entries) { + global $aio_wp_security; + $meta_key = 'aiowps_account_status'; + $meta_value = 'approved'; // set account status + $failed_accts = ''; // string to store comma separated accounts which failed to update + $at_least_one_updated = false; + if (is_array($entries)) { + $entries = array_map('esc_sql', $entries); // Escape every array element + //Let's go through each entry and approve + foreach ($entries as $user_id) { + $result = update_user_meta($user_id, $meta_key, $meta_value); + if (false === $result) { + $failed_accts .= ' '.$user_id.', '; + $aio_wp_security->debug_logger->log_debug("AIOWPSecurity_List_Registered_Users::approve_selected_accounts() - could not approve account ID: $user_id", 4); + } else { + $at_least_one_updated = true; + $user = get_user_by('id', $user_id); + if (false === $user) { + //don't send mail + } else { + $this->send_email_upon_account_activation($user); + } + } + } + if ($at_least_one_updated) { + AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected accounts were approved successfully.', 'all-in-one-wp-security-and-firewall')); + } + if ('' != $failed_accts) { + //display any failed account updates + rtrim($failed_accts); + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('The following accounts failed to update successfully:', 'all-in-one-wp-security-and-firewall') . ' ' . $failed_accts); + } + } + } + + /** + * This function sends an email to an approved user + * + * @param WP_User $user - the object for the approved user + * + * @return bool + */ + public function send_email_upon_account_activation($user) { + global $aio_wp_security; + if (!($user instanceof WP_User)) { + return false; + } + + $to_email_address = $user->user_email; + $email_msg = ''; + $subject = '['.network_site_url().'] '. __('Your account is now active', 'all-in-one-wp-security-and-firewall'); + /* translators: %s: Username */ + $email_msg .= sprintf(__('Your account with username: %s is now active', 'all-in-one-wp-security-and-firewall'), $user->user_login) . "\n"; + $subject = apply_filters('aiowps_register_approval_email_subject', $subject); + $email_msg = apply_filters('aiowps_register_approval_email_msg', $email_msg, $user); //also pass the WP_User object + + $sendMail = wp_mail($to_email_address, $subject, $email_msg); + if (false === $sendMail) { + $aio_wp_security->debug_logger->log_debug("Manual account approval notification email failed to send to " . $to_email_address, 4); + } + return $sendMail; + } + + /** + * This function deletes selected entries pending approval + * + * @param array|int $entries - this is an array of users or single user to be deleted + * + * @return void|string + */ + public function delete_selected_accounts($entries) { + global $aio_wp_security; + if (is_array($entries)) { + $entries = array_map('esc_sql', $entries); // Escape every array element + //Let's go through each entry and delete account + foreach ($entries as $user_id) { + $result = wp_delete_user($user_id); + if (true !== $result) { + $aio_wp_security->debug_logger->log_debug("AIOWPSecurity_List_Registered_Users::delete_selected_accounts() - could not delete account ID: $user_id", 4); + } + } + AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected accounts were deleted successfully.', 'all-in-one-wp-security-and-firewall')); + } + } + + /** + * This function blocks selected ip + * + * @param array|int $entries - this is an array of ips or ip to be blocked + * + * @return void|string + */ + public function block_selected_ips($entries) { + global $aio_wp_security; + if (is_array($entries)) { + $entries = array_filter($entries, function ($entry) { + return AIOWPSecurity_Utility_IP::get_user_ip_address() != $entry; + }); + + if (empty($entries)) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Only invalid IP addresses were provided: you can not block your own IP address', 'all-in-one-wp-security-and-firewall')); + return; + } + $entries = array_map('esc_sql', $entries); // Escape every array element + //Let's go through each entry and block IP + $total_success = 0; + foreach ($entries as $id) { + $ip_address = get_user_meta($id, 'aiowps_registrant_ip', true); + $result = AIOWPSecurity_Blocking::add_ip_to_block_list($ip_address, 'registration_spam'); + if (false === $result) { + if (AIOWPSecurity_Utility_IP::get_user_ip_address() == $ip_address) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('You cannot block your own IP address:', 'all-in-one-wp-security-and-firewall') . ' ' . $ip_address); + } + $aio_wp_security->debug_logger->log_debug("AIOWPSecurity_List_Registered_Users::block_selected_ips() - could not block IP : $ip_address", 4); + } else { + $total_success++; + } + } + if ($total_success > 0) { + $msg = __('The selected IP addresses were successfully added to the permanent block list.', 'all-in-one-wp-security-and-firewall'); + $msg .= ' '.__('View Blocked IPs', 'all-in-one-wp-security-and-firewall').''; + AIOWPSecurity_Admin_Menu::show_msg_updated_st($msg); + } + } + } + + /** + * Grabs the data from database and handles the pagination + * + * @param boolean $ignore_pagination - whether to not paginate + * @return void + */ + public function prepare_items($ignore_pagination = false) { + //First, lets decide how many records per page to show + $per_page = 100; + $columns = $this->get_columns(); + $current_page = $this->get_pagenum(); + $offset = ($current_page - 1) * $per_page; + $hidden = array(); + $sortable = $this->get_sortable_columns(); + $search = isset($_REQUEST['s']) ? sanitize_text_field(wp_unslash($_REQUEST['s'])) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- pcp check ingore this + + $this->_column_headers = array($columns, $hidden, $sortable); + + $this->process_bulk_action(); + + //Get registered users which have the special 'aiowps_account_status' meta key set to 'pending' + if ($ignore_pagination) { + $result = $this->get_registered_user_data('pending', $search); + } else { + $result = $this->get_registered_user_data('pending', $search, $per_page, $offset); + } + + $total_items = $result['total']; + $this->items = $result['data']; + + if ($ignore_pagination) return; + + $this->set_pagination_args(array( + 'total_items' => $total_items, //WE have to calculate the total number of items + 'per_page' => $per_page, //WE have to determine how many items to show on a page + 'total_pages' => ceil($total_items/$per_page) //WE have to calculate the total number of pages + )); + } + + /** + * Returns all users who have the special 'aiowps_account_status' meta key + * + * @param string $status - the status we want to search for + * @param string $search - the search query + * @param null $per_page - how many results per page + * @param int $offset - the page offset + * + * @return array - an array of users that match the search + */ + public function get_registered_user_data($status = '', $search = '', $per_page = null, $offset = 0) { + $user_fields = array( 'ID', 'user_login', 'user_email', 'user_registered'); + $user_query = new WP_User_Query(array('meta_key' => 'aiowps_account_status', 'meta_value' => $status, 'fields' => $user_fields, 'number' => $per_page, 'offset' => $offset)); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key, WordPress.DB.SlowDBQuery.slow_db_query_meta_value -- ignore this + $user_results = $user_query->results; + $user_total = $user_query->get_total(); + + $final_data = array(); + foreach ($user_results as $user) { + $temp_array = get_object_vars($user); //Turn the object into array + $temp_array['account_status'] = get_user_meta($temp_array['ID'], 'aiowps_account_status', true); + $ip = get_user_meta($temp_array['ID'], 'aiowps_registrant_ip', true); + $temp_array['ip_address'] = empty($ip) ? '' : $ip; + if (empty($search)) { + $final_data[] = $temp_array; + } else { + $input = preg_quote($search, '~'); // don't forget to quote input string! + + $result = preg_grep('~' . $input . '~', $temp_array); + if (!empty($result)) $final_data[] = $temp_array; + } + } + + return array( + 'data' => $final_data, + 'total' => $user_total, + ); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-reset-settings.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-reset-settings.php new file mode 100755 index 00000000..179a49e5 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-reset-settings.php @@ -0,0 +1,90 @@ +query('TRUNCATE ' . $wpdb->prefix . 'aiowps_login_lockdown'); + $wpdb->query('TRUNCATE ' . $wpdb->prefix . 'aiowps_global_meta'); + $wpdb->query('TRUNCATE ' . $wpdb->prefix . 'aiowps_events'); + $wpdb->query('TRUNCATE ' . $wpdb->prefix . 'aiowps_permanent_block'); + // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared -- PCP error. Ignore. + if (is_main_site()) { + $wpdb->query('TRUNCATE ' . AIOWPSEC_TBL_LOGGED_IN_USERS); + $wpdb->query('TRUNCATE ' . AIOWPSEC_TBL_MESSAGE_STORE); + $wpdb->query('TRUNCATE ' . AIOWPSEC_TBL_DEBUG_LOG); + $wpdb->query('TRUNCATE ' . AIOWPSEC_TBL_AUDIT_LOG); + } + // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared -- PCP error. Ignore. + return true; + } + } + +endif; diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-settings-menu.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-settings-menu.php new file mode 100755 index 00000000..13556c04 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-settings-menu.php @@ -0,0 +1,157 @@ + array( + 'title' => __('General settings', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_general_settings'), + ), + 'htaccess-file-operations' => array( + 'title' => '.htaccess '.__('file', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_htaccess_file_operations'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ), + 'wp-config-file-operations' => array( + 'title' => 'wp-config.php '.__('file', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_wp_config_file_operations'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ), + 'delete-plugin-settings' => array( + 'title' => __('Delete plugin settings', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_delete_plugin_settings_tab') + ), + 'wp-version-info' => array( + 'title' => __('WP version info', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_wp_version_info'), + ), + 'settings-file-operations' => array( + 'title' => __('Import/Export', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_settings_file_operations'), + ), + 'advanced-settings' => array( + 'title' => __('Advanced settings', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_advanced_settings'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ), + ); + + $menu_tabs = apply_filters('aiowpsecurity_setting_tabs', $menu_tabs); + $this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab')); + } + + /** + * Renders the submenu's general settings tab. + * + * @return void + */ + protected function render_general_settings() { + global $aio_wp_security; + + $aio_wp_security->include_template('wp-admin/settings/general-settings.php', false, array()); + } + + /** + * Renders the submenu's htaccess file operations tab. + * + * @return void + */ + protected function render_htaccess_file_operations() { + global $aio_wp_security; + + $aio_wp_security->include_template('wp-admin/settings/htaccess-file-operations.php', false, array()); + } + + /** + * Renders the submenu's wp config file operations tab. + * + * @return void + */ + protected function render_wp_config_file_operations() { + global $aio_wp_security; + + $aio_wp_security->include_template('wp-admin/settings/wp-config-file-operations.php', false, array()); + } + + /** + * Renders the submenu's delete plugin settings tab. + * + * @return void + */ + protected function render_delete_plugin_settings_tab() { + global $aio_wp_security; + + $aio_wp_security->include_template('wp-admin/settings/delete-plugin-settings.php', false, array()); + } + + /** + * Renders the submenu's wp version info tab. + * + * @return void + */ + protected function render_wp_version_info() { + global $aio_wp_security, $aiowps_feature_mgr; + + $aio_wp_security->include_template('wp-admin/settings/wp-version-info.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr)); + } + + /** + * Renders the submenu's settings file operations tab. + * + * @return void + */ + protected function render_settings_file_operations() { + global $aio_wp_security; + + $events_table_name = AIOWPSEC_TBL_EVENTS; + AIOWPSecurity_Utility::cleanup_table($events_table_name, 500); + + $aio_wp_security->include_template('wp-admin/settings/settings-file-operations.php', false, array()); + } + + /** + * Renders advanced settings tab. + * + * @return void + */ + protected function render_advanced_settings() { + if (!is_main_site()) { + return; + } + + global $aio_wp_security; + + $aios_commands = new AIOWPSecurity_Commands(); + + $advanced_settings_data = $aios_commands->get_ip_address_detection_data(); + + $aio_wp_security->include_template('wp-admin/settings/advanced-settings.php', false, $advanced_settings_data); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-spam-menu.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-spam-menu.php new file mode 100755 index 00000000..1c13d061 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-spam-menu.php @@ -0,0 +1,93 @@ + array( + 'title' => __('Comment spam', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_comment_spam'), + ), + 'comment-spam-ip-monitoring' => array( + 'title' => __('Comment spam IP monitoring', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_comment_spam_ip_monitoring'), + ), + ); + + $this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab')); + } + + /** + * Renders the submenu's comment spam ip monitoring tab body. + * + * @return Void + */ + protected function render_comment_spam() { + global $aiowps_feature_mgr, $aio_wp_security; + $aio_wp_security->include_template('wp-admin/spam-prevention/comment-spam.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr)); + } + + /** + * Renders the submenu's comment spam ip monitoring tab body. + * + * @return Void + */ + protected function render_comment_spam_ip_monitoring() { + global $aio_wp_security, $aiowps_feature_mgr, $wpdb; + include_once 'wp-security-list-comment-spammer-ip.php'; // For rendering the AIOWPSecurity_List_Table in tab2 + $spammer_ip_list = new AIOWPSecurity_List_Comment_Spammer_IP(); + + $block_comments_output = ''; + + $min_block_comments = $aio_wp_security->configs->get_value('aiowps_spam_ip_min_comments_block'); + if (!empty($min_block_comments)) { + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $total_res = $wpdb->get_results($wpdb->prepare('SELECT * FROM '.AIOWPSEC_TBL_PERM_BLOCK.' WHERE block_reason=%s', 'spam')); + $block_comments_output = '
'; + if (empty($total_res)) { + $block_comments_output .= '

'.esc_html__('You currently have no IP addresses permanently blocked due to spam.', 'all-in-one-wp-security-and-firewall').'

'; + } else { + $total_count = count($total_res); + $todays_blocked_count = 0; + foreach ($total_res as $blocked_item) { + $now_date_time = new DateTime('now', new DateTimeZone('UTC')); + $blocked_date = new DateTime('@'.$blocked_item->created); //@ with timestamp creates correct DateTime + if ($blocked_date->format('Y-m-d') == $now_date_time->format('Y-m-d')) { + //there was an IP added to permanent block list today + ++$todays_blocked_count; + } + } + $block_comments_output .= '

'.esc_html__('Spammer IPs added to permanent block list today:', 'all-in-one-wp-security-and-firewall'). ' ' . esc_html($todays_blocked_count).'

'.'

'.esc_html__('All time total:', 'all-in-one-wp-security-and-firewall'). ' ' .esc_html($total_count).'

'.'

'.esc_html__('View blocked IPs', 'all-in-one-wp-security-and-firewall').'

'; + } + } + + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce. + $page = isset($_REQUEST['page']) ? sanitize_text_field(wp_unslash($_REQUEST['page'])) : ''; + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce. + $tab = isset($_REQUEST['tab']) ? sanitize_text_field(wp_unslash($_REQUEST['tab'])) : ''; + + $aio_wp_security->include_template('wp-admin/spam-prevention/comment-spam-ip-monitoring.php', false, array('spammer_ip_list' => $spammer_ip_list, 'aiowps_feature_mgr' => $aiowps_feature_mgr, 'block_comments_output' => $block_comments_output, 'page' => $page, 'tab' => $tab)); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-tools-menu.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-tools-menu.php new file mode 100755 index 00000000..a41827c8 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-tools-menu.php @@ -0,0 +1,98 @@ + array( + 'title' => __('Password tool', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_password_tool'), + ), + 'whois-lookup' => array( + 'title' => __('WHOIS lookup', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_whois_lookup_tab'), + ), + 'custom-rules' => array( + 'title' => __('Custom .htaccess rules', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_custom_rules'), + 'display_condition_callback' => array('AIOWPSecurity_Utility', 'allow_to_write_to_htaccess'), + ), + 'visitor-lockout' => array( + 'title' => __('Visitor lockout', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_visitor_lockout'), + ), + ); + + $this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab')); + } + + /** + * Render the 'Custom (htaccess) rules' tab + * + * @return void + */ + protected function render_custom_rules() { + global $aio_wp_security; + + $aio_wp_security->include_template('wp-admin/tools/custom-htaccess.php'); + } + + /** + * Renders the submenu's password tool tab + * + * @return Void + */ + protected function render_password_tool() { + global $aio_wp_security; + + wp_enqueue_script('aiowpsec-pw-tool-js'); + $aio_wp_security->include_template('wp-admin/tools/password-tool.php'); + } + + /** + * Renders the submenu's whois-lookup tab body. + * + * @return Void + */ + protected function render_whois_lookup_tab() { + global $aio_wp_security; + + $aio_wp_security->include_template('wp-admin/tools/whois-lookup.php', false, array()); + } + + /** + * Renders the submenu's visitor lockout tab + * + * @return void + */ + protected function render_visitor_lockout() { + global $aio_wp_security; + + $aio_wp_security->include_template('wp-admin/tools/visitor-lockout.php', false, array()); + } + +} // End of class diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-user-security-menu.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-user-security-menu.php new file mode 100755 index 00000000..721f2a43 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-user-security-menu.php @@ -0,0 +1,296 @@ + array( + 'title' => __('User accounts', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_wp_user_account'), + ), + 'login-lockout' => array( + 'title' => __('Login lockout', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_login_lockout'), + ), + 'force-logout' => array( + 'title' => __('Force logout', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_force_logout'), + ), + 'logged-in-users' => array( + 'title' => __('Logged in users', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_logged_in_users'), + ), + 'manual-approval' => array( + 'title' => __('Manual approval', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_manual_approval'), + ), + 'salt' => array( + 'title' => __('Salt', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_salt_tab'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ), + 'http-authentication' => array( + 'title' => __('HTTP authentication', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_http_authentication'), + ), + 'hibp' => array( + 'title' => __('HIBP', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_hibp'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ), + 'additional' => array( + 'title' => __('Additional settings', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_additional'), + ), + ); + + $this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab')); + } + + /** + * Renders the submenu's WP User Account tab + * + * @return Void + */ + protected function render_wp_user_account() { + global $aio_wp_security, $aiowps_feature_mgr; + + if (is_multisite()) { // Multi-site: get admin accounts for current site + $blog_id = get_current_blog_id(); + $user_accounts = $this->get_all_admin_accounts($blog_id); + } else { + $user_accounts = $this->get_all_admin_accounts(); + } + + $aio_wp_security->include_template('wp-admin/user-security/user-accounts.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr, 'user_accounts' => $user_accounts, 'AIOWPSecurity_User_Security_Menu' => $this)); + } + + + /** + * This function will retrieve all user accounts which have 'administrator' role and will return html code with results in a table + * + * @param string $blog_id - the blog we want to get the user account information from + * + * @return string - the html from the result + */ + private function get_all_admin_accounts($blog_id = '') { + // TODO: Have included the "blog_id" variable for future use for cases where people want to search particular blog (eg, multi-site) + if ($blog_id) { + $admin_users = get_users('blog_id='.$blog_id.'&orderby=login&role=administrator'); + } else { + $admin_users = get_users('orderby=login&role=administrator'); + } + // now let's put the results in an HTML table + $account_output = ""; + if (!empty($admin_users)) { + $account_output .= ''; + $account_output .= ''; + foreach ($admin_users as $entry) { + $account_output .= ''; + if (strtolower($entry->user_login) == 'admin') { + $account_output .= ''; + } else { + $account_output .= ''; + } + $user_acct_edit_link = admin_url('user-edit.php?user_id=' . $entry->ID); + $account_output .= ''; + $account_output .= ''; + } + $account_output .= '
'.esc_html(__('Account login name', 'all-in-one-wp-security-and-firewall')).'
'.esc_html($entry->user_login).''.esc_html($entry->user_login).''.esc_html(__('Edit user', 'all-in-one-wp-security-and-firewall')).'
'; + } + return $account_output; + } + + /** + * Login Lockout configuration to set. + * + * @global AIO_WP_Security $aio_wp_security + * @global AIOWPSecurity_Feature_Item_Manager $aiowps_feature_mgr + * + * @return Void + */ + protected function render_login_lockout() { + global $aio_wp_security, $aiowps_feature_mgr; + + include_once 'wp-security-list-locked-ip.php'; // For rendering the AIOWPSecurity_List_Table in tab1 + $locked_ip_list = new AIOWPSecurity_List_Locked_IP(); // For rendering the AIOWPSecurity_List_Table in tab1 + + $aiowps_lockdown_allowed_ip_addresses = $aio_wp_security->configs->get_value('aiowps_lockdown_allowed_ip_addresses'); + + $aio_wp_security->include_template('wp-admin/user-security/login-lockout.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr, 'locked_ip_list' => $locked_ip_list, "aiowps_lockdown_allowed_ip_addresses" => $aiowps_lockdown_allowed_ip_addresses)); + } + + /** + * Force logged user to logout after x minutes. + * + * @global AIO_WP_Security $aio_wp_security + * @global AIOWPSecurity_Feature_Item_Manager $aiowps_feature_mgr + * @return void + */ + protected function render_force_logout() { + global $aio_wp_security, $aiowps_feature_mgr; + + $aio_wp_security->include_template('wp-admin/user-security/force-logout.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr)); + } + + /** + * Logged in users list. + * + * @global AIO_WP_Security $aio_wp_security + * @return void + */ + protected function render_logged_in_users() { + global $aio_wp_security; + + include_once 'wp-security-list-logged-in-users.php'; // For rendering the AIOWPSecurity_List_Table + $user_list = new AIOWPSecurity_List_Logged_In_Users(); + + $aio_wp_security->include_template('wp-admin/user-security/logged-in-users.php', false, array('user_list' => $user_list)); + } + + /** + * Renders the submenu's manual approval tab + * + * @return Void + */ + protected function render_manual_approval() { + global $aio_wp_security, $aiowps_feature_mgr; + + include_once 'wp-security-list-registered-users.php'; // For rendering the AIOWPSecurity_List_Table + $user_list = new AIOWPSecurity_List_Registered_Users(); + + $aio_wp_security->include_template('wp-admin/user-security/manual-approval.php', false, array('user_list' => $user_list, 'aiowps_feature_mgr' => $aiowps_feature_mgr)); + } + + /** + * Renders the submenu's salt tab + * + * @return Void + */ + protected function render_salt_tab() { + global $aio_wp_security; + + $aio_wp_security->include_template('wp-admin/user-security/salt.php'); + } + + /** + * Renders the submenu's http authentication tab. + * + * @global AIO_WP_Security $aio_wp_security + * + * @return void + */ + protected function render_http_authentication() { + global $aio_wp_security, $aiowps_feature_mgr; + + if (isset($_POST['aiowps_save_http_authentication_settings'])) { + $nonce_user_cap_result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($_POST['_wpnonce'], 'aiowpsec-http-authentication-settings-nonce'); + + if (is_wp_error($nonce_user_cap_result)) { + $aio_wp_security->debug_logger->log_debug($nonce_user_cap_result->get_error_message(), 4); + die($nonce_user_cap_result->get_error_message()); + } + + $error = false; + + $aio_wp_security->configs->set_value('aiowps_http_authentication_admin', ''); + + if (isset($_POST['aiowps_http_authentication_admin'])) { + if (!is_ssl()) { + $this->show_msg_error(__('Failed to save \'Enable for WordPress dashboard\'.', 'all-in-one-wp-security-and-firewall') . ' ' . __('Your site is currently not using https.', 'all-in-one-wp-security-and-firewall')); + $error = true; + } else { + $aio_wp_security->configs->set_value('aiowps_http_authentication_admin', '1'); + } + } + + $aio_wp_security->configs->set_value('aiowps_http_authentication_frontend', ''); + + if (isset($_POST['aiowps_http_authentication_frontend'])) { + if (!is_ssl()) { + $this->show_msg_error(__('Failed to save \'Enable for frontend\'.', 'all-in-one-wp-security-and-firewall') . ' ' . __('Your site is currently not using https.', 'all-in-one-wp-security-and-firewall')); + $error = true; + } else { + $aio_wp_security->configs->set_value('aiowps_http_authentication_frontend', '1'); + } + } + + if (empty($_POST['aiowps_http_authentication_username'])) { + $this->show_msg_error(__('Failed to save \'Username\'.', 'all-in-one-wp-security-and-firewall') . ' ' . __('Please enter a value for the HTTP authentication username.', 'all-in-one-wp-security-and-firewall')); + $error = true; + } else { + $aio_wp_security->configs->set_value('aiowps_http_authentication_username', sanitize_text_field($_POST['aiowps_http_authentication_username'])); + } + + if (empty($_POST['aiowps_http_authentication_password'])) { + $this->show_msg_error(__('Failed to save \'Password\'.', 'all-in-one-wp-security-and-firewall') . ' ' . __('Please enter a value for the HTTP authentication password.', 'all-in-one-wp-security-and-firewall')); + $error = true; + } else { + $aio_wp_security->configs->set_value('aiowps_http_authentication_password', sanitize_text_field($_POST['aiowps_http_authentication_password'])); + } + + $aio_wp_security->configs->set_value('aiowps_http_authentication_failure_message', htmlentities(stripslashes($_POST['aiowps_http_authentication_failure_message']), ENT_COMPAT, 'UTF-8')); + + $aio_wp_security->configs->save_config(); + + // Recalculate points after the feature status/options have been altered. + $aiowps_feature_mgr->check_feature_status_and_recalculate_points(); + + if (!$error) { + $this->show_msg_settings_updated(); + } + } + + wp_enqueue_script('aiowpsec-pw-tool-js'); + + $aio_wp_security->include_template('wp-admin/user-security/http-authentication.php'); + } + + /** + * Renders the submenu's hibp tab. + * + * @global AIO_WP_Security $aio_wp_security + * + * @return void + */ + protected function render_hibp() { + global $aio_wp_security; + + $aio_wp_security->include_template('wp-admin/user-security/hibp.php'); + } + + /** + * Shows additional tab and field for the disable application password and saves on submit. + * + * @global AIO_WP_Security $aio_wp_security + * @global AIOWPSecurity_Feature_Item_Manager $aiowps_feature_mgr + * @return void + */ + protected function render_additional() { + global $aio_wp_security, $aiowps_feature_mgr; + + $aio_wp_security->include_template('wp-admin/user-security/additional.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr)); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/backups/index.html b/wp-content/plugins/all-in-one-wp-security-and-firewall/backups/index.html new file mode 100755 index 00000000..e69de29b diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-brute-force-commands.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-brute-force-commands.php new file mode 100755 index 00000000..44783bac --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-brute-force-commands.php @@ -0,0 +1,561 @@ +' . __('You cannot use the value "wp-admin" for your login page slug.', 'all-in-one-wp-security-and-firewall'); + } elseif (preg_match('/[^\p{L}\p{N}_\-]/u', $aiowps_login_page_slug)) { + $error = '
' . __('You must use alphanumeric characters for your login page slug.', 'all-in-one-wp-security-and-firewall'); + } + } + + if ($error) { + $success = false; + $message = $error; + } else { + $options['aiowps_enable_rename_login_page'] = isset($data["aiowps_enable_rename_login_page"]) ? '1' : ''; + $options['aiowps_login_page_slug'] = $aiowps_login_page_slug; + + $this->save_settings($options); + + if (get_option('permalink_structure')) { + $home_url = trailingslashit(home_url()); + } else { + $home_url = trailingslashit(home_url()) . '?'; + } + + $message = __('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall'); + $args['badges'] = array("bf-rename-login-page"); + $args['content'] = array('aios-rename-login-notice' => $aio_wp_security->include_template('wp-admin/brute-force/partials/rename-login-notice.php', true, array('home_url' => $home_url))); + } + + return $this->handle_response($success, $message, $args); + } + + /** + * Handles the AJAX request to enable or configure cookie-based brute force prevention. + * + * @param array $data The data received from the AJAX request. + * + * @return array The response containing the status, message, and badge. + */ + public function perform_cookie_based_brute_force_prevention($data) { + global $aio_wp_security; + + $options = array(); + $values = array(); + $info = array(); + + $success = true; + $message = ''; + $result = ''; + + if (isset($data['aiowps_enable_brute_force_attack_prevention'])) { + $brute_force_feature_secret_word = sanitize_text_field($data['aiowps_brute_force_secret_word']); + $redirect_url = sanitize_text_field($data['aiowps_cookie_based_brute_force_redirect_url']); + if (empty($brute_force_feature_secret_word)) { + $brute_force_feature_secret_word = AIOS_DEFAULT_BRUTE_FORCE_FEATURE_SECRET_WORD; + $info[] = __('You entered an invalid value for the secret word.', 'all-in-one-wp-security-and-firewall'). ' ' . __('It has been set to the default value.', 'all-in-one-wp-security-and-firewall'); + } elseif (!ctype_alnum($brute_force_feature_secret_word)) { + $message = '

' . __('Settings have not been saved - your secret word must consist only of alphanumeric characters i.e., letters and/or numbers only.', 'all-in-one-wp-security-and-firewall') . '

'; + $success = false; + } + + if (filter_var($redirect_url, FILTER_VALIDATE_URL)) { + $redirect_url = esc_url_raw($redirect_url); + } else { + $redirect_url = 'http://127.0.0.1'; + $info[] = __('You entered an invalid value for the redirect url.', 'all-in-one-wp-security-and-firewall'). ' ' . __('It has been set to the default value.', 'all-in-one-wp-security-and-firewall'); + } + + $options['aiowps_cookie_based_brute_force_redirect_url'] = $redirect_url; + + if ($success) { + $options['aiowps_enable_brute_force_attack_prevention'] = '1'; + $options['aiowps_brute_force_secret_word'] = $brute_force_feature_secret_word; + + $result = '

' . __('You have successfully enabled the cookie based brute force prevention feature', 'all-in-one-wp-security-and-firewall') . '

'; + $result .= '

' . __('From now on you will need to log into your WP Admin using the following URL:', 'all-in-one-wp-security-and-firewall') . '

'; + $result .= '

'.AIOWPSEC_WP_URL.'/?'.esc_html($brute_force_feature_secret_word).'=1

'; + $result .= '

' . __('It is important that you save this URL value somewhere in case you forget it, OR,', 'all-in-one-wp-security-and-firewall') . '

'; + $result .= '

' . sprintf(__('simply remember to add a "?%s=1" to your current site URL address.', 'all-in-one-wp-security-and-firewall'), esc_html($brute_force_feature_secret_word)) . '

'; + AIOWPSecurity_Utility::set_cookie_value(AIOWPSecurity_Utility::get_brute_force_secret_cookie_name(), AIOS_Helper::get_hash($brute_force_feature_secret_word)); + } + } else { + $options['aiowps_enable_brute_force_attack_prevention'] = ''; + $message = __('You have successfully saved cookie based brute force prevention feature settings.', 'all-in-one-wp-security-and-firewall'); + $brute_force_feature_secret_word = $aio_wp_security->configs->get_value('aiowps_brute_force_secret_word'); + $redirect_url = $aio_wp_security->configs->get_value('aiowps_cookie_based_brute_force_redirect_url'); + } + + $options['aiowps_brute_force_attack_prevention_pw_protected_exception'] = isset($data['aiowps_brute_force_attack_prevention_pw_protected_exception']) ? '1' : ''; + $options['aiowps_brute_force_attack_prevention_ajax_exception'] = isset($data['aiowps_brute_force_attack_prevention_ajax_exception']) ? '1' : ''; + + if ($success) { + $this->save_settings($options); + + AIOWPSecurity_Configure_Settings::set_cookie_based_bruteforce_firewall_configs(); + + $message = __('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall'); + $values['aiowps_brute_force_secret_word'] = $brute_force_feature_secret_word; + $values['aiowps_cookie_based_brute_force_redirect_url'] = $redirect_url; + } + $content = array( + 'aios-brute-force-info-box' => $result + ); + + $badges = array("firewall-enable-brute-force-attack-prevention"); + + $args = array( + 'badges' => $badges, + 'info' => $info, + 'values' => $values, + 'content' => $content + ); + + return $this->handle_response($success, $message, $args); + } + + /** + * Handles the AJAX request for performing cookie test. + * + * @return array The response containing the status, message, and badge. + */ + public function perform_cookie_test() { + global $aio_wp_security; + + $success = true; + + $random_suffix = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(10); + $test_cookie_name = 'aiowps_cookie_test_'.$random_suffix; + $aio_wp_security->configs->set_value('aiowps_cookie_brute_test', $test_cookie_name, true); + $set_cookie = AIOWPSecurity_Utility::set_cookie_value($test_cookie_name, '1'); + $aiowps_cookie_test_success = ''; + $args = array(); + + if ($set_cookie) { + $aiowps_cookie_test_success = '1'; + $message = __('The cookie test was successful, you can now enable this feature.', 'all-in-one-wp-security-and-firewall'); + $result = '

' . __('The cookie test was successful, you can now enable this feature.', 'all-in-one-wp-security-and-firewall') . '

'; + } else { + $success = false; + $message = __('The cookie test failed.', 'all-in-one-wp-security-and-firewall') .' '. __('Consequently, this feature cannot be used on this site.', 'all-in-one-wp-security-and-firewall'); + $result = '

' . __('The cookie test failed on this server.', 'all-in-one-wp-security-and-firewall') .' '. __('Consequently, this feature cannot be used on this site.', 'all-in-one-wp-security-and-firewall') . '

'; + } + + $this->save_settings(array('aiowps_cookie_test_success' => $aiowps_cookie_test_success)); // save the value + $args['content'] = array( + 'aios-perform-cookie-test-div' => $this->get_perform_cookie_test_content(), + 'cookie-test-result-div' => $result + ); + + return $this->handle_response($success, $message, $args); + } + + /** + * Handles the AJAX request to enable or configure login whitelist settings. + * + * @param array $data The data received from the AJAX request. + * + * @return array The response containing the status, message, and badge. + */ + public function perform_login_whitelist_settings($data) { + global $aio_wp_security; + + $success = true; + $options = array(); + $message = ''; + + if (!empty($data['aiowps_allowed_ip_addresses'])) { + $ip_addresses = sanitize_textarea_field(stripslashes($data['aiowps_allowed_ip_addresses'])); + $ip_list_array = AIOWPSecurity_Utility_IP::create_ip_list_array_from_string_with_newline($ip_addresses); + $validated_ip_list_array = AIOWPSecurity_Utility_IP::validate_ip_list($ip_list_array, 'whitelist'); + if (is_wp_error($validated_ip_list_array)) { + $result = -1; + $success = false; + $message = nl2br($validated_ip_list_array->get_error_message()); + } else { + $result = 1; + $whitelist_ip_data = implode("\n", $validated_ip_list_array); + $options['aiowps_allowed_ip_addresses'] = $whitelist_ip_data; + } + } else { + $result = 1; + $options['aiowps_allowed_ip_addresses'] = ''; // Clear the IP address config value + } + + if (1 == $result) { + $options['aiowps_enable_whitelisting'] = isset($data["aiowps_enable_whitelisting"]) ? '1' : ''; + if ('1' == $aio_wp_security->configs->get_value('aiowps_is_login_whitelist_disabled_on_upgrade')) { + $aio_wp_security->configs->delete_value('aiowps_is_login_whitelist_disabled_on_upgrade'); + } + $this->save_settings($options); + } + + $args = array( + 'badges' => array('whitelist-manager-ip-login-whitelisting') + ); + + return $this->handle_response($success, $message, $args); + } + + /** + * Handles the AJAX request to enable or configure honeypot brute force settings. + * + * @param array $data The data received from the AJAX request. + * + * @return array The response containing the status, message, and badge. + */ + public function perform_honeypot_settings($data) { + + $options = array(); + // Save all the form values to the options + $options['aiowps_enable_login_honeypot'] = isset($data["aiowps_enable_login_honeypot"]) ? '1' : ''; + $options['aiowps_enable_registration_honeypot'] = isset($data["aiowps_enable_registration_honeypot"]) ? '1' : ''; + + $this->save_settings($options); + + $args = array( + 'badges' => array('login-honeypot', 'registration-honeypot') + ); + + return $this->handle_response(true, '', $args); + } + + /** + * Handles the AJAX request to enable or configure captcha settings. + * + * @param array $data The data received from the AJAX request. + * + * @return array The response containing the status, message, and badge. + */ + public function perform_captcha_settings($data) { + global $aio_wp_security; + + $captcha_themes = $aio_wp_security->captcha_obj->get_captcha_themes(); + $supported_captchas = $aio_wp_security->captcha_obj->get_supported_captchas(); + $options = array(); + + $default_captcha = isset($data['aiowps_default_captcha']) ? sanitize_text_field($data['aiowps_default_captcha']) : ''; + + $default_captcha = array_key_exists($default_captcha, $supported_captchas) ? $default_captcha : 'none'; + + $options['aiowps_default_captcha'] = $default_captcha; + + // Save all the form values to the options + $random_20_digit_string = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(20); // Generate random 20 char string for use during CAPTCHA encode/decode + $options['aiowps_captcha_secret_key'] = $random_20_digit_string; + $options['aiowps_enable_login_captcha'] = isset($data["aiowps_enable_login_captcha"]) ? '1' : ''; + $options['aiowps_enable_registration_page_captcha'] = isset($data["aiowps_enable_registration_page_captcha"]) ? '1' : ''; + $options['aiowps_enable_comment_captcha'] = isset($data["aiowps_enable_comment_captcha"]) ? '1' : ''; + $options['aiowps_enable_bp_register_captcha'] = isset($data["aiowps_enable_bp_register_captcha"]) ? '1' : ''; + $options['aiowps_enable_bbp_new_topic_captcha'] = isset($data["aiowps_enable_bbp_new_topic_captcha"]) ? '1' : ''; + $options['aiowps_enable_woo_login_captcha'] = isset($data["aiowps_enable_woo_login_captcha"]) ? '1' : ''; + $options['aiowps_enable_woo_register_captcha'] = isset($data["aiowps_enable_woo_register_captcha"]) ? '1' : ''; + $options['aiowps_enable_woo_lostpassword_captcha'] = isset($data["aiowps_enable_woo_lostpassword_captcha"]) ? '1' : ''; + $options['aiowps_enable_woo_checkout_captcha'] = isset($data["aiowps_enable_woo_checkout_captcha"]) ? '1' : ''; + $options['aiowps_enable_custom_login_captcha'] = isset($data["aiowps_enable_custom_login_captcha"]) ? '1' : ''; + $options['aiowps_enable_lost_password_captcha'] = isset($data["aiowps_enable_lost_password_captcha"]) ? '1' : ''; + $options['aiowps_enable_contact_form_7_captcha'] = isset($data["aiowps_enable_contact_form_7_captcha"]) ? '1' : ''; + $options['aiowps_enable_password_protected_captcha'] = isset($data["aiowps_enable_password_protected_captcha"]) ? '1' : ''; + + $options['aiowps_turnstile_site_key'] = sanitize_text_field(stripslashes($data['aiowps_turnstile_site_key'])); + $options['aiowps_recaptcha_site_key'] = sanitize_text_field(stripslashes($data['aiowps_recaptcha_site_key'])); + + $turnstile_theme = isset($data['aiowps_turnstile_theme']) ? sanitize_text_field($data['aiowps_turnstile_theme']) : ''; + $turnstile_theme = array_key_exists($turnstile_theme, $captcha_themes) ? $turnstile_theme : 'auto'; + $options['aiowps_turnstile_theme'] = $turnstile_theme; + + // If secret key is masked then don't resave it + $turnstile_secret_key = sanitize_text_field($data['aiowps_turnstile_secret_key']); + if (strpos($turnstile_secret_key, '********') === false) { + $options['aiowps_turnstile_secret_key'] = $turnstile_secret_key; + } + + // If secret key is masked then don't resave it + $recaptcha_secret_key = sanitize_text_field($data['aiowps_recaptcha_secret_key']); + if (strpos($recaptcha_secret_key, '********') === false) { + $options['aiowps_recaptcha_secret_key'] = $recaptcha_secret_key; + } + + if ('google-recaptcha-v2' == $aio_wp_security->configs->get_value('aiowps_default_captcha') && false === $aio_wp_security->captcha_obj->google_recaptcha_verify_configuration($aio_wp_security->configs->get_value('aiowps_recaptcha_site_key'), $aio_wp_security->configs->get_value('aiowps_recaptcha_secret_key'))) { + $options['aios_google_recaptcha_invalid_configuration'] = '1'; + } elseif ('1' == $aio_wp_security->configs->get_value('aios_google_recaptcha_invalid_configuration')) { + $aio_wp_security->configs->delete_value('aios_google_recaptcha_invalid_configuration'); + } + + $this->save_settings($options); + + $success = false; + $message = ''; + if ('cloudflare-turnstile' == $aio_wp_security->configs->get_value('aiowps_default_captcha') && false === $aio_wp_security->captcha_obj->cloudflare_turnstile_verify_configuration($aio_wp_security->configs->get_value('aiowps_turnstile_site_key'), $aio_wp_security->configs->get_value('aiowps_turnstile_secret_key'))) { + $message = __('Your Cloudflare Turnstile configuration is invalid.', 'all-in-one-wp-security-and-firewall').' '.__('Please enter the correct Cloudflare Turnstile keys below to use the Turnstile feature.', 'all-in-one-wp-security-and-firewall'); + } elseif ('google-recaptcha-v2' == $aio_wp_security->configs->get_value('aiowps_default_captcha') && '1' == $aio_wp_security->configs->get_value('aios_google_recaptcha_invalid_configuration')) { + $message = __('Your Google reCAPTCHA configuration is invalid.', 'all-in-one-wp-security-and-firewall').' '.__('Please enter the correct reCAPTCHA keys below to use the reCAPTCHA feature.', 'all-in-one-wp-security-and-firewall'); + } else { + $success = true; + } + + $features = array( + "user-login-captcha", + "user-registration-captcha", + "lost-password-captcha", + "custom-login-captcha", + "comment-form-captcha", + "password_protected-captcha", + ); + + if (AIOWPSecurity_Utility::is_woocommerce_plugin_active()) { + $woocommerce_features = array( + "woo-login-captcha", + "woo-lostpassword-captcha", + "woo-register-captcha", + "woo-checkout-captcha", + ); + $features = array_merge($features, $woocommerce_features); + } + + if (AIOWPSecurity_Utility::is_buddypress_plugin_active()) { + $features[] = "bp-register-captcha"; + } + + if (AIOWPSecurity_Utility::is_bbpress_plugin_active()) { + $features[] = "bbp-new-topic-captcha"; + } + + if (AIOWPSecurity_Utility::is_contact_form_7_plugin_active()) { + $features[] = "contact-form-7-captcha"; + } + + $args = array( + 'badges' => $features + ); + + return $this->handle_response($success, $message, $args); + } + + /** + * Handles the AJAX request to enable or configure 404 detection and settings. + * + * @param array $data The data received from the AJAX request. + * + * @return array The response containing the status, message, and badge. + */ + public function perform_404_settings($data) { + + $options = array(); + $info = array(); + $values = array(); + + $options['aiowps_enable_404_logging'] = isset($data["aiowps_enable_404_IP_lockout"]) ? '1' : ''; //the "aiowps_enable_404_IP_lockout" checkbox currently controls both the 404 lockout and 404 logging + $options['aiowps_enable_404_IP_lockout'] = isset($data["aiowps_enable_404_IP_lockout"]) ? '1' : ''; + + $lockout_time_length = isset($data['aiowps_404_lockout_time_length']) ? sanitize_text_field($data['aiowps_404_lockout_time_length']) : ''; + $redirect_url = isset($data['aiowps_404_lock_redirect_url']) ? sanitize_text_field(trim($data['aiowps_404_lock_redirect_url'])) : ''; + + if (isset($data["aiowps_enable_404_IP_lockout"])) { + if (!is_numeric($lockout_time_length) || $lockout_time_length < 1) { + $info[] = __('You entered a non numeric or negative value for the lockout time length field.', 'all-in-one-wp-security-and-firewall'). ' ' . __('It has been set to the default value.', 'all-in-one-wp-security-and-firewall'); + $lockout_time_length = '60'; // Set it to the default value for this field + } + + if ('' == $redirect_url || '' == esc_url($redirect_url, array('http', 'https'))) { + $info[] = __('You entered an incorrect format for the "Redirect URL" field.', 'all-in-one-wp-security-and-firewall') . ' ' . __('It has been set to the default value.', 'all-in-one-wp-security-and-firewall'); + $redirect_url = 'http://127.0.0.1'; + } + } + + $options['aiowps_404_lockout_time_length'] = absint($lockout_time_length); + $options['aiowps_404_lock_redirect_url'] = $redirect_url; + $this->save_settings($options); + + $badges = array("firewall-enable-404-blocking"); + $values['aiowps_404_lockout_time_length'] = $lockout_time_length; + $values['aiowps_404_lock_redirect_url'] = $redirect_url; + + $args = array( + 'badges' => $badges, + 'info' => $info, + 'values' => $values + ); + + return $this->handle_response(true, '', $args); + } + + /** + * Handles the AJAX request to clear 404 logs. + * + * @return array The response containing the status, message, and badge. + */ + public function perform_delete_404_event_records() { + global $aio_wp_security, $wpdb; + + $success = true; + $events_table_name = AIOWPSEC_TBL_EVENTS; + //Delete all 404 records from the events table + $where = array('event_type' => '404'); + $result = $wpdb->delete($events_table_name, $where); + + if (false === $result) { + $error = empty($wpdb->last_error) ? '' : $wpdb->last_error; + $aio_wp_security->debug_logger->log_debug("404 Detection Feature - Delete all 404 event logs operation failed. $error", 4); + $success = false; + $message = __('404 Detection Feature - The operation to delete all the 404 event logs failed', 'all-in-one-wp-security-and-firewall'); + } else { + $message = __('All 404 event logs were deleted from the database successfully.', 'all-in-one-wp-security-and-firewall'); + } + + return $this->handle_response($success, $message); + } + + /** + * Handles the AJAX request for 404 log item actions. + * + * @param array $data The data received from the AJAX request. + * + * @return array The response containing the status, message, and badge. + */ + public function perform_404_log_item_action($data) { + global $wpdb, $aio_wp_security, $aiowps_firewall_config; + + if (empty($data['action']) || !in_array($data['action'], array('delete', 'temp_block', 'blacklist', 'unblock'))) { + return $this->handle_response(false, __('Invalid action provided for 404 log item.', 'all-in-one-wp-security-and-firewall')); + } + + $action = $data['action']; + $message = false; + + switch ($action) { + case 'delete': + if (!isset($data['id'])) { + return $this->handle_response(false, __('Invalid 404 event log ID provided.', 'all-in-one-wp-security-and-firewall')); + } + $events_table = AIOWPSEC_TBL_EVENTS; + $id = absint($data['id']); + //Delete single record + $delete_command = "DELETE FROM " . $events_table . " WHERE id = '" . absint($id) . "'"; + $result = $wpdb->query($delete_command); + if (false === $result) { + // Error on single delete + $aio_wp_security->debug_logger->log_debug('Database error occurred when deleting rows from Events table. Database error: '.$wpdb->last_error, 4); + return $this->handle_response(false, __('The selected record(s) have failed to delete.', 'all-in-one-wp-security-and-firewall')); + } else { + $message = __('The selected record(s) has been deleted successfully.', 'all-in-one-wp-security-and-firewall'); + } + break; + case 'temp_block': + if (!isset($data['ip'])) { + return $this->handle_response(false, __('Invalid IP provided.', 'all-in-one-wp-security-and-firewall')); + } + $ip = sanitize_text_field($data['ip']); + $username = isset($data['username']) ? sanitize_user($data['username']) : ''; + + if (AIOWPSecurity_Utility_IP::get_user_ip_address() == $ip) { + return $this->handle_response(false, __('You cannot block your own IP address:', 'all-in-one-wp-security-and-firewall') . ' ' . $ip); + } + //Block single record + if (filter_var($ip, FILTER_VALIDATE_IP)) { + AIOWPSecurity_Utility::lock_IP($ip, '404', $username); + $message = __('The selected IP address is now temporarily blocked.', 'all-in-one-wp-security-and-firewall'); + } else { + $message = __('The selected entry is not a valid IP address.', 'all-in-one-wp-security-and-firewall'); + return $this->handle_response(false, $message); + } + break; + case 'blacklist': + if (!isset($data['ip'])) { + return $this->handle_response(false, __('Invalid IP provided.', 'all-in-one-wp-security-and-firewall')); + } + + $bl_ip_addresses = $aio_wp_security->configs->get_value('aiowps_banned_ip_addresses'); //get the currently saved blacklisted IPs + $ip_list_array = AIOWPSecurity_Utility_IP::create_ip_list_array_from_string_with_newline($bl_ip_addresses); + $ip = sanitize_text_field($data['ip']); + $ip_list_array[] = $ip; + $validated_ip_list_array = AIOWPSecurity_Utility_IP::validate_ip_list($ip_list_array, 'blacklist'); + + if (is_wp_error($validated_ip_list_array)) { + $response = nl2br($validated_ip_list_array->get_error_message()); + return $this->handle_response(false, $response); + } else { + $banned_ip_data = implode("\n", $validated_ip_list_array); + $aio_wp_security->configs->set_value('aiowps_enable_blacklisting', '1'); // Force blacklist feature to be enabled. + $aio_wp_security->configs->set_value('aiowps_banned_ip_addresses', $banned_ip_data); + $aio_wp_security->configs->save_config(); + + $aiowps_firewall_config->set_value('aiowps_blacklist_ips', $validated_ip_list_array); + $message = __('The selected IP addresses have been added to the blacklist and will be permanently blocked.', 'all-in-one-wp-security-and-firewall'); + } + break; + case 'unblock': + if (!isset($data['ip'])) { + return $this->handle_response(false, __('Invalid log event ID provided.', 'all-in-one-wp-security-and-firewall')); + } + + $ip_range = sanitize_text_field($data['ip']); + $lockout_table = AIOWPSEC_TBL_LOGIN_LOCKOUT; + + // get the latest data with that ip in the table that's locked and reason is 404 + $query = $wpdb->prepare("SELECT id FROM {$lockout_table} WHERE `released` > UNIX_TIMESTAMP() AND `lock_reason` = %s and failed_login_ip = %s ORDER BY id ASC LIMIT 1", '404', $ip_range); + $id = $wpdb->get_var($query); + + if (null === $id) { + return $this->handle_response(false, __('Invalid log event ID provided.', 'all-in-one-wp-security-and-firewall')); + } + + $result = $wpdb->query($wpdb->prepare("UPDATE $lockout_table SET `released` = UNIX_TIMESTAMP() WHERE `id` = %d", absint($id))); + + if (null != $result) { + $message = __('Access from the selected IP address has been unblocked.', 'all-in-one-wp-security-and-firewall'); + } else { + return $this->handle_response(false, __('The selected IP entry could not be unlocked', 'all-in-one-wp-security-and-firewall')); + } + break; + } + + return $this->handle_response(true, $message); + } + + /** + * Get the content for performing a cookie test. + * + * This method checks if the cookie test is successful or if the brute-force attack prevention feature is already enabled. + * If either condition is true, it returns an empty string. Otherwise, it displays a message prompting the user to perform + * a cookie test before enabling the feature, along with a button to initiate the test. + * + * @return string The HTML content for the cookie test section. + */ + private function get_perform_cookie_test_content() { + global $aio_wp_security; + $cookie_test_value = $aio_wp_security->configs->get_value('aiowps_cookie_test_success'); + + if ('1' == $cookie_test_value || '1' == $aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention')) { + return ''; + } else { + return $aio_wp_security->include_template('wp-admin/brute-force/partials/cookie-test-container.php', true); + } + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-comment-commands.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-comment-commands.php new file mode 100755 index 00000000..e2f65953 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-comment-commands.php @@ -0,0 +1,221 @@ + $aiowps_trash_spam_comments_after_days + ); + } + + $response['status'] = 'success'; + $response['message'] = __('The settings were successfully updated.', 'all-in-one-wp-security-and-firewall'); + $response['info'] = $info; + + // Commit the config settings + $this->save_settings($options); + AIOWPSecurity_Comment::trash_spam_comments(); + $response['badges'] = $this->get_features_id_and_html(array('detect-spambots')); + + return $response; + } + + /** + * Perform the saving of comment auto block spammers ip settings + * + * @param array $data - the request data contains the post data + * + * @return array + */ + public function perform_auto_block_spam_ip($data) { + $response = array( + 'status' => 'success', + 'values' => array(), + 'info' => array() + ); + + $enable_auto_block_ip = isset($data["aiowps_enable_autoblock_spam_ip"]) ? '1' : ''; + + $spam_ip_min_comments = sanitize_text_field($data['aiowps_spam_ip_min_comments_block']); + if (!is_numeric($spam_ip_min_comments)) { + $response['info'][] = __('You entered a non-numeric value for the "minimum number of spam comments" field; it has been set to the default value.', 'all-in-one-wp-security-and-firewall'); + $spam_ip_min_comments = '3';// Set it to the default value for this field + } elseif ((int) $spam_ip_min_comments <= 0 || empty($spam_ip_min_comments)) { + $response['info'][] = __('You must enter an integer greater than zero for the "minimum number of spam comments" field; it has been set to the default value.', 'all-in-one-wp-security-and-firewall'); + $spam_ip_min_comments = '3';// Set it to the default value for this field + } + + // Save all the form values to the options + $options = array( + 'aiowps_enable_autoblock_spam_ip' => $enable_auto_block_ip, + 'aiowps_spam_ip_min_comments_block' => absint($spam_ip_min_comments), + ); + + $this->save_settings($options); + $response['message'] = __('The settings were successfully updated.', 'all-in-one-wp-security-and-firewall'); + + $response['badges'] = $this->get_features_id_and_html(array('auto-block-spam-ips')); + $response['values']['aiowps_spam_ip_min_comments_block'] = absint($spam_ip_min_comments); + + return $response; + } + + /** + * Perform the ip spam comment search + * + * @param array $data - the request data contains the post data + * + * @return array + */ + public function perform_ip_spam_search($data) { + $response = array( + 'status' => 'success', + 'info' => array() + ); + + $min_comments_per_ip = sanitize_text_field($data['aiowps_spam_ip_min_comments']); + $error = ''; + + if (!is_numeric($min_comments_per_ip)) { + $error = __('You entered a non-numeric value for the minimum spam comments per IP field; it has been set to the default value.', 'all-in-one-wp-security-and-firewall'); + $min_comments_per_ip = '5'; // Set it to the default value for this field + } elseif ((int) $min_comments_per_ip <= 0 || empty($min_comments_per_ip)) { + $error = __('You must enter an integer greater than zero for the minimum spam comments per IP field; it has been set to the default value.', 'all-in-one-wp-security-and-firewall'); + $min_comments_per_ip = '5'; // Set it to the default value for this field + } + + $min_comments_per_ip = absint($min_comments_per_ip); + + // Save all the form values to the options + $this->save_settings(array( + 'aiowps_spam_ip_min_comments' => $min_comments_per_ip + )); + + if (!empty($error)) { + $response['message'] = $error; + } + + $response['values']['aiowps_spam_ip_min_comments'] = $min_comments_per_ip; + + return $response; + } + + /** + * Perform the action of blocking a spam IP address. + * + * This function takes an IP address as input, checks if it is valid and not the user's own IP, + * and then attempts to add it to the block list for spam. It returns the status and message of the operation. + * + * @param array $data The data containing the IP address to block. + * + * @return array The result of the block operation, including status, message, and updated blocked comments output. + */ + public function perform_block_spam_ip($data) { + + if (empty($data['ip'])) { + return array('status' => 'error', 'message' => __('Invalid IP address provided.', 'all-in-one-wp-security-and-firewall')); + } + + $ip = wp_strip_all_tags($data['ip']); + + if (AIOWPSecurity_Utility_IP::get_user_ip_address() == $ip) { + return array('status' => 'error', 'message' => __('You cannot block your own IP address:', 'all-in-one-wp-security-and-firewall') . ' ' . $ip); + } + + $result = AIOWPSecurity_Blocking::add_ip_to_block_list($ip, 'spam'); + + if ($result) { + $status = 'success'; + $message = __('The selected IP address is now permanently blocked.', 'all-in-one-wp-security-and-firewall'); + } else { + $status = 'error'; + $message = __('The selected IP address could not be blocked due to one of the following reasons:', 'all-in-one-wp-security-and-firewall'); + $message .= ' ' . __('either it has already been blocked, or your user account lacks sufficient permissions to perform IP blocking.', 'all-in-one-wp-security-and-firewall'); + } + + return array( + 'status' => $status, + 'message' => $message, + 'content' => array('aios-blocked-comments-output' => $this->get_blocked_comments_output()) + ); + } + + /** + * Retrieves the output for displaying blocked comments due to spam. + * + * This function queries the database to get IP addresses that are permanently blocked due to spam. + * It returns HTML output that displays the count of IPs blocked today and the all-time total count. + * + * @global object $aio_wp_security The global instance of the aio_wp_security class. + * @global object $wpdb The global instance of the WordPress database class. + * + * @return string HTML output for the blocked comments section. + */ + private function get_blocked_comments_output() { + global $aio_wp_security, $wpdb; + + $block_comments_output = ''; + $min_block_comments = $aio_wp_security->configs->get_value('aiowps_spam_ip_min_comments_block'); + + if (!empty($min_block_comments)) { + $now_date = (new DateTime('now', new DateTimeZone('UTC')))->format('Y-m-d'); + + $sql = $wpdb->prepare( + "SELECT COUNT(*) AS total_count, + SUM(CASE WHEN DATE(FROM_UNIXTIME(created)) = %s THEN 1 ELSE 0 END) AS todays_blocked_count FROM ".AIOWPSEC_TBL_PERM_BLOCK." WHERE block_reason = %s", + $now_date, + 'spam' + ); + + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore + $result = $wpdb->get_row($sql); + + $block_comments_output = '
'; + if (empty($result) || 0 == $result->total_count) { + $block_comments_output .= '

'.esc_html__('You currently have no IP addresses permanently blocked due to spam.', 'all-in-one-wp-security-and-firewall').'

'; + } else { + $todays_blocked_count = $result->todays_blocked_count; + $total_count = $result->total_count; + + $block_comments_output .= '

'.esc_html__('Spammer IPs added to permanent block list today:', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html($todays_blocked_count) . '

'; + $block_comments_output .= '

'.esc_html__('All time total:', 'all-in-one-wp-security-and-firewall'). ' ' . $total_count.'

'; + $block_comments_output .= '

'.esc_html__('View blocked IPs', 'all-in-one-wp-security-and-firewall').'

'; + } + $block_comments_output .= '
'; + } + + return $block_comments_output; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-file-scan-commands.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-file-scan-commands.php new file mode 100755 index 00000000..a53bf6fb --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-file-scan-commands.php @@ -0,0 +1,280 @@ +configs->get_value('aiowps_fcd_exclude_filetypes')) { + $reset_scan_data = true; + } + } + + if (!empty($data['aiowps_fcd_exclude_files'])) { + $files = sanitize_textarea_field(trim($data['aiowps_fcd_exclude_files'])); + // Get the currently saved config value and check if this has changed. If so do another scan to reset the scan data so it omits these files/dirs + if ($files != $aio_wp_security->configs->get_value('aiowps_fcd_exclude_files')) { + $reset_scan_data = true; + } + } + + // Explode by end-of-line character, then trim and filter empty lines + $email_list_array = array_filter(array_map('trim', explode("\n", $data['aiowps_fcd_scan_email_address'])), 'strlen'); + foreach ($email_list_array as $key => $value) { + $email_sane = sanitize_email($value); + if (!is_email($email_sane)) { + $errors[] = __('The following address was removed because it is not a valid email address:', 'all-in-one-wp-security-and-firewall') . ' ' . htmlspecialchars($value); + unset($email_list_array[$key]); + } + } + $email_address = implode("\n", $email_list_array); + if (!empty($errors)) { + $info[] = implode('
', $errors); + } + + // Save all the form values to the options + $options['aiowps_enable_automated_fcd_scan'] = isset($data["aiowps_enable_automated_fcd_scan"]) ? '1' : ''; + $options['aiowps_fcd_scan_frequency'] = absint($fcd_scan_frequency); + $options['aiowps_fcd_scan_interval'] = sanitize_text_field($data["aiowps_fcd_scan_interval"]); + $options['aiowps_fcd_exclude_filetypes'] = $file_types; + $options['aiowps_fcd_exclude_files'] = $files; + $options['aiowps_send_fcd_scan_email'] = isset($data["aiowps_send_fcd_scan_email"]) ? '1' : ''; + $options['aiowps_fcd_scan_email_address'] = $email_address; + $this->save_settings($options); + + $content['aios-file-change-info-box'] = ''; + // Let's check if backup interval was set to less than 24 hours + if (isset($data["aiowps_enable_automated_fcd_scan"]) && ($fcd_scan_frequency < 24) && 0 == $data["aiowps_fcd_scan_interval"]) { + $content['aios-file-change-info-box'] = '
'; + $content['aios-file-change-info-box'] .= '

' . __('You have configured your file change detection scan to occur at least once daily.', 'all-in-one-wp-security-and-firewall') . '

'; + $content['aios-file-change-info-box'] .= '

' . __('For most websites we recommended that you choose a less frequent schedule such as once every few days, once a week or once a month.', 'all-in-one-wp-security-and-firewall') . '

'; + $content['aios-file-change-info-box'] .= '

' . __('Choosing a less frequent schedule will also help reduce your server load.', 'all-in-one-wp-security-and-firewall') . '

'; + $content['aios-file-change-info-box'] .= '
'; + } + + if ($reset_scan_data) { + $aio_wp_security->scan_obj->execute_file_change_detection_scan(); + $new_scan_alert = __('New scan completed: The plugin has detected that you have made changes to the "File Types To Ignore" or "Files To Ignore" fields.', 'all-in-one-wp-security-and-firewall').' '.__('In order to ensure that future scan results are accurate, the old scan data has been refreshed.', 'all-in-one-wp-security-and-firewall'); + $info[] = $new_scan_alert; + } + + $next_fcd_scan_time = AIOWPSecurity_Scan::get_next_scheduled_scan(); + + if (false == $next_fcd_scan_time) { + $next_scheduled_scan = '' . esc_html__('Nothing is currently scheduled', 'all-in-one-wp-security-and-firewall') . ''; + } else { + $scan_time = AIOWPSecurity_Utility::convert_timestamp($next_fcd_scan_time, 'D, F j, Y H:i'); + $next_scheduled_scan = '' . esc_html($scan_time) . ''; + } + + $content['aiowps-next-files-scan-inner'] = $next_scheduled_scan; + $values = array('aiowps_fcd_scan_frequency' => absint($fcd_scan_frequency)); + $badges = array('scan-file-change-detection'); + + $args = array( + 'content' => $content, + 'values' => $values, + 'badges' => $badges, + 'info' => $info + ); + + return $this->handle_response(true, '', $args); + } + + /** + * Retrieves the last file scan data and returns the data to UDC. + * + * @param array $data The request data. + * + * @return array|string[]|WP_Error + */ + public function get_last_scan_data($data) { + global $aio_wp_security; + + if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) { + return new WP_Error(esc_html__('Sorry, you do not have enough privilege to execute the requested action.', 'all-in-one-wp-security-and-firewall')); + } + + if ($data['reset_change_detected']) { + $aio_wp_security->configs->set_value('aiowps_fcds_change_detected', false, true); + } + + $fcd_data = AIOWPSecurity_Scan::get_fcd_data(); + + $data = $fcd_data['last_scan_result']; + + foreach (array('files_added', 'files_removed', 'files_changed') as $key) { + /* Normalize missing or non-array buckets to an empty array and skip processing */ + if (!isset($data[$key]) || !is_array($data[$key])) { + $data[$key] = array(); + continue; + } + + /* Convert last_modified for each entry */ + foreach ($data[$key] as &$info) { + if (is_array($info) && array_key_exists('last_modified', $info) && is_numeric($info['last_modified'])) { + $info['last_modified'] = AIOWPSecurity_Utility::convert_timestamp($info['last_modified']); + } + } + + unset($info); + } + + $fcd_data['last_scan_result'] = $data; + + return $this->handle_response(true, false, array('extra_args' => $fcd_data)); + } + + /** + * Gets the last file scan result and returns the scan result HTML template + * + * @param array $data - the request data + * + * @return array + */ + public function get_last_scan_results($data) { + global $aio_wp_security; + + if ($data['reset_change_detected']) $aio_wp_security->configs->set_value('aiowps_fcds_change_detected', false, true); + + $fcd_data = AIOWPSecurity_Scan::get_fcd_data(); + + if (!$fcd_data || !isset($fcd_data['last_scan_result'])) { + // no fcd data found + $message = __('No previous scan data was found; either run a manual scan or schedule regular file scans', 'all-in-one-wp-security-and-firewall'); + return $this->handle_response(false, $message); + } + + $content = array('aiowps_previous_scan_wrapper' => $aio_wp_security->include_template('wp-admin/scanner/scan-result.php', true, array('fcd_data' => $fcd_data))); + + return $this->handle_response(true, false, array('content' => $content)); + } + + /** + * Performs a file scan and returns the scan result + * + * @return array + */ + public function perform_file_scan() { + global $aio_wp_security; + + $content = array(); + $extra_args = array(); + + $result = $aio_wp_security->scan_obj->execute_file_change_detection_scan(); + + if (false === $result) { + // error case + $message = __('There was an error during the file change detection scan.', 'all-in-one-wp-security-and-firewall') . ' ' . __('Please check the plugin debug logs.', 'all-in-one-wp-security-and-firewall'); + return $this->handle_response(false, $message); + } + + $aio_wp_security->configs->set_value('aiowps_last_scan_time', time(), true); + + // If this is first scan display special message + if (1 == $result['initial_scan']) { + $extra_args['result'] = __('This is your first file change detection scan.', 'all-in-one-wp-security-and-firewall').' '.__('The details from this scan will be used for future scans.', 'all-in-one-wp-security-and-firewall'). ' ' . __('View the file scan results', 'all-in-one-wp-security-and-firewall') . ''; + $content['aiowps-previous-files-scan-inner'] = '' . __('View last file scan results', 'all-in-one-wp-security-and-firewall') . ''; + } elseif (!$aio_wp_security->configs->get_value('aiowps_fcds_change_detected')) { + $extra_args['result'] = __('The scan is complete - There were no file changes detected.', 'all-in-one-wp-security-and-firewall'); + } elseif ($aio_wp_security->configs->get_value('aiowps_fcds_change_detected')) { + $extra_args['result'] = __('The scan has detected that there was a change in your website\'s files.', 'all-in-one-wp-security-and-firewall'). ' ' . __('View the file scan results', 'all-in-one-wp-security-and-firewall') . ''; + } + + $args = array( + 'extra_args' => $extra_args, + 'content' => $content + ); + + return $this->handle_response(true, false, $args); + } + + /** + * Render the legacy UDC Scanner. + * + * @return array + */ + public function get_scanner_contents() { + global $aio_wp_security; + + $GLOBALS['aiowps_feature_mgr'] = $this->get_feature_mgr_object(); + + $scanner_data = $this->get_scanner_data(); + + $content = $aio_wp_security->include_template('wp-admin/scanner/file-change-detect.php', true, $scanner_data); + + return array( + 'status' => 'success', + 'content' => $content, + ); + } + + /** + * Return file scanner data. + * + * @return array Array of option values, + */ + public function get_scanner_data() { + global $aio_wp_security; + + $fcd_data = AIOWPSecurity_Scan::get_fcd_data(); + $previous_scan = isset($fcd_data['last_scan_result']); + + $next_fcd_scan_time = AIOWPSecurity_Scan::get_next_scheduled_scan(); + + $aiowps_fcds_change_detected = $aio_wp_security->configs->get_value('aiowps_fcds_change_detected'); + $aiowps_enable_automated_fcd_scan = $aio_wp_security->configs->get_value('aiowps_enable_automated_fcd_scan'); + $aiowps_fcd_scan_frequency = $aio_wp_security->configs->get_value('aiowps_fcd_scan_frequency'); + $aiowps_fcd_scan_interval = $aio_wp_security->configs->get_value('aiowps_fcd_scan_interval'); + $aiowps_fcd_exclude_filetypes = $aio_wp_security->configs->get_value('aiowps_fcd_exclude_filetypes'); + $aiowps_fcd_exclude_files = $aio_wp_security->configs->get_value('aiowps_fcd_exclude_files'); + $aiowps_send_fcd_scan_email = $aio_wp_security->configs->get_value('aiowps_send_fcd_scan_email'); + $aiowps_fcd_scan_email_address = $aio_wp_security->configs->get_value('aiowps_fcd_scan_email_address'); + $aiowps_last_scan_time = $aio_wp_security->configs->get_value('aiowps_last_scan_time'); + + return array( + 'previous_scan' => $previous_scan, + 'next_fcd_scan_time' => false === $next_fcd_scan_time ? '' : AIOWPSecurity_Utility::convert_timestamp($next_fcd_scan_time, 'D, F j, Y H:i'), + 'aiowps_fcds_change_detected' => $aiowps_fcds_change_detected, + 'aiowps_enable_automated_fcd_scan' => $aiowps_enable_automated_fcd_scan, + 'aiowps_fcd_scan_frequency' => $aiowps_fcd_scan_frequency, + 'aiowps_fcd_scan_interval' => $aiowps_fcd_scan_interval, + 'aiowps_fcd_exclude_filetypes' => $aiowps_fcd_exclude_filetypes, + 'aiowps_fcd_exclude_files' => $aiowps_fcd_exclude_files, + 'aiowps_send_fcd_scan_email' => $aiowps_send_fcd_scan_email, + 'aiowps_fcd_scan_email_address' => $aiowps_fcd_scan_email_address, + 'aiowps_last_scan_time' => AIOWPSecurity_Utility::convert_timestamp($aiowps_last_scan_time, 'D, F j, Y H:i'), + ); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-files-commands.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-files-commands.php new file mode 100755 index 00000000..16dd18b1 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-files-commands.php @@ -0,0 +1,224 @@ + $aio_wp_security->include_template('wp-admin/filesystem-security/partials/file-permissions-table.php', true, array('files_dirs_to_check' => $files_dirs_to_check, 'file_utility' => new AIOWPSecurity_Utility_File()))); + $args = array( + 'content' => $content, + 'badges' => $badges, + ); + + return $this->handle_response($success, $message, $args); + } + + /** + * This function performs file protection settings + * + * @param array $data - the request data contains the settings + * + * @return array + */ + public function perform_file_protection_settings($data) { + global $aio_wp_security; + + $success = true; + $message = ''; + + $options = array(); + // Update settings for delete readme.html and wp-config-sample.php. + $options['aiowps_auto_delete_default_wp_files'] = isset($data['aiowps_auto_delete_default_wp_files']) ? '1' : ''; + + // Update settings for prevent hotlinking. + $options['aiowps_prevent_hotlinking'] = isset($data['aiowps_prevent_hotlinking']) ? '1' : ''; + + // Update settings for php file editing + $disable_file_editing = isset($data["aiowps_disable_file_editing"]) ? '1' : ''; + $disable_file_editing_status = $disable_file_editing ? AIOWPSecurity_Utility::disable_file_edits() : AIOWPSecurity_Utility::enable_file_edits(); + if ($disable_file_editing_status) { + // Save settings if no errors + $options['aiowps_disable_file_editing'] = $disable_file_editing; + } else { + $message = __('Disable PHP file editing failed: unable to modify or make a backup of the wp-config.php file.', 'all-in-one-wp-security-and-firewall'); + return $this->handle_response(false, $message); + } + + $this->save_settings($options); + + + if (AIOWPSecurity_Utility_Htaccess::write_to_htaccess() && '' !== $options['aiowps_prevent_hotlinking']) { + + // Now let's write the applicable rules to the .htaccess file + $res = AIOWPSecurity_Utility_Htaccess::write_to_htaccess(); + + if ($res) { + $message = __('The settings have been successfully updated', 'all-in-one-wp-security-and-firewall'); + } else { + $success = false; + $message = __('Could not write to the .htaccess file.', 'all-in-one-wp-security-and-firewall'); + + // revert options affected by .htaccess write fail + $options['aiowps_prevent_hotlinking'] = $aio_wp_security->configs->get_value('aiowps_prevent_hotlinking'); + $this->save_settings($options); + } + } + + $features = array( + "auto-delete-wp-files", + "prevent-hotlinking", + "filesystem-file-editing", + ); + + return $this->handle_response($success, $message, array('badges' => $features)); + } + + /** + * This function performs deleting default wp files + * + * @return array + */ + public function perform_delete_default_wp_files() { + $success = true; + $message = __('The files have been deleted successfully.', 'all-in-one-wp-security-and-firewall'); + + $result = AIOWPSecurity_Utility::delete_unneeded_default_files(); + + if (!empty($result['error'])) { + $success = false; + $message = sprintf(__('Failed to delete the %s file(s).', 'all-in-one-wp-security-and-firewall'), $result['error']) . '
' . __('Please try to delete them manually.', 'all-in-one-wp-security-and-firewall'); + } + + return $this->handle_response($success, $message, array('info' => $result['info'])); + } + + /** + * This function performs save copy protection settings + * + * @param array $data - the request data + * + * @return array + */ + public function perform_save_copy_protection($data) { + $this->save_settings(array('aiowps_copy_protection' => isset($data["aiowps_copy_protection"]) ? '1' : '')); + + return $this->handle_response(true, '', array('badges' => array('enable-copy-protection'))); + } + + /** + * This function performs save frame display prevent setting + * + * @param array $data - the request data + * + * @return array + */ + public function perform_save_frame_display_prevent($data) { + $this->save_settings(array('aiowps_prevent_site_display_inside_frame' => isset($data["aiowps_prevent_site_display_inside_frame"]) ? '1' : '')); + + return $this->handle_response(true, '', array('badges' => array('enable-frame-protection'))); + } + + /** + * This function performs host system logs + * + * @param array $data - the request data contains the lgos settings + * + * @return array + */ + public function perform_host_system_logs($data) { + + $content = array(); + $success = true; + $message = false; + + if (isset($data['aiowps_system_log_file'])) { + if ('' != $data['aiowps_system_log_file']) { + $sys_log_file = basename(sanitize_text_field($data['aiowps_system_log_file'])); + } else { + $sys_log_file = 'error_log'; + } + $this->save_settings(array('aiowps_system_log_file' => $sys_log_file)); + } + + $logResults = AIOWPSecurity_Utility_File::recursive_file_search($sys_log_file, 0, ABSPATH); + + if (empty($logResults) || '' == $logResults) { + $success = false; + $message = __('No system logs were found.', 'all-in-one-wp-security-and-firewall'); + } else { + $content['aios-host-system-logs-results'] = ''; + foreach ($logResults as $file) { + $content['aios-host-system-logs-results'] .= $this->display_system_logs_in_table($file); + } + } + + $values = array('aiowps_system_log_file' => $sys_log_file); + + $args = array( + 'content' => $content, + 'values' => $values + ); + + return $this->handle_response($success, $message, $args); + } + + /** + * Displays the last 50 entries of a system log file in a table format. + * + * This function reads the contents of the specified file and returns a + * rendered template displaying the last 50 entries of the log file. + * + * @param string $filepath The path to the log file to be read. + * + * @return string The rendered HTML template displaying the log entries. + */ + private function display_system_logs_in_table($filepath) { + global $aio_wp_security; + // Get contents of the error_log file + $last_50_entries = AIOWPSecurity_Utility_File::read_file_lines($filepath, -1, 50, true); + return $aio_wp_security->include_template('wp-admin/filesystem-security/filesystem-log-result.php', true, array('filepath' => $filepath, 'last_50_entries' => $last_50_entries)); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-firewall-commands.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-firewall-commands.php new file mode 100755 index 00000000..152f6ff6 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-firewall-commands.php @@ -0,0 +1,787 @@ +set_value('aiowps_enable_pingback_firewall', $enable_pingback); + $options['aiowps_disable_xmlrpc_pingback_methods'] = isset($data["aiowps_disable_xmlrpc_pingback_methods"]) ? '1' : ''; //this disables only pingback methods of xmlrpc but leaves other methods so that Jetpack and other apps will still work + $options['aiowps_disable_rss_and_atom_feeds'] = isset($data['aiowps_disable_rss_and_atom_feeds']) ? '1' : ''; + $aiowps_firewall_config->set_value('aiowps_forbid_proxy_comments', isset($data['aiowps_forbid_proxy_comments'])); + $aiowps_firewall_config->set_value('aiowps_deny_bad_query_strings', isset($data['aiowps_deny_bad_query_strings'])); + $aiowps_firewall_config->set_value('aiowps_advanced_char_string_filter', isset($data['aiowps_advanced_char_string_filter'])); + + $block_request_methods = array_map('strtolower', AIOS_Abstracted_Ids::get_firewall_block_request_methods()); + $current_request_methods_settings = $aiowps_firewall_config->get_value('aiowps_6g_block_request_methods'); + $current_other_settings = array( + $aiowps_firewall_config->get_value('aiowps_6g_block_query'), + $aiowps_firewall_config->get_value('aiowps_6g_block_request'), + $aiowps_firewall_config->get_value('aiowps_6g_block_referrers'), + $aiowps_firewall_config->get_value('aiowps_6g_block_agents'), + ); + + $are_methods_set = !empty($current_request_methods_settings); + $are_others_set = array_reduce($current_other_settings, function($carry, $item) { + return $carry || $item; + }); + + if (($are_methods_set || $are_others_set) && '1' !== $aio_wp_security->configs->get_value('aiowps_enable_6g_firewall')) { + $options['aiowps_enable_6g_firewall'] = '1'; + } + + if (isset($data['aiowps_enable_6g_firewall'])) { + $aiowps_6g_block_request_methods = array_filter(AIOS_Abstracted_Ids::get_firewall_block_request_methods(), function($block_request_method) { + return ('PUT' != $block_request_method); + }); + + if (false === $are_methods_set && false === $are_others_set) { + $aiowps_firewall_config->set_value('aiowps_6g_block_request_methods', $aiowps_6g_block_request_methods); + $aiowps_firewall_config->set_value('aiowps_6g_block_query', true); + $aiowps_firewall_config->set_value('aiowps_6g_block_request', true); + $aiowps_firewall_config->set_value('aiowps_6g_block_referrers', true); + $aiowps_firewall_config->set_value('aiowps_6g_block_agents', true); + } else { + $methods = array(); + + foreach ($block_request_methods as $block_request_method) { + if (isset($data['aiowps_block_request_method_'.$block_request_method])) { + $methods[] = strtoupper($block_request_method); + } + } + + $aiowps_firewall_config->set_value('aiowps_6g_block_request_methods', $methods); + $aiowps_firewall_config->set_value('aiowps_6g_block_query', isset($data['aiowps_block_query'])); + $aiowps_firewall_config->set_value('aiowps_6g_block_request', isset($data['aiowps_block_request'])); + $aiowps_firewall_config->set_value('aiowps_6g_block_referrers', isset($data['aiowps_block_refs'])); + $aiowps_firewall_config->set_value('aiowps_6g_block_agents', isset($data['aiowps_block_agents'])); + } + + $options['aiowps_enable_6g_firewall'] = '1'; + + //shows the success notice + } else { + AIOWPSecurity_Configure_Settings::turn_off_all_6g_firewall_configs(); + $options['aiowps_enable_6g_firewall'] = ''; + } + + $aiowps_firewall_config->set_value('aiowps_ban_post_blank_headers', isset($data['aiowps_ban_post_blank_headers'])); + + if (isset($data['aiowps_block_fake_googlebots'])) { + $validated_ip_list_array = AIOWPSecurity_Utility::get_googlebot_ip_ranges(); + + if (is_wp_error($validated_ip_list_array)) { + $info[] = __('The attempt to save the \'Block fake Googlebots\' settings failed, because it was not possible to validate the Googlebot IP addresses:', 'all-in-one-wp-security-and-firewall') . ' ' . $validated_ip_list_array->get_error_message(); + } else { + $aiowps_firewall_config->set_value('aiowps_block_fake_googlebots', true); + $aiowps_firewall_config->set_value('aiowps_googlebot_ip_ranges', $validated_ip_list_array); + } + } else { + $aiowps_firewall_config->set_value('aiowps_block_fake_googlebots', false); + } + $options['aiowps_disallow_unauthorized_rest_requests'] = isset($data["aiowps_disallow_unauthorized_rest_requests"]) ? '1' : ''; + + $aios_whitelisted_rest_routes = array(); + $route_namespaces = AIOWPSecurity_Utility::get_rest_namespaces(); + foreach ($route_namespaces as $route_namespace) { + if (isset($data['aios_whitelisted_rest_routes_'.str_replace('-', '_', $route_namespace)])) { + $aios_whitelisted_rest_routes[] = $route_namespace; + } + } + $options['aios_whitelisted_rest_routes'] = $aios_whitelisted_rest_routes; + + $aios_roles_disallowed_rest_requests = array(); + $user_roles = AIOWPSecurity_Utility_Permissions::get_user_roles(); + foreach ($user_roles as $id => $name) { + if (!isset($data['aios_allowed_roles_rest_requests_'.$id])) { + $aios_roles_disallowed_rest_requests[] = $id; + } + } + $options['aios_roles_disallowed_rest_requests'] = $aios_roles_disallowed_rest_requests; + + // Commit the config settings + $this->save_settings($options); + + $block_request_methods = array_map('strtolower', AIOS_Abstracted_Ids::get_firewall_block_request_methods()); + $methods = $aiowps_firewall_config->get_value('aiowps_6g_block_request_methods'); + if (empty($methods)) { + $methods = array(); + } + + $blocked_query = (bool) $aiowps_firewall_config->get_value('aiowps_6g_block_query'); + $blocked_request = (bool) $aiowps_firewall_config->get_value('aiowps_6g_block_request'); + $blocked_referrers = (bool) $aiowps_firewall_config->get_value('aiowps_6g_block_referrers'); + $blocked_agents = (bool) $aiowps_firewall_config->get_value('aiowps_6g_block_agents'); + $content = array('aios-6g-firewall-settings-container .aios-advanced-options-panel' => $aio_wp_security->include_template('wp-admin/firewall/partials/advanced-settings-6g.php', true, compact('methods', 'blocked_query', 'blocked_request', 'blocked_referrers', 'blocked_agents', 'block_request_methods'))); + + $features = array( + 'firewall-pingback-rules', + 'firewall-disable-rss-and-atom', + 'firewall-forbid-proxy-comments', + 'firewall-deny-bad-queries', + 'firewall-advanced-character-string-filter', + 'firewall-enable-6g', + 'firewall-block-fake-googlebots', + 'firewall-ban-post-blank-headers', + 'disallow-unauthorised-requests', + ); + + $args = array( + 'badges' => $features, + 'content' => $content, + 'info' => $info, + 'extra_args' => array('xmlprc_warning' => $enable_pingback ? $aio_wp_security->include_template('wp-admin/firewall/partials/xmlrpc-warning-notice.php', true) : '') + ); + + return $this->handle_response(true, '', $args); + } + + /** + * Perform saving .htaccess firewall settings + * + * @param array $data - the request data contains the firewall settings + * + * @return array - containing a status and message + */ + public function perform_htaccess_firewall_settings($data) { + global $aio_wp_security; + + + $options = array(); + $info = array(); + $message = ''; + $success = true; + + // Max file upload size in basic rules + $upload_size = absint($data['aiowps_max_file_upload_size']); + + $max_allowed = apply_filters('aiowps_max_allowed_upload_config', 250); // Set a filterable limit of 250MB + $max_allowed = absint($max_allowed); + + if ($upload_size > $max_allowed) { + $upload_size = $max_allowed; + } elseif (empty($upload_size) || 0 > $upload_size) { + $upload_size = AIOS_FIREWALL_MAX_FILE_UPLOAD_LIMIT_MB; + $info[] = __('Max file upload limit was set to default value, because you entered a negative or zero value'); + } + + // Store the current value in case the .htaccess write operation fails and we need to revert it + $original_options = array( + 'aiowps_enable_basic_firewall' => $aio_wp_security->configs->get_value("aiowps_enable_basic_firewall"), + 'aiowps_max_file_upload_size' => $aio_wp_security->configs->get_value('aiowps_max_file_upload_size'), + 'aiowps_block_debug_log_file_access' => $aio_wp_security->configs->get_value("aiowps_block_debug_log_file_access"), + 'aiowps_disable_index_views' => $aio_wp_security->configs->get_value('aiowps_disable_index_views'), + ); + + + // Save settings + $options['aiowps_enable_basic_firewall'] = isset($data["aiowps_enable_basic_firewall"]) ? '1' : ''; + $options['aiowps_max_file_upload_size'] = $upload_size; + $options['aiowps_block_debug_log_file_access'] = isset($data["aiowps_block_debug_log_file_access"]) ? '1' : ''; + $options['aiowps_disable_index_views'] = isset($data['aiowps_disable_index_views']) ? '1' : ''; + + // Commit the config settings + $this->save_settings($options); + + //Now let's write the applicable rules to the .htaccess file + $res = AIOWPSecurity_Utility_Htaccess::write_to_htaccess(); + + if (!$res) { + $success = false; + $message = __('Could not write to the .htaccess file', 'all-in-one-wp-security-and-firewall'); + + $this->save_settings($original_options); + } + + $features = array( + 'firewall-basic-rules', + 'firewall-block-debug-file-access', + 'firewall-disable-index-views', + ); + + $values = array('aiowps_max_file_upload_size' => $upload_size); + + $args = array( + 'badges' => $features, + 'info' => $info, + 'values' => $values + ); + + return $this->handle_response($success, $message, $args); + } + + /** + * Save and update the 5G firewall settings, and conditionally update the .htaccess file if needed. + * + * This function handles the saving of the 5G firewall settings based on user input. It checks if + * the 5G firewall setting has been modified and writes the applicable rules to the .htaccess file + * if necessary. In case of failure to write to the .htaccess file, it returns an error message. + * + * @param array $data The data array containing the 5G firewall setting. + * + * @global object $aio_wp_security The global instance of the All-In-One WP Security & Firewall plugin. + * + * @return array An array containing the status ('success' or 'error') and a message indicating + * the result of the operation. + */ + public function perform_save_5g_settings($data) { + global $aio_wp_security; + + $response = array( + 'status' => 'success', + 'message' => __('The settings were successfully updated.', 'all-in-one-wp-security-and-firewall') + ); + + $options = array(); + + // If the user has changed the 5G firewall checkbox settings, then there is a need to write htaccess rules again. + $is_5G_firewall_option_changed = ((isset($data['aiowps_enable_5g_firewall']) && '1' != $aio_wp_security->configs->get_value('aiowps_enable_5g_firewall')) || (!isset($data['aiowps_enable_5g_firewall']) && '1' == $aio_wp_security->configs->get_value('aiowps_enable_5g_firewall'))); + + // Save settings + $options['aiowps_enable_5g_firewall'] = isset($data['aiowps_enable_5g_firewall']) ? '1' : ''; + $this->save_settings($options); + + $res = true; + + if ($is_5G_firewall_option_changed) { + $res = AIOWPSecurity_Utility_Htaccess::write_to_htaccess(); // let's write the applicable rules to the .htaccess file + } + + if (!$res) { + $response['status'] = 'error'; + $response['message'] = __('Could not write to the .htaccess file for the 5G firewall settings, please check the file permissions.', 'all-in-one-wp-security-and-firewall'); + // revert settings + $options['aiowps_enable_5g_firewall'] = ''; + $this->save_settings($options); + } + + return $response; + } + + /** + * Perform saving blacklist settings + * + * @param array $data - the request data contains blacklist settings + * + * @return array - containing a status, message and feature badge html + */ + public function perform_save_blacklist_settings($data) { + global $aio_wp_security; + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + + $options = array(); + $message = ''; + $success = true; + + $result = 1; + $aiowps_enable_blacklisting = isset($data["aiowps_enable_blacklisting"]) ? '1' : ''; + + if (!empty($data['aiowps_banned_ip_addresses'])) { + $ip_addresses = sanitize_textarea_field(stripslashes($data['aiowps_banned_ip_addresses'])); + $ip_list_array = AIOWPSecurity_Utility_IP::create_ip_list_array_from_string_with_newline($ip_addresses); + $validated_ip_list_array = AIOWPSecurity_Utility_IP::validate_ip_list($ip_list_array, 'blacklist'); + if (is_wp_error($validated_ip_list_array)) { + $result = -1; + $success = false; + $message = nl2br($validated_ip_list_array->get_error_message()); + } else { + $banned_ip_addresses_list = preg_split('/\R/', $aio_wp_security->configs->get_value('aiowps_banned_ip_addresses')); // Historical settings where the separator may have depended on PHP_EOL. + if ($banned_ip_addresses_list !== $validated_ip_list_array) { + $banned_ip_data = implode("\n", $validated_ip_list_array); + $options['aiowps_banned_ip_addresses'] = $banned_ip_data; + $aiowps_firewall_config->set_value('aiowps_blacklist_ips', $validated_ip_list_array); + } + $data['aiowps_banned_ip_addresses'] = ''; // Clear the post variable for the banned address list. + } + } else { + $options['aiowps_banned_ip_addresses'] = ''; // Clear the IP address config value + $aiowps_firewall_config->set_value('aiowps_blacklist_ips', array()); + } + + if (!empty($data['aiowps_banned_user_agents'])) { + $this->validate_user_agent_list(stripslashes($data['aiowps_banned_user_agents'])); + } else { + // Clear the user agent list + $options['aiowps_banned_user_agents'] = ''; + $aiowps_firewall_config->set_value('aiowps_blacklist_user_agents', array()); + } + + if (1 == $result) { + $aio_wp_security->configs->set_value('aiowps_enable_blacklisting', $aiowps_enable_blacklisting, true); + if ('1' == $aio_wp_security->configs->get_value('aiowps_is_ip_blacklist_settings_notice_on_upgrade')) { + $aio_wp_security->configs->delete_value('aiowps_is_ip_blacklist_settings_notice_on_upgrade'); + } + } + + $this->save_settings($options); + + $args = array( + 'badges' => array("blacklist-manager-ip-user-agent-blacklisting") + ); + + return $this->handle_response($success, $message, $args); + } + + /** + * The AJAX function for storing ips in firewall allowlist + * + * @param array $data - the request data contains data to updated + * + * @return array - containing a status and message + */ + public function perform_firewall_allowlist($data) { + $aiowps_firewall_allow_list = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::ALLOW_LIST); + + $message = ''; + $success = true; + $allowlist = $data['aios_firewall_allowlist']; + + if (empty($allowlist)) { + $aiowps_firewall_allow_list::add_ips(''); + return $this->handle_response(true, ''); + } + + $ips = sanitize_textarea_field(wp_unslash($allowlist)); + $ips = AIOWPSecurity_Utility_IP::create_ip_list_array_from_string_with_newline($ips); + $validated_ip_list_array = AIOWPSecurity_Utility_IP::validate_ip_list($ips, 'firewall_allowlist'); + + if (is_wp_error($validated_ip_list_array)) { + $success = false; + $message = nl2br($validated_ip_list_array->get_error_message()); + } else { + $aiowps_firewall_allow_list::add_ips($validated_ip_list_array); + } + + return $this->handle_response($success, $message); + } + + /** + * The AJAX function for saving PHP firewall and block and allowlists in UDC. + * + * @param array $data The data send from UDC. + * + * @return array|WP_Error + */ + public function perform_save_firewall($data) { + if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) { + return new WP_Error(esc_html__('Sorry, you do not have enough privilege to execute the requested action.', 'all-in-one-wp-security-and-firewall')); + } + + $response = $this->perform_firewall_allowlist($data); + if ('error' === $response['status']) { + return $response; + } + + $response = $this->perform_save_blacklist_settings($data); + if ('error' === $response['status']) { + return $response; + } + + return $this->perform_php_firewall_settings($data); + } + + /** + * Perform the setup process for the firewall. + * + * This function handles the setup form for the firewall and renders notices accordingly. + * + * @return array An array containing the content and message for the response. + */ + public function perform_setup_firewall() { + global $aio_wp_security; + + $firewall_setup = AIOWPSecurity_Firewall_Setup_Notice::get_instance(); + $content = array('aiowps-firewall-status-container' => $aio_wp_security->include_template('wp-admin/firewall/partials/firewall-set-up-button.php', true)); + + $firewall_setup->do_setup(); + ob_start(); + $firewall_setup->render_notices(); + $result = ob_get_clean(); + + + $args = array( + 'content' => $content, + 'extra_args' => array('info_box' => $result) + ); + + $message = false; + + if (AIOWPSecurity_Utility_Firewall::is_firewall_setup()) { + $content['aiowps-firewall-status-container'] = $aio_wp_security->include_template('wp-admin/firewall/partials/firewall-downgrade-button.php', true); + $message = __('Firewall has been setup successfully.', 'all-in-one-wp-security-and-firewall'); + $args['content'] = $content; + } + + return $this->handle_response(AIOWPSecurity_Utility_Firewall::is_firewall_setup(), $message, $args); + } + + /** + * Perform the downgrade process for the firewall. + * + * This function removes the firewall and returns a response indicating success. + * + * @return array An array containing the status, content, and message for the response. + */ + public function perform_downgrade_firewall() { + global $aio_wp_security; + + AIOWPSecurity_Utility_Firewall::remove_firewall(); + + $message = AIOWPSecurity_Utility_Firewall::is_firewall_setup() ? __('Something went wrong please try again later.', 'all-in-one-wp-security-and-firewall') : __('Firewall has been downgraded successfully.', 'all-in-one-wp-security-and-firewall'); + $success = true; + $downgrade_button = $aio_wp_security->include_template('wp-admin/firewall/partials/firewall-set-up-button.php', true); + $extra_args = array(); + + if (AIOWPSecurity_Utility_Firewall::is_firewall_setup()) { + $success = false; + $downgrade_button = $aio_wp_security->include_template('wp-admin/firewall/partials/firewall-downgrade-button.php', true); + } else { + $extra_args['info_box'] = $aio_wp_security->include_template('notices/firewall-setup-notice.php', true, array('show_dismiss' => false)); + } + + $args = array( + 'content' => array('aiowps-firewall-status-container' => $downgrade_button), + 'extra_args' => $extra_args + ); + + return $this->handle_response($success, $message, $args); + } + + /** + * Validates posted user agent list and set, save as config. + * + * @param string $banned_user_agents - List of banned user agents + * + * @return void + */ + private function validate_user_agent_list($banned_user_agents) { + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + $submitted_agents = AIOWPSecurity_Utility::splitby_newline_trim_filter_empty($banned_user_agents); + $agents = array_unique( + array_filter( + array_map( + 'sanitize_text_field', + $submitted_agents + ), + 'strlen' + ) + ); + $aiowps_firewall_config->set_value('aiowps_blacklist_user_agents', $agents); + $this->save_settings(array( + 'aiowps_banned_user_agents' => implode("\n", $agents) + )); + } + + /** + * This function performs save upgrade unsafe http calls settings. + * + * @param array $data - The request data. + * + * @return array + */ + public function perform_save_upgrade_unsafe_http_calls_settings($data) { + $upgrade_unsafe_http_calls_url_exceptions = sanitize_textarea_field(wp_unslash($data['aiowps_upgrade_unsafe_http_calls_url_exceptions'])); + + $errors = ''; + + if (!empty($upgrade_unsafe_http_calls_url_exceptions)) { + foreach (preg_split('/\R/', $upgrade_unsafe_http_calls_url_exceptions) as $url) { + $url = sanitize_url($url); + + if (empty($url)) { + continue; + } + + if (0 === strpos($url, '#')) { + continue; + } + + $parsed_url = parse_url($url); // phpcs:ignore WordPress.WP.AlternativeFunctions.parse_url_parse_url -- Using the same function as WordPress in order to not preclude URLs that would be allowed by WordPress. + + if (empty($parsed_url['scheme'])) { // The same weak sanity check used by the WordPress wp_remote_* functions. + /* translators: %s URL entered by user. */ + $errors .= "\n" . sprintf(__('%s is not a valid url.', 'all-in-one-wp-security-and-firewall'), $url); + continue; + } + } + } + + if (!empty($errors)) { + return $this->handle_response(false, nl2br(trim($errors)), array('badges' => array('upgrade-unsafe-http-calls'))); + } + + $this->save_settings(array( + 'aiowps_upgrade_unsafe_http_calls' => isset($data['aiowps_upgrade_unsafe_http_calls']) ? '1' : '', + 'aiowps_upgrade_unsafe_http_calls_url_exceptions' => $upgrade_unsafe_http_calls_url_exceptions + )); + + return $this->handle_response(true, '', array('badges' => array('upgrade-unsafe-http-calls'))); + } + + /** + * Render the PHP firewall rules for the legacy UDC theme. + * + * @return array + */ + public function get_php_firewall_contents() { + global $aio_wp_security; + + $GLOBALS['aiowps_feature_mgr'] = $this->get_feature_mgr_object(); + $php_firewall_data = $this->get_php_firewall_data(); + + $content = $aio_wp_security->include_template('/wp-admin/firewall/php-firewall-rules.php', true, compact('php_firewall_data')); + + return array( + 'status' => 'success', + 'content' => $php_firewall_data['no_firewall'] . $content, + ); + } + + /** + * Render the .htaccess firewall rules for the legacy UDC theme. + * + * @return array + */ + public function get_htaccess_contents() { + global $aio_wp_security; + + $GLOBALS['aiowps_feature_mgr'] = $this->get_feature_mgr_object(); + + $htaccess_rules_data = $this->get_htaccess_rules_data(); + + $content = $aio_wp_security->include_template('/wp-admin/firewall/htaccess-firewall-rules.php', true, compact('htaccess_rules_data')); + + return array( + 'status' => 'success', + 'content' => $content, + ); + } + + /** + * Render the Block & Allow Lists for the legacy UDC theme. + * + * @return array + */ + public function get_block_allow_lists_contents() { + global $aio_wp_security; + + /* Needed for submit_button() */ + require_once(ABSPATH . 'wp-admin/includes/template.php'); + + $GLOBALS['aiowps_feature_mgr'] = $this->get_feature_mgr_object(); + + $block_allowlist_data = $this->get_block_allow_lists_data(); + + $content = $aio_wp_security->include_template('wp-admin/firewall/block-and-allow-lists.php', true, $block_allowlist_data); + + return array( + 'status' => 'success', + 'content' => $content, + ); + } + + /** + * Render the Advanced Settings for the legacy UDC theme. + * + * @return array + */ + public function get_advanced_settings_contents() { + global $aio_wp_security; + + $GLOBALS['aiowps_feature_mgr'] = $this->get_feature_mgr_object(); + + $advanced_settings_data = $this->get_firewall_advanced_settings_data(); + + $content = $aio_wp_security->include_template('wp-admin/firewall/advanced-settings.php', true, compact('advanced_settings_data')); + + return array( + 'status' => 'success', + 'content' => $content, + ); + } + + /** + * Return data for the advanced firewall. + * + * @return array + */ + public function get_firewall_advanced_settings_data() { + global $aio_wp_security; + + $aiowps_upgrade_unsafe_http_calls = $aio_wp_security->configs->get_value('aiowps_upgrade_unsafe_http_calls'); + $aiowps_upgrade_unsafe_http_calls_url_exceptions = $aio_wp_security->configs->get_value('aiowps_upgrade_unsafe_http_calls_url_exceptions'); + + return array( + 'aiowps_upgrade_unsafe_http_calls' => $aiowps_upgrade_unsafe_http_calls, + 'aiowps_upgrade_unsafe_http_calls_url_exceptions' => $aiowps_upgrade_unsafe_http_calls_url_exceptions, + ); + } + + + /** + * Return data for the allow & block lists. + * + * @return array + */ + public function get_block_allow_lists_data() { + global $aio_wp_security; + + $aiowps_enable_blacklisting = $aio_wp_security->configs->get_value('aiowps_enable_blacklisting'); + $aiowps_banned_ip_addresses = $aio_wp_security->configs->get_value('aiowps_banned_ip_addresses'); + $aiowps_banned_user_agents = $aio_wp_security->configs->get_value('aiowps_banned_user_agents'); + + $aiowps_firewall_allow_list = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::ALLOW_LIST); + $allowlist = $aiowps_firewall_allow_list::get_ips(); + + return array( + 'aiowps_enable_blacklisting' => $aiowps_enable_blacklisting, + 'aiowps_banned_ip_addresses' => $aiowps_banned_ip_addresses, + 'aiowps_banned_user_agents' => $aiowps_banned_user_agents, + 'allowlist' => $allowlist, + ); + } + + /** + * Return data for the .htaccess rules. + * + * @return array + */ + public function get_htaccess_rules_data() { + global $aio_wp_security; + + $aiowps_enable_basic_firewall = $aio_wp_security->configs->get_value('aiowps_enable_basic_firewall'); + $aiowps_max_file_upload_size = $aio_wp_security->configs->get_value('aiowps_max_file_upload_size'); + $aiowps_block_debug_log_file_access = $aio_wp_security->configs->get_value('aiowps_block_debug_log_file_access'); + $aiowps_disable_index_views = $aio_wp_security->configs->get_value('aiowps_disable_index_views'); + + return array( + 'aiowps_enable_basic_firewall' => $aiowps_enable_basic_firewall, + 'aiowps_max_file_upload_size' => $aiowps_max_file_upload_size, + 'aiowps_block_debug_log_file_access' => $aiowps_block_debug_log_file_access, + 'aiowps_disable_index_views' => $aiowps_disable_index_views, + ); + } + + /** + * Return data for the PHP firewall. + * + * @return array + */ + public function get_php_firewall_data() { + global $aio_wp_security, $aiowps_firewall_config, $aiowps_feature_mgr; + + $is_udc_request = AIOS_Helper::is_updraft_central_request(); + + $block_request_methods = array_map('strtolower', AIOS_Abstracted_Ids::get_firewall_block_request_methods()); + + $no_firewall_notice = ''; + $user_roles = array(); + + // Load required data from config + if (!empty($aiowps_firewall_config)) { + // firewall config is available + $methods = $aiowps_firewall_config->get_value('aiowps_6g_block_request_methods'); + if (empty($methods)) { + $methods = array(); + } + + $blocked_query = (bool) $aiowps_firewall_config->get_value('aiowps_6g_block_query'); + $blocked_request = (bool) $aiowps_firewall_config->get_value('aiowps_6g_block_request'); + $blocked_referrers = (bool) $aiowps_firewall_config->get_value('aiowps_6g_block_referrers'); + $blocked_agents = (bool) $aiowps_firewall_config->get_value('aiowps_6g_block_agents'); + + if (empty($methods) && (!$blocked_query && !$blocked_request && !$blocked_referrers && !$blocked_agents) && '1' == $aio_wp_security->configs->get_value('aiowps_enable_6g_firewall')) { + $aio_wp_security->configs->set_value('aiowps_enable_6g_firewall', ''); + $aio_wp_security->configs->save_config(); + $aiowps_feature_mgr->check_feature_status_and_recalculate_points(); + } + + } else { + if ($is_udc_request) { + ob_start(); + } + + ?> +
+

+

+
+

+

+

+
+ configs->get_value('aiowps_enable_6g_firewall'); + $advanced_options_disabled = '1' != $aiowps_enable_6g_firewall; + + $settings = array_merge(array('methods' => $methods), compact('aiowps_enable_6g_firewall', 'blocked_query', 'blocked_request', 'blocked_referrers', 'blocked_agents', 'block_request_methods', 'aiowps_firewall_config', 'advanced_options_disabled')); + + $aiowps_enable_pingback_firewall = $aiowps_firewall_config->get_value('aiowps_enable_pingback_firewall'); + $aiowps_disable_xmlrpc_pingback_methods = $aio_wp_security->configs->get_value('aiowps_disable_xmlrpc_pingback_methods'); + $aiowps_disable_rss_and_atom_feeds = $aio_wp_security->configs->get_value('aiowps_disable_rss_and_atom_feeds'); + $aiowps_forbid_proxy_comments = $aiowps_firewall_config->get_value('aiowps_forbid_proxy_comments'); + $aiowps_deny_bad_query_strings = $aiowps_firewall_config->get_value('aiowps_deny_bad_query_strings'); + $aiowps_advanced_char_string_filter = $aiowps_firewall_config->get_value('aiowps_advanced_char_string_filter'); + + $aiowps_disallow_unauthorized_rest_requests = $aio_wp_security->configs->get_value('aiowps_disallow_unauthorized_rest_requests'); + $aios_roles_disallowed_rest_requests = $aio_wp_security->configs->get_value('aios_roles_disallowed_rest_requests'); + $aios_whitelisted_rest_routes = $aio_wp_security->configs->get_value('aios_whitelisted_rest_routes'); + $aiowps_block_fake_googlebots = $aiowps_firewall_config->get_value('aiowps_block_fake_googlebots'); + $aiowps_ban_post_blank_headers = $aiowps_firewall_config->get_value('aiowps_ban_post_blank_headers'); + + $wp_user_roles = AIOWPSecurity_Utility_Permissions::get_user_roles(); + foreach ($wp_user_roles as $role => $role_name) { + $user_roles[] = $role; + } + + + return array( + 'aiowps_enable_pingback_firewall' => $aiowps_enable_pingback_firewall, + 'aiowps_disable_xmlrpc_pingback_methods' => $aiowps_disable_xmlrpc_pingback_methods, + 'aiowps_disable_rss_and_atom_feeds' => $aiowps_disable_rss_and_atom_feeds, + 'aiowps_forbid_proxy_comments' => $aiowps_forbid_proxy_comments, + 'aiowps_deny_bad_query_strings' => $aiowps_deny_bad_query_strings, + 'aiowps_advanced_char_string_filter' => $aiowps_advanced_char_string_filter, + 'aiowps_disallow_unauthorized_rest_requests' => $aiowps_disallow_unauthorized_rest_requests, + 'aios_roles_disallowed_rest_requests' => $aios_roles_disallowed_rest_requests, + 'aios_whitelisted_rest_routes' => $aios_whitelisted_rest_routes, + 'user_roles' => $user_roles, + 'aiowps_block_fake_googlebots' => $aiowps_block_fake_googlebots, + 'aiowps_ban_post_blank_headers' => $aiowps_ban_post_blank_headers, + 'ng_settings' => $settings, + 'no_firewall' => $no_firewall_notice, + ); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-ip-commands.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-ip-commands.php new file mode 100755 index 00000000..5cfc124f --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-ip-commands.php @@ -0,0 +1,133 @@ +handle_response(false, __('No IP provided.', 'all-in-one-wp-security-and-firewall')); + } + + if (!filter_var($data['ip'], FILTER_VALIDATE_IP)) { + return $this->handle_response(false, __('Invalid IP provided.', 'all-in-one-wp-security-and-firewall')); + } + + if (!AIOWPSecurity_Utility::unlock_ip($data['ip'])) { + return $this->handle_response(false, __('Failed to unlock the selected IP address.', 'all-in-one-wp-security-and-firewall')); + } else { + return $this->handle_response(true, __('The selected IP address was unlocked successfully.', 'all-in-one-wp-security-and-firewall')); + } + } + + /** + * Unblacklists an IP. + * + * @param array $data Contains the IP address to be unblacklisted. + * + * @return array + */ + public function unblacklist_ip($data) { + + if (!isset($data['ip'])) { + return $this->handle_response(false, __('No IP provided.', 'all-in-one-wp-security-and-firewall')); + } + + if (!filter_var($data['ip'], FILTER_VALIDATE_IP)) { + return $this->handle_response(false, __('Invalid IP provided.', 'all-in-one-wp-security-and-firewall')); + } + + if (!AIOWPSecurity_Utility::unblacklist_ip($data['ip'])) { + return $this->handle_response(false, __('Failed to unblacklist the selected IP address.', 'all-in-one-wp-security-and-firewall')); + } else { + return $this->handle_response(true, __('The selected IP address was unblacklisted successfully.', 'all-in-one-wp-security-and-firewall')); + } + } + + /** + * Unblocks an IP by permanent block record ID. + * + * @param array $data Contains the ID of the entry in the AIOWPSEC_TBL_PERM_BLOCK table. + * + * @return array + */ + public function blocked_ip_list_unblock_ip($data) { + + if (!isset($data['id'])) { + return $this->handle_response(false, __('Invalid blocked IP ID provided.', 'all-in-one-wp-security-and-firewall')); + } + + include_once AIO_WP_SECURITY_PATH . '/admin/wp-security-list-permanent-blocked-ip.php'; // For rendering the AIOWPSecurity_List_Table + $blocked_ip_list = new AIOWPSecurity_List_Blocked_IP(); // For rendering the AIOWPSecurity_List_Table + $result = $blocked_ip_list->unblock_ip_address($data['id']); + + if (false === $result) { + $message = __('Failed to unblock and delete the selected record(s).', 'all-in-one-wp-security-and-firewall'); + } else { + $message = __('Successfully unblocked and deleted the selected record(s).', 'all-in-one-wp-security-and-firewall'); + } + return $this->handle_response(true, $message); + } + + /** + * Locks an IP. + * + * @param array $data Contains the IP address to be locked. + * + * @return array + */ + public function lock_ip($data) { + + if (!isset($data['ip'])) { + return $this->handle_response(false, __('No IP provided.', 'all-in-one-wp-security-and-firewall')); + } + + if (!filter_var($data['ip'], FILTER_VALIDATE_IP)) { + return $this->handle_response(false, __('Invalid IP provided.', 'all-in-one-wp-security-and-firewall')); + } + + if (!isset($data['lock_reason'])) { + return $this->handle_response(false, __('No lockout reason provided.', 'all-in-one-wp-security-and-firewall')); + } + + AIOWPSecurity_Utility::lock_ip($data['ip'], $data['lock_reason']); + + return $this->handle_response(true, __('The selected IP address is now temporarily locked.', 'all-in-one-wp-security-and-firewall')); + } + + /** + * Blacklists an IP. + * + * @param array $data Contains the IP address to be blacklisted. + * + * @return array + */ + public function blacklist_ip($data) { + + if (!isset($data['ip'])) { + return $this->handle_response(false, __('No IP provided.', 'all-in-one-wp-security-and-firewall')); + } + + if (!filter_var($data['ip'], FILTER_VALIDATE_IP)) { + return $this->handle_response(false, __('Invalid IP provided.', 'all-in-one-wp-security-and-firewall')); + } + + $result = AIOWPSecurity_Utility::blacklist_ip($data['ip']); + + if (is_wp_error($result)) { + return $this->handle_response(false, nl2br($result->get_error_message())); + } else { + return $this->handle_response(true, __('The selected IP address has been added to the blacklist.', 'all-in-one-wp-security-and-firewall')); + } + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-log-commands.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-log-commands.php new file mode 100755 index 00000000..f527439d --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-log-commands.php @@ -0,0 +1,345 @@ +handle_response(false, AIOWPSecurity_Admin_Menu::show_msg_error_st(__('No audit log ID provided.', 'all-in-one-wp-security-and-firewall'), true)); + } + + include_once AIO_WP_SECURITY_PATH.'/admin/wp-security-list-audit.php'; + $audit_log_list = new AIOWPSecurity_List_Audit_Log(); + + return $this->handle_response(true, $audit_log_list->delete_audit_event_records($data['id'])); + } + + /** + * Deletes an IP lockout record. + * + * @param array $data Contains the ID of the entry in the AIOWPSEC_TBL_LOGIN_LOCKOUT table. + * + * @return array + */ + public function delete_locked_ip_record($data) { + + if (!isset($data['id'])) { + return $this->handle_response(false, AIOWPSecurity_Admin_Menu::show_msg_error_st(__('No locked IP record ID provided.', 'all-in-one-wp-security-and-firewall'), true)); + } + + include_once AIO_WP_SECURITY_PATH . '/admin/wp-security-list-locked-ip.php'; + + $locked_ip_list = new AIOWPSecurity_List_Locked_IP(); + $result = $locked_ip_list->delete_lockout_records($data['id']); + return $this->handle_response(true, $result); + } + + /** + * Clear debug logs + * + * @return array + */ + public function clear_debug_logs() { + global $aio_wp_security; + + $ret = $aio_wp_security->debug_logger->clear_logs(); + + if (is_wp_error($ret)) { + return $this->handle_response(false, AIOWPSecurity_Admin_Menu::show_msg_error_st(esc_html($ret->get_error_message()).'

'.esc_html($ret->get_error_data()).'

', true)); + } else { + return $this->handle_response(true, AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The debug logs have been cleared.', 'all-in-one-wp-security-and-firewall'), true)); + } + } + + /** + * Renders the audit log tab content. + * + * This function handles the rendering of the audit log tab content based on the + * provided data via AJAX request. The data is used to filter the audit log or perform actions + * + * @access public + * @return void + */ + public function render_audit_log_tab() { + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- PCP warning. Nonce checked in previous function. + if (empty($_POST['data'])) return; + + // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput -- PCP warning. Nonce checked in previous function and sanitization done at later. + $data = wp_unslash($_POST['data']); + + // Needed for rendering the audit log table + include_once(AIO_WP_SECURITY_PATH.'/admin/wp-security-list-audit.php'); + $audit_log_list = new AIOWPSecurity_List_Audit_Log($data); + $audit_log_list->ajax_response(); + } + + /** + * Exports the audit logs as a CSV file and sends the data as an AJAX response. + * + * This function retrieves audit log data, prepares it for export, and generates a CSV string. + * The CSV data is then sent back as part of an AJAX response, along with the filename for the CSV file. + * + * @return array + */ + public function export_audit_logs() { + + // Needed for rendering the audit log table + include_once(AIO_WP_SECURITY_PATH.'/admin/wp-security-list-audit.php'); + $audit_log_list = new AIOWPSecurity_List_Audit_Log(); + + $audit_log_list->prepare_items(true); + $export_keys = array( + 'id' => 'ID', + 'created' => __('Date and time', 'all-in-one-wp-security-and-firewall'), + 'level' => __('Level', 'all-in-one-wp-security-and-firewall'), + 'network_id' => __('Network ID', 'all-in-one-wp-security-and-firewall'), + 'site_id' => __('Site ID', 'all-in-one-wp-security-and-firewall'), + 'username' => __('Username', 'all-in-one-wp-security-and-firewall'), + 'ip' => __('IP', 'all-in-one-wp-security-and-firewall'), + 'event_type' => __('Event', 'all-in-one-wp-security-and-firewall'), + 'details' => __('Details', 'all-in-one-wp-security-and-firewall'), + 'stacktrace' => __('Stack trace', 'all-in-one-wp-security-and-firewall') + ); + + $title = 'audit_event_logs.csv'; + ob_start(); + AIOWPSecurity_Admin_Init::aiowps_output_csv($audit_log_list->items, $export_keys, $title); + + $data = ob_get_clean(); + + return array( + 'title' => $title, + 'data' => $data + ); + } + + /** + * Initializing the WP List API, since UDC commands do not load all parts of WP. + * + * @return void + */ + private function init_wp_list() { + if (!function_exists('submit_button')) { + require_once(ABSPATH . 'wp-admin/includes/template.php'); + } + + if (!function_exists('render_screen_reader_content')) { + require_once(ABSPATH . 'wp-admin/includes/class-wp-screen.php'); + } + + if (!function_exists('get_column_headers')) { + require_once(ABSPATH . 'wp-admin/includes/screen.php'); + } + } + + /** + * Returns the data for downloading the audit log. + * + * @return array|WP_Error + */ + public function process_audit_log_export() { + if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) { + return new WP_Error(esc_html__('Sorry, you do not have enough privilege to execute the requested action.', 'all-in-one-wp-security-and-firewall')); + } + + $this->init_wp_list(); + + return $this->export_audit_logs(); + } + + /** + * Returns the HTML for the audit log. + * + * @return array + */ + public function get_audit_log_contents() { + global $aio_wp_security; + + $this->init_wp_list(); + + // Needed for rendering the audit log table + include_once AIO_WP_SECURITY_PATH . '/admin/wp-security-list-audit.php'; + $data = array(); + // phpcs:disable WordPress.Security.NonceVerification.Recommended -- PCP warning. Processing form data without nonce verification. No nonce. + if (isset($_GET['event-filter'])) $data['event-filter'] = sanitize_text_field(wp_unslash($_GET['event-filter'])); // Failed logins and logins only to show as audit log + $audit_log_list = new AIOWPSecurity_List_Audit_Log($data); + + $tab = isset($_GET["tab"]) ? sanitize_text_field(wp_unslash($_GET["tab"])) : ''; + $page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : ''; + // phpcs:enable WordPress.Security.NonceVerification.Recommended -- PCP warning. Processing form data without nonce verification. No nonce. + + $content = $aio_wp_security->include_template('wp-admin/dashboard/audit-logs.php', true, array('audit_log_list' => $audit_log_list, 'page' => $page, 'tab' => $tab)); + + return array( + 'status' => 'success', + 'content' => $content, + ); + } + + /** + * Deletes entry from audit log. + * + * @param array $data Table config data. + * + * @return array|WP_Error + */ + public function do_delete_audit_log($data) { + if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) { + return new WP_Error(esc_html__('Sorry, you do not have enough privilege to execute the requested action.', 'all-in-one-wp-security-and-firewall')); + } + + $this->init_wp_list(); + + if (!class_exists('AIOWPSecurity_Admin_Menu')) { + include_once AIO_WP_SECURITY_PATH . '/admin/wp-security-admin-menu.php'; + } + + return $this->delete_audit_log($data); + } + + /** + * Renders audit log after actions (delete/orderby, block/unblock, etc.) + * + * @param array $data Table config data. + * + * @return array + */ + public function do_render_audit_log_tab($data) { + $this->init_wp_list(); + + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- PCP warning. Nonce checked in previous function. + if (empty($data)) return array(); + + // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput -- PCP warning. Nonce checked in previous function and sanitization done at later. + $data = wp_unslash($data); + + if (!class_exists('AIOWPSecurity_Admin_Menu')) { + include_once AIO_WP_SECURITY_PATH . '/admin/wp-security-admin-menu.php'; + } + + // Needed for rendering the audit log table + include_once(AIO_WP_SECURITY_PATH.'/admin/wp-security-list-audit.php'); + $audit_log_list = new AIOWPSecurity_List_Audit_Log($data); + + return $audit_log_list->ajax_response(true); + } + + /** + * Parses raw audit log data for human-readable output. + * + * @param AIOWPSecurity_List_Audit_Log $audit_log_list Audit log object. + * @param array $data Raw audit log data. + * + * @return array + */ + private function parse_audit_log_data($audit_log_list, $data) { + $items = array(); + + foreach ($data as $db_item) { + if (empty($db_item)) { + continue; + } + + $item = array(); + + foreach ($db_item as $key => $value) { + switch ($key) { + case 'created': + $item[$key] = AIOWPSecurity_Utility::convert_timestamp($value); + break; + case 'event_type': + $item[$key] = $audit_log_list->column_event_type($db_item); + break; + case 'details': + $item[$key] = $audit_log_list->column_details($db_item); + break; + case 'stacktrace': + $item[$key] = $audit_log_list->column_stacktrace($db_item); + break; + default: + $item[$key] = $value; + break; + } + } + + $items[] = $item; + } + + return $items; + } + + /** + * Returns the data for the audit log table. + * + * @param array $data Configuration data. + * + * @return array + */ + public function get_audit_log_data($data) { + // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput -- PCP warning. Nonce checked in previous function and sanitization done at later. + $data = isset($data) ? wp_unslash($data) : array(); + + $data = isset($data['data']) ? $data['data'] : $data; + + $this->init_wp_list(); + $final_column = array(); + + // Needed for rendering the audit log table + include_once(AIO_WP_SECURITY_PATH.'/admin/wp-security-list-audit.php'); + $audit_log_list = new AIOWPSecurity_List_Audit_Log($data); + + $audit_log_list->prepare_items(); + + list($columns, $hidden) = $audit_log_list->get_column_info(); + + foreach ($columns as $column_key => $column_display_name) { + if ('cb' !== $column_key) { + if (!in_array($column_key, $hidden, true)) { + $final_column[$column_key] = array('label' => $column_display_name); + } + } + } + + $audit_log_items = isset($audit_log_list->items) ? $audit_log_list->items : array(); + + foreach ($audit_log_items as $key => $item) { + $ip = isset($item['ip']) ? $item['ip'] : ''; + + if ('' !== $ip) { + $audit_log_items[$key]['is_ip_locked'] = AIOWPSecurity_Utility::check_locked_ip($ip, 'audit-log'); + $audit_log_items[$key]['is_ip_blacklisted'] = AIOWPSecurity_Utility::check_blacklist_ip($ip); + } + } + + $items = $this->parse_audit_log_data($audit_log_list, $audit_log_items); + + $bulk_actions = $audit_log_list->get_bulk_actions(); + + $paged = !empty($data['paged']) ? (int) $data['paged'] : 1; + + AIOWPSecurity_Audit_Events::setup_event_types(); + + return array( + 'audit_log_data' => array( + 'bulk_actions' => $bulk_actions, + 'event_types' => AIOWPSecurity_Audit_Events::$event_types, + 'log_levels' => AIOWPSecurity_Audit_Events::$log_levels, + 'columns' => $final_column, + 'items' => $items, + 'is_multisite' => is_multisite(), + 'pagination' => array('page' => $paged, 'pages' => $audit_log_list->get_pagination_arg('total_pages'), 'results' => $audit_log_list->get_pagination_arg('total_items')), + ), + ); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-settings-commands.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-settings-commands.php new file mode 100755 index 00000000..59133c07 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-settings-commands.php @@ -0,0 +1,562 @@ +handle_response($success, $message, array('info' => $info)); + } + + /** + * Performs the action to disable all firewall rules. + * + * This method disables all firewall rules provided by the AIOWPSecurity_Settings_Tasks class. + * + * @return array An associative array containing the status and message of the operation. + * - 'status' : (string) The status of the operation, either 'success' or 'error'. + * - 'message' : (string) A message indicating the outcome of the operation. + * If the operation is successful, it contains an update message. + * If there is an error, it contains an error message. + */ + public function perform_disable_all_firewall_rules() { + $msg = AIOWPSecurity_Settings_Tasks::disable_all_firewall_rules(); + $success = true; + $message = ''; + + if (isset($msg['updated'])) { + $message = $msg['updated']; + } elseif (isset($msg['error'])) { + $message = $msg['error']; + $success = false; + } + + return $this->handle_response($success, $message); + } + + /** + * Performs the action to reset all settings. + * + * This method resets all settings provided by the AIOWPSecurity_Settings_Tasks class to their default values. + * + * @return array An associative array containing the status and message of the operation. + * - 'status' : (string) The status of the operation, either 'success' or 'error'. + * - 'message' : (string) A message indicating the outcome of the operation. + * If the operation is successful, it contains an update message. + * If there is an error, it contains an error message. + */ + public function perform_reset_all_settings() { + $msg = AIOWPSecurity_Settings_Tasks::reset_all_settings(); + + $success = true; + $message = ''; + + if (isset($msg['updated'])) { + $message = $msg['updated']; + } elseif (isset($msg['error'])) { + $message = $msg['error']; + $success = false; + } + + return $this->handle_response($success, $message); + } + + /** + * Performs the action to save debug settings. + * + * This method updates the debug settings in the AIOWPSecurity_Configs instance based on the provided data. + * + * @param array $data An associative array containing the data to update the debug settings. + * - 'aiowps_enable_debug': (bool) Indicates whether debug mode should be enabled. + * @return array An associative array containing the status and message of the operation. + * - 'status' : (string) The status of the operation, which is always 'success'. + * - 'message' : (string) A message indicating that the settings have been updated successfully. + */ + public function perform_save_debug_settings($data) { + global $aio_wp_security; + + $aio_wp_security->configs->set_value('aiowps_enable_debug', '1' === $data["aiowps_enable_debug"] ? '1' : '', true); + + return $this->handle_response(true); + } + + /** + * Performs the action to backup the .htaccess file. + * + * This method creates a backup of the .htaccess file and renames it with a random prefix. + * It also provides a message indicating the outcome of the backup operation. + * + * @global object $aio_wp_security The global instance of the All-in-One WP Security & Firewall plugin. + * @return array An associative array containing the status and message of the backup operation. + * - 'status' : (string) The status of the operation, which can be 'success' or 'error'. + * - 'message' : (string) A message indicating the outcome of the backup operation. + */ + public function perform_backup_htaccess_file() { + global $aio_wp_security; + + $home_path = AIOWPSecurity_Utility_File::get_home_path(); + $htaccess_path = $home_path . '.htaccess'; + + $result = AIOWPSecurity_Utility_File::backup_and_rename_htaccess($htaccess_path); //Backup the htaccess file + $extra_args = array(); + + if ($result) { + $aiowps_backup_dir = WP_CONTENT_DIR.'/'.AIO_WP_SECURITY_BACKUPS_DIR_NAME; + $success = true; + $message = __('Your .htaccess file was successfully backed up.', 'all-in-one-wp-security-and-firewall'); + $extra_args['data'] = file_get_contents($aiowps_backup_dir.'/'. $result .'.txt'); + $extra_args['title'] = $result; + } else { + $aio_wp_security->debug_logger->log_debug("htaccess - Backup operation failed!", 4); + $success = false; + $message = __('htaccess backup failed.', 'all-in-one-wp-security-and-firewall'); + } + + return $this->handle_response($success, $message, array('extra_args' => $extra_args)); + } + + /** + * Performs the action to restore the .htaccess file. + * + * This method restores the .htaccess file using the provided data, which includes the contents of the .htaccess file. + * It also verifies that the file chosen has valid contents relevant to the .htaccess file. + * + * @global object $aio_wp_security The global instance of the All-in-One WP Security & Firewall plugin. + * @param array $data An associative array containing the data needed to restore the .htaccess file. + * - 'aiowps_htaccess_file' : (string) The name of the .htaccess file to restore from. + * - 'aiowps_htaccess_file_contents' : (string) The contents of the .htaccess file to restore. + * @return array An associative array containing the status and message of the restore operation. + * - 'status' : (string) The status of the operation, which can be 'success' or 'error'. + * - 'message' : (string) A message indicating the outcome of the restore operation. + */ + public function perform_restore_htaccess_file($data) { + global $aio_wp_security; + + $success = true; + + $home_path = AIOWPSecurity_Utility_File::get_home_path(); + $htaccess_path = $home_path . '.htaccess'; + + if (empty($data['aiowps_htaccess_file']) && empty($data['aiowps_htaccess_file_contents'])) { + $message = __('Please choose a valid .htaccess to restore from.', 'all-in-one-wp-security-and-firewall'); + $success = false; + } else { + $htaccess_file_contents = trim(stripslashes($data['aiowps_htaccess_file_contents'])); + //Verify that file chosen has contents which are relevant to .htaccess file + $is_htaccess = AIOWPSecurity_Utility_Htaccess::check_if_htaccess_contents($htaccess_file_contents); + if (1 == $is_htaccess) { + if (!file_put_contents($htaccess_path, $htaccess_file_contents)) { + //Failed to make a backup copy + $aio_wp_security->debug_logger->log_debug("htaccess - Restore from .htaccess operation failed.", 4); + $message = __('The restoration of the .htaccess file failed; please attempt to restore the .htaccess file manually using FTP.', 'all-in-one-wp-security-and-firewall'); + $success = false; + } else { + $message = __('Your .htaccess file has successfully been restored.', 'all-in-one-wp-security-and-firewall'); + } + } else { + $aio_wp_security->debug_logger->log_debug("htaccess restore failed - Contents of restore file appear invalid.", 4); + $success = false; + $message = __('The restoration .htaccess file has failed, please check the contents of the file you are trying to restore from.', 'all-in-one-wp-security-and-firewall'); + } + } + + return $this->handle_response($success, $message); + } + + /** + * Performs the action to restore the wp-config.php file. + * + * This method restores the wp-config.php file using the provided data, which includes the contents of the wp-config.php file. + * It also verifies that the file chosen is a valid wp-config.php file. + * + * @global object $aio_wp_security The global instance of the All-in-One WP Security & Firewall plugin. + * @param array $data An associative array containing the data needed to restore the wp-config.php file. + * - 'aiowps_wp_config_file' : (string) The name of the wp-config.php file to restore from. + * - 'aiowps_wp_config_file_contents' : (string) The contents of the wp-config.php file to restore. + * @return array An associative array containing the status and message of the restore operation. + * - 'status' : (string) The status of the operation, which can be 'success' or 'error'. + * - 'message' : (string) A message indicating the outcome of the restore operation. + */ + public function perform_restore_wp_config_file($data) { + global $aio_wp_security; + + $success = true; + + if (empty($data['aiowps_wp_config_file']) && empty($data['aiowps_wp_config_file_contents'])) { + $message = __('Please choose a wp-config.php file to restore from.', 'all-in-one-wp-security-and-firewall'); + $success = false; + } else { + $wp_config_file_contents = trim(stripslashes($data['aiowps_wp_config_file_contents'])); + + //Verify that file chosen is a wp-config.file + $is_wp_config = AIOWPSecurity_Utility_File::check_if_wp_config_contents($wp_config_file_contents); + if ($is_wp_config) { + $active_root_wp_config = AIOWPSecurity_Utility_File::get_wp_config_file_path(); + if (!file_put_contents($active_root_wp_config, $wp_config_file_contents)) { + //Failed to make a backup copy + $aio_wp_security->debug_logger->log_debug("wp-config.php - Restore from backed up wp-config operation failed.", 4); + $message = __('The restoration of the wp-config.php file failed, please attempt to restore this file manually using FTP.', 'all-in-one-wp-security-and-firewall'); + $success = false; + } else { + $message =__('Your wp-config.php file has successfully been restored.', 'all-in-one-wp-security-and-firewall'); + } + } else { + $aio_wp_security->debug_logger->log_debug("wp-config.php restore failed - Contents of restore file appear invalid.", 4); + $message = __('The restoration of the wp-config.php file failed, please check the contents of the file you are trying to restore from.', 'all-in-one-wp-security-and-firewall'); + $success = false; + } + } + + return $this->handle_response($success, $message); + } + + /** + * Performs the action to delete plugin settings. + * + * This method deletes specific plugin settings based on the provided data. + * + * @param array $data An associative array containing the data needed to delete plugin settings. + * - 'aiowps_on_uninstall_delete_db_tables' : (string) Indicates whether to delete plugin database tables on uninstallation. + * - 'aiowps_on_uninstall_delete_configs' : (string) Indicates whether to delete plugin configuration settings on uninstallation. + * @return array An associative array containing the status and message of the delete operation. + * - 'status' : (string) The status of the operation, which can be 'success'. + * - 'message' : (string) A message indicating that the plugin settings have been successfully deleted. + */ + public function perform_delete_plugin_settings($data) { + + $options = array(); + //Save settings + $options['aiowps_on_uninstall_delete_db_tables'] = isset($data['aiowps_on_uninstall_delete_db_tables']) ? '1' : ''; + $options['aiowps_on_uninstall_delete_configs'] = isset($data['aiowps_on_uninstall_delete_configs']) ? '1' : ''; + $this->save_settings($options); + + return $this->handle_response(true); + } + + /** + * Performs the action to remove WordPress version information settings. + * + * This method sets the option to remove WordPress version information meta tags based on the provided data. + * + * @param array $data An associative array containing the data needed to configure the removal of WordPress version information. + * - 'aiowps_remove_wp_generator_meta_info' : (string) Indicates whether to remove WordPress version information meta tags. + * @return array An associative array containing the status, message, and additional badges related to the removal of WordPress version information. + * - 'status' : (string) The status of the operation, which can be 'success'. + * - 'message' : (string) A message indicating that the settings have been successfully updated. + * - 'badges' : (array) An array containing feature IDs and HTML for additional badges. + */ + public function perform_remove_wp_version_info_settings($data) { + global $aio_wp_security; + + $aio_wp_security->configs->set_value('aiowps_remove_wp_generator_meta_info', '1' === $data["aiowps_remove_wp_generator_meta_info"] ? '1' : '', true); + + return $this->handle_response(true, '', array('badges' => array('wp-generator-meta-tag'))); + } + + /** + * Performs the action to restore AIOWPS settings from an imported file. + * + * This method restores AIOWPS settings from the provided data representing an imported file. + * + * @param array $data An associative array containing the data needed to restore AIOWPS settings. + * - 'aiowps_import_settings_file' : (string) The name of the file containing the AIOWPS settings. + * - 'aiowps_import_settings_file_contents': (string) The contents of the file containing the AIOWPS settings. + * @return array An associative array containing the status and messages related to the restoration of AIOWPS settings. + * - 'status' : (string) The status of the operation, which can be 'success' or 'error'. + * - 'messages' : (array) An array of messages indicating the outcome of the restoration process. + * - 'redirect_url' : (string|null) The URL to redirect to after the restoration process, if applicable. + */ + public function perform_restore_aiowps_settings($data) { + global $aio_wp_security, $simba_two_factor_authentication; + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + + $success = true; + $info = array(); + $extra_args = array(); + + $msg_updated = __('Your AIOS settings were successfully imported.', 'all-in-one-wp-security-and-firewall'); + $msg_error = sprintf(__('Could not write to the %s file.', 'all-in-one-wp-security-and-firewall'), AIOWPSecurity_Utility_File::get_home_path().'.htaccess') . ' ' . __('Please check the file permissions.', 'all-in-one-wp-security-and-firewall'); + + if (empty($data['aiowps_import_settings_file']) && empty($data['aiowps_import_settings_file_contents'])) { + $success = false; + $message = __('Please choose a file to import your settings from.', 'all-in-one-wp-security-and-firewall'); + } else { + // Let's get the uploaded import file contents + $import_file_contents = trim($data['aiowps_import_settings_file_contents']); // stripslashes not required wp_unslash applied already AIOWPSecurity_Ajax::set_data + + // Verify that file chosen has valid AIOS settings contents + $aiowps_settings_file_contents = AIOWPSecurity_Utility_File::check_if_valid_aiowps_settings_content($import_file_contents); + + if ($aiowps_settings_file_contents) { + $is_enabled_cookie_bruteforce_before_import = $aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention'); + // Apply the settings + $settings_array = json_decode($import_file_contents, true); + if (array_key_exists('general', $settings_array)) { + $aiowps_settings_applied = update_option('aio_wp_security_configs', $settings_array['general']); + + if (!$aiowps_settings_applied && get_option('aio_wp_security_configs') === $settings_array['general']) { + $aiowps_settings_applied = true; + } + + if (is_main_site() && is_super_admin()) { + if (array_key_exists('tfa', $settings_array) && true == $simba_two_factor_authentication->is_tfa_integrated) { + $tfa_settings_applied = $simba_two_factor_authentication->set_configs($settings_array['tfa']); + + if (!$tfa_settings_applied && $simba_two_factor_authentication->get_configs() !== $settings_array['tfa']) { + $aiowps_settings_applied = false; + } + } + + if (array_key_exists('firewall', $settings_array)) { + $aiowps_settings_applied = $aiowps_settings_applied && $aiowps_firewall_config->set_contents($settings_array['firewall']); + } + } + } else { + $aiowps_settings_applied = update_option('aio_wp_security_configs', $settings_array); + + if (!$aiowps_settings_applied && get_option('aio_wp_security_configs') === $settings_array) { + $aiowps_settings_applied = true; + } + } + + if (!$aiowps_settings_applied) { + // Failed to import settings + $aio_wp_security->debug_logger->log_debug('Import AIOS settings operation failed.', 4); + $success = false; + $message = __('Import AIOS settings operation failed.', 'all-in-one-wp-security-and-firewall'); + } else { + $aio_wp_security->configs->load_config(); // Refresh the configs global variable + + //Just in case user submits partial config settings + //Run add_option_values to make sure any missing config items are at least set to default + AIOWPSecurity_Configure_Settings::add_option_values(); + + $res = true; + + if (AIOWPSecurity_Utility::allow_to_write_to_htaccess()) $res = AIOWPSecurity_Utility_Htaccess::write_to_htaccess(); + + // Now let's refresh the .htaccess file with any modified rules if applicable + + $is_enabled_cookie_bruteforce = $aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention'); + + if ($is_enabled_cookie_bruteforce_before_import != $is_enabled_cookie_bruteforce && 1 == $is_enabled_cookie_bruteforce) { + $url = 'admin.php?page='.AIOWPSEC_SETTINGS_MENU_SLUG."&tab=settings-file-operations&success=import_settings"; + $url .= empty($aio_wp_security->configs->get_value('aiowps_brute_force_secret_word')) ? '' : '&'.$aio_wp_security->configs->get_value('aiowps_brute_force_secret_word').'=1'; + $url .= $res ? '' : '&error=write_htaccess'; + $extra_args['redirect_url'] = admin_url(sanitize_url($url)); + } + + $message = $msg_updated; + if (!$res) { + $info[] = $msg_error; + } + } + } else { + // Invalid settings file + $aio_wp_security->debug_logger->log_debug("The contents of your settings file are invalid.", 4); + $success = false; + $message = __('The contents of your settings file are invalid, please check the contents of the file you are trying to import settings from.', 'all-in-one-wp-security-and-firewall'); + } + } + + $args = array( + 'info' => $info, + 'extra_args' => $extra_args + ); + + return $this->handle_response($success, $message, $args); + } + + /** + * Performs the action to save IP settings. + * + * This method saves the IP settings based on the provided data. + * + * @param array $data An associative array containing the data needed to save IP settings. + * - 'aiowps_ip_retrieve_method': (string) The ID of the IP retrieval method. + * @return array An associative array containing the status and message related to saving IP settings. + * - 'status': (string) The status of the operation, which can be 'success' or 'error'. + * - 'message': (string|null) A message indicating the outcome of saving IP settings, or null if no message is provided. + */ + public function perform_save_ip_settings($data) { + global $wpdb, $aio_wp_security; + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + + $ip_retrieve_method_id = sanitize_text_field($data["aiowps_ip_retrieve_method"]); + + $message = false; + + if (in_array($ip_retrieve_method_id, array_keys(AIOS_Abstracted_Ids::get_ip_retrieve_methods()))) { + $aio_wp_security->configs->set_value('aiowps_ip_retrieve_method', $ip_retrieve_method_id, true); + $aiowps_firewall_config->set_value('aios_ip_retrieve_method', $ip_retrieve_method_id); + $logged_in_users_table = AIOWPSEC_TBL_LOGGED_IN_USERS; + + //Clear logged in list because it might be showing wrong addresses + if (AIOWPSecurity_Utility::is_multisite_install()) { + $current_blog_id = get_current_blog_id(); + $wpdb->query($wpdb->prepare("DELETE FROM `{$logged_in_users_table}` WHERE site_id = %d", $current_blog_id)); + } + $wpdb->query("DELETE FROM `{$logged_in_users_table}`"); + + $message = ''; + } + + return $this->handle_response(true, $message); + } + + /** + * Perform saving the wp-config.php file. + * + * This method backs up the wp-config.php file and retrieves its content. + * It returns the status of the operation, the file content, and the backup title. + * + * @return array An array containing the status, file content, and backup title. + */ + public function perform_save_wp_config() { + $wp_config_path = AIOWPSecurity_Utility_File::get_wp_config_file_path(); + AIOWPSecurity_Utility_File::backup_and_rename_wp_config($wp_config_path); // Backup the wp_config.php file + $title = "wp-config-backup.txt"; + $file_content = file_get_contents($wp_config_path); + + $extra_args = array( + 'data' => $file_content, + 'title' => $title + ); + + return $this->handle_response(true, false, array('extra_args' => $extra_args)); + } + + /** + * Perform exporting All-In-One Security settings. + * + * This method exports general settings, firewall settings, and two-factor authentication settings + * if applicable. It then returns the exported data in JSON format along with a title for the export. + * + * @return array An array containing the status, exported data in JSON format, and a title for the export. + */ + public function perform_export_aios_settings() { + global $simba_two_factor_authentication; + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + + $config_data = array(); + $config_data['general'] = get_option('aio_wp_security_configs'); + + if (is_main_site() && is_super_admin()) { + $config_data['firewall'] = $aiowps_firewall_config->get_contents(); + + if (true == $simba_two_factor_authentication->is_tfa_integrated) { + $config_data['tfa'] = $simba_two_factor_authentication->get_configs(); + } + } + + $output = json_encode($config_data); + + $extra_args = array( + 'data' => $output, + 'title' => 'aiowps_' . current_time('Y-m-d_H-i') . '.txt' + ); + + return $this->handle_response(true, false, array('extra_args' => $extra_args)); + } + + /** + * Render the Import/Export settings UI for legacy UDC. + * + * @return array + */ + public function get_import_export_contents() { + global $aio_wp_security; + + $content = $aio_wp_security->include_template('wp-admin/settings/settings-file-operations.php', true, array()); + + return array( + 'status' => 'success', + 'content' => $content, + ); + } + + /** + * Render the reset settings UI for legacy UDC. + * + * @return array + */ + public function get_reset_contents() { + global $aio_wp_security; + + $content = $aio_wp_security->include_template('wp-admin/settings/general-settings.php', true, array()); + + return array( + 'status' => 'success', + 'content' => $content, + ); + } + + /** + * Return ip address detection data for the advanced settings. + * + * @return array + */ + public function get_ip_address_detection_data() { + global $aio_wp_security; + + $ip_retrieve_methods_postfixes = array( + 'REMOTE_ADDR' => __('Default - if correct, then this is the best option', 'all-in-one-wp-security-and-firewall'), + 'HTTP_CF_CONNECTING_IP' => __("Only use if you're using Cloudflare.", 'all-in-one-wp-security-and-firewall'), + ); + + $ip_retrieve_methods = array(); + + foreach (AIOS_Abstracted_Ids::get_ip_retrieve_methods() as $id => $ip_method) { + $ip_retrieve_methods[$id]['ip_method'] = $ip_method; + + if (isset($_SERVER[$ip_method])) { + /* translators: %s: IP Method */ + $ip_retrieve_methods[$id]['ip_method'] .= ' ' . sprintf(__('(current value: %s)', 'all-in-one-wp-security-and-firewall'), sanitize_text_field(wp_unslash($_SERVER[$ip_method]))); + $ip_retrieve_methods[$id]['is_enabled'] = true; + } else { + $ip_retrieve_methods[$id]['ip_method'] .= ' (' . __('no value (i.e. empty) on your server', 'all-in-one-wp-security-and-firewall') . ')'; + $ip_retrieve_methods[$id]['is_enabled'] = false; + } + + if (!empty($ip_retrieve_methods_postfixes[$ip_method])) { + $ip_retrieve_methods[$id]['ip_method'] .= ' (' . $ip_retrieve_methods_postfixes[$ip_method] . ')'; + } + } + + return array( + 'is_localhost' => AIOWPSecurity_Utility::is_localhost(), + 'current_ip_retrieve_method' => $aio_wp_security->configs->get_value('aiowps_ip_retrieve_method'), + 'ip_retrieve_methods' => $ip_retrieve_methods, + 'server_suitable_ip_methods' => AIOWPSecurity_Utility_IP::get_server_suitable_ip_methods() + ); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-tfa-commands.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-tfa-commands.php new file mode 100755 index 00000000..5797b662 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-tfa-commands.php @@ -0,0 +1,216 @@ +init_tfa(); + + $controller = $tfa->get_controller(); + + $old_algorithm = $controller->get_user_otp_algorithm($current_user->ID); + + if ($old_algorithm != $data['tfa_algorithm_type']) { + $controller->changeUserAlgorithmTo($current_user->ID, $data['tfa_algorithm_type']); + } + + return array( + 'status' => 'success', + ); + } + + /** + * Saves the TFA activation setting. + * + * @param array $data Passed arguments. + * + * @return array|WP_Error + */ + public function save_activation_setting($data) { + if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) { + return new WP_Error(esc_html__('Sorry, you do not have enough privilege to execute the requested action.', 'all-in-one-wp-security-and-firewall')); + } + + global $current_user; + + $tfa = $this->init_tfa(); + + $tfa->change_tfa_enabled_status($current_user->ID, $data['tfa_enable_tfa']); + + return array( + 'status' => 'success', + ); + } + + /** + * Updates the TFA private key. + * + * @return array|WP_Error + */ + public function update_private_key() { + if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) { + return new WP_Error(esc_html__('Sorry, you do not have enough privilege to execute the requested action.', 'all-in-one-wp-security-and-firewall')); + } + + global $current_user; + + $user_id = $current_user->ID; + + delete_user_meta($user_id, 'tfa_priv_key_64'); + delete_user_meta($user_id, 'simba_tfa_emergency_codes_64'); + + return array( + 'status' => 'success', + ); + } + + /** + * Updates the TFA OTP Code. + * + * @param array $data Passed arguments. + * + * @return array|WP_Error + */ + public function update_otp_code($data) { + if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) { + return new WP_Error(esc_html__('Sorry, you do not have enough privilege to execute the requested action.', 'all-in-one-wp-security-and-firewall')); + } + + global $current_user; + + $tfa = $this->init_tfa(); + + if ('refreshotp' == $data['subaction']) { + $code = $tfa->get_controller()->get_current_code($current_user->ID); + + if (false === $code) { + return array( + 'status' => 'error', + 'code' => '', + ); + } + + return array( + 'status' => 'success', + 'code' => $code, + ); + } elseif ('untrust_device' == $data['subaction']) { + global $current_user; + + $trusted_devices = $tfa->user_get_trusted_devices(); + + $trusted_device = $trusted_devices[wp_unslash($data['device_id'])]; + + if (isset($trusted_device)) { + unset($trusted_device); + } + + $current_user_id = $current_user->ID; + + $tfa->user_set_trusted_devices($current_user_id, $trusted_devices); + + $trusted_list = $tfa->include_template('trusted-devices-inner-box.php', array('trusted_devices' => $tfa->user_get_trusted_devices()), true); + + return array( + 'status' => 'success', + 'trusted_list' => $trusted_list, + ); + } + + exit; + } + + /** + * Renders the TFA UI. + * + * @return array + */ + public function get_tfa_contents() { + if (!function_exists('submit_button')) { + require_once(ABSPATH . 'wp-admin/includes/template.php'); + } + + $tfa = $this->init_tfa(); + + $content = $tfa->include_template('user-settings.php', array('simba_tfa' => $tfa), true); + + return array( + 'status' => 'success', + 'content' => $content, + ); + } + + /** + * Get the TFA settings data for the new UDC theme. + * + * @return array + */ + public function get_tfa_data() { + $tfa = $this->init_tfa(); + + return array( + 'tfa_required_administrator' => $tfa->get_option('tfa_required_administrator'), + 'tfa_administrator' => $tfa->get_option('tfa_administrator'), + ); + } + + /** + * Save the TFA settings data for the new UDC theme. + * + * @param array $data The data to save. + * + * @return array|WP_Error + */ + public function perform_save_tfa($data) { + if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) { + return new WP_Error(esc_html__('Sorry, you do not have enough privilege to execute the requested action.', 'all-in-one-wp-security-and-firewall')); + } + + $success = false; + $message = ''; + + $tfa = $this->init_tfa(); + + $value = isset($data["tfa_required_administrator"]) ? '1' : ''; + + if ($tfa->update_option('tfa_required_administrator', $value)) { + $tfa->update_option('tfa_administrator', $value); + + $success = true; + } + + return $this->handle_response($success, $message); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-tools-commands.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-tools-commands.php new file mode 100755 index 00000000..18196dab --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-tools-commands.php @@ -0,0 +1,253 @@ +')) { + if (!(filter_var($ip_or_domain, FILTER_VALIDATE_IP) || filter_var($ip_or_domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME))) $invalid_domain = true; // phpcs:ignore PHPCompatibility.Constants.NewConstants.filter_validate_domainFound -- This code only runs on php 7.0+ so ignore the warning + } + + if ($invalid_domain) { + $result = __('Please enter a valid IP address or domain name to look up.', 'all-in-one-wp-security-and-firewall'); + $result .= __('Nothing to show.', 'all-in-one-wp-security-and-firewall'); + } else { + $result = $this->whois_lookup($ip_or_domain); + + if (is_wp_error($result)) { + $result = htmlspecialchars($result->get_error_message()); + $result .= __('Nothing to show.', 'all-in-one-wp-security-and-firewall'); + } else { + $result = htmlspecialchars($result); + } + } + + $args = array( + 'content' => array('aios-who-is-lookup-result-container' => $aio_wp_security->include_template('wp-admin/tools/partials/who-is-lookup-result.php', true, array('result' => $result, 'ip_or_domain' => $ip_or_domain))) + ); + + return $this->handle_response(true, false, $args); + } + + /** + * Store custom .htaccess settings provided by the user. + * + * @param array $data The data containing the custom .htaccess settings. + * It should include keys 'aiowps_enable_custom_rules', 'aiowps_custom_rules', + * and 'aiowps_place_custom_rules_at_top' if applicable. + * @return array An array containing the status of the operation and any relevant messages. + * The 'status' key indicates whether the operation was successful. + * The 'message' key contains any informational or error messages. + */ + public function perform_store_custom_htaccess_settings($data) { + global $aio_wp_security; + + $success = true; + $message = ''; + + $options = array(); + // Save settings + if (isset($data["aiowps_enable_custom_rules"]) && empty($data['aiowps_custom_rules'])) { + $message = __('You must enter some .htaccess directives in the text box below', 'all-in-one-wp-security-and-firewall'); + return $this->handle_response(false, $message); + } else { + if (!empty($data['aiowps_custom_rules'])) { + // Sanitize textarea shoud not be used as etc rules gets removed. + // Escape textarea should not be used the & becomes &. + // Here stripslashes as old version 5.3.0 not required, AIOWPSecurity_Ajax::set_data applies wp_unslash for ajax data. + // So the .htacces rule having index\.php backslashes removed if used stripslashes below. + $options['aiowps_custom_rules'] = $data['aiowps_custom_rules']; + } else { + $options['aiowps_custom_rules'] = ''; //Clear the custom rules config value + } + + $aiowps_custom_rules = $aio_wp_security->configs->get_value('aiowps_custom_rules'); + $aiowps_place_custom_rules_at_top = $aio_wp_security->configs->get_value('aiowps_place_custom_rules_at_top'); + + $options['aiowps_enable_custom_rules'] = isset($data["aiowps_enable_custom_rules"]) ? '1' : ''; + $options['aiowps_place_custom_rules_at_top'] = isset($data["aiowps_place_custom_rules_at_top"]) ? '1' : ''; + $this->save_settings($options); // Save the configuration + + $write_result = AIOWPSecurity_Utility_Htaccess::write_to_htaccess(); //now let's write to the .htaccess file + if (!$write_result) { + $options['aiowps_enable_custom_rules'] = $aiowps_custom_rules; + $options['aiowps_place_custom_rules_at_top'] = $aiowps_place_custom_rules_at_top; + + $this->save_settings($options); + + $success = false; + $message = __('The plugin was unable to write to the .htaccess file, please edit file manually.', 'all-in-one-wp-security-and-firewall'); + $aio_wp_security->debug_logger->log_debug("Custom Rules feature - The plugin was unable to write to the .htaccess file."); + } + } + + return $this->handle_response($success, $message); + } + + /** + * Perform the general visitor lockout settings operation. + * + * @param array $data The data containing the general visitor lockout settings. + * It should include keys 'aiowps_site_lockout' and 'aiowps_site_lockout_msg'. + * @return array An array containing the status of the operation and any relevant messages. + * The 'status' key indicates whether the operation was successful. + * The 'message' key contains an informational message about the outcome of the operation. + */ + public function perform_general_visitor_lockout($data) { + $options = array(); + + // Save settings + $options['aiowps_site_lockout'] = isset($data["aiowps_site_lockout"]) ? '1' : ''; + $maint_msg = wp_kses_post(wp_unslash($data['aiowps_site_lockout_msg'])); + $options['aiowps_site_lockout_msg'] = $maint_msg; // Text area/msg box + $this->save_settings($options); + + do_action('aiowps_site_lockout_settings_saved'); + + return array( + 'status' => 'success', + 'message' => __('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall') + ); + } + + /** + * Perform the general visitor lockout setting operation for the dashboard widget. + * + * @param array $data The data containing the general visitor lockout setting. + * It should include the 'aiowps_site_lockout' key. + * @return array An array containing the status of the operation and any relevant messages. + * The 'status' key indicates whether the operation was successful. + * The 'message' key contains an informational message about the outcome of the operation. + */ + public function perform_general_visitor_lockout_dashboard_widget($data) { + $options = array(); + + // Save settings + $options['aiowps_site_lockout'] = isset($data["aiowps_site_lockout"]) ? '1' : ''; + $this->save_settings($options); + + do_action('aiowps_site_lockout_settings_saved'); + + return $this->handle_response(true); + } + + /** + * Checks a password against the HIBP database. + * + * @param array $data Contains the password to be checked. + * + * @return array + */ + public function hibp_check_password($data) { + return array( + 'status' => 'success', + 'pwned' => AIOS_HIBP::password_is_pwned($data['password']), + ); + } + + /** + * Does a WHOIS lookup on an IP address or domain name and then returns the result. + * + * @param String $search - IP address or domain name to do a WHOIS lookup on + * @param Integer $timeout - connection timeout for fsockopen + * + * @return String|WP_Error - returns preformatted WHOIS lookup result or WP_Error + */ + private function whois_lookup($search, $timeout = 10) { + $fp = @fsockopen('whois.iana.org', 43, $errno, $errstr, $timeout); + + if (!$fp) { + return new WP_Error('whois_lookup_failed', 'whois.iana.org: Socket Error '.$errno.' - '.$errstr); + } + + $queries = sprintf(__('Querying %s: %s', 'all-in-one-wp-security-and-firewall'), 'whois.iana.org', $search)."\n"; + + fputs($fp, $search."\r\n"); + $out = ''; + while (!feof($fp)) { + $line = fgets($fp); + if (preg_match('/refer: +(\S+)/', $line, $matches)) { + $referral_server = $matches[1]; + $queries .= sprintf(__('Redirected to %s', 'all-in-one-wp-security-and-firewall'), $referral_server)."\n"; + break; + } + $out .= $line; + } + fclose($fp); + + if (!isset($referral_server) && filter_var($search, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && preg_match('/whois: +(\S+)/', $out, $matches)) { + $referral_server = $matches[1]; + $queries .= sprintf(__('Redirected to %s', 'all-in-one-wp-security-and-firewall'), $referral_server)."\n"; + } + + $referrals = array(); + + while (isset($referral_server)) { + $referrals[] = $referral_server; + + $fp = @fsockopen($referral_server, 43, $errno, $errstr, $timeout); + + if (!$fp) { + return new WP_Error('whois_lookup_failed', $referral_server.': Socket Error '.$errno.' - '.$errstr); + } + + if ('whois.arin.net' == $referral_server) { + $formatted_search = 'n + '.$search; + } elseif ('whois.denic.de' == $referral_server) { + $formatted_search = '-T dn,ace '.$search; + } elseif ('whois.dk-hostmaster.dk' == $referral_server) { + $formatted_search = '--charset=utf-8 --show-handles '.$search; + } elseif ('whois.nic.ad.jp' == $referral_server || 'whois.jprs.jp' == $referral_server) { + $formatted_search = $search.'/e'; + } else { + $formatted_search = $search; + } + + $queries .= sprintf(__('Querying %s: %s', 'all-in-one-wp-security-and-firewall'), $referral_server, $formatted_search)."\n"; + + $referral_server = null; + + fputs($fp, $formatted_search."\r\n"); + $out = ''; + while (!feof($fp)) { + $line = fgets($fp); + if (preg_match('/Registrar WHOIS Server: +(\S+)/', $line, $matches) + || preg_match('/% referto: +whois -h (\S+)/', $line, $matches) + || preg_match('/% referto: +(\S+)/', $line, $matches) + || preg_match('/ReferralServer: +rwhois:\/\/(\S+)/', $line, $matches) + || preg_match('/ReferralServer: +whois:\/\/(\S+)/', $line, $matches) + ) { + if (!in_array($matches[1], $referrals)) { + $referral_server = $matches[1]; + $queries .= sprintf(__('Redirected to %s', 'all-in-one-wp-security-and-firewall'), $referral_server)."\n"; + break; + } + } + $out .= $line; + } + fclose($fp); + } + + return $queries."\n".$out; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-user-security-commands.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-user-security-commands.php new file mode 100755 index 00000000..33c5c700 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/commands/wp-security-user-security-commands.php @@ -0,0 +1,716 @@ +configs->set_value('aiowps_prevent_users_enumeration', isset($data["aiowps_prevent_users_enumeration"]) ? '1' : '', true); + $aio_wp_security->configs->set_value('aiowps_enforce_strong_password', isset($data['aiowps_enforce_strong_password']) ? '1' : '', true); + + $badges = array('enforce-strong-password', 'disable-users-enumeration'); + + return $this->handle_response(true, '', array('badges' => $badges)); + } + + /** + * Performs the action to change the admin username. + * + * @param array $data An array containing the data for changing the admin username. + * The array may contain the following keys: + * - 'aiowps_new_user_name': The new username to be set for the admin. + * @return array Returns an array containing the status of the operation ('success' or 'error'), + * and a message indicating the result of the operation. + * If the operation is successful, it also includes a badge representing the updated feature details. + */ + public function perform_change_admin_username($data) { + global $wpdb, $aio_wp_security; + + $response = array( + 'status' => 'success', + 'content' => array() + ); + + $error = ''; + if (!empty($data['aiowps_new_user_name'])) { + $new_username = sanitize_text_field($data['aiowps_new_user_name']); + if (validate_username($new_username)) { + if (AIOWPSecurity_Utility::check_user_exists($new_username)) { + $response['status'] = 'error'; + $error = sprintf(__('Username: %s already exists, please enter another value.', 'all-in-one-wp-security-and-firewall'), $new_username); + } else { + // let's check if currently logged in username is 'admin' + $user = wp_get_current_user(); + $user_login = $user->user_login; + if ('admin' == strtolower($user_login)) { + $username_is_admin = true; + } else { + $username_is_admin = false; + } + // Now let's change the username + $sql = $wpdb->prepare("UPDATE `" . $wpdb->users . "` SET user_login = '" . esc_sql($new_username) . "' WHERE user_login=%s", "admin"); + $result = $wpdb->query($sql); + if (false === $result) { + // There was an error updating the users table + $user_update_error = __('The database update operation of the user account failed.', 'all-in-one-wp-security-and-firewall'); + $response['status'] = 'error'; + $response['message'] = $user_update_error; + $aio_wp_security->debug_logger->log_debug($user_update_error . ' ' . $wpdb->last_error, 4); + return $response; + } + + // multisite considerations + if (is_multisite()) { // process sitemeta if we're in a multi-site situation + $oldAdmins = $wpdb->get_var("SELECT meta_value FROM `" . $wpdb->sitemeta . "` WHERE meta_key = 'site_admins'"); + $newAdmins = str_replace('5:"admin"', strlen($new_username) . ':"' . esc_sql($new_username) . '"', $oldAdmins); + $wpdb->query("UPDATE `" . $wpdb->sitemeta . "` SET meta_value = '" . esc_sql($newAdmins) . "' WHERE meta_key = 'site_admins'"); + } + + // If user is logged in with username "admin" then log user out and send to login page so they can login again + if ($username_is_admin) { + // Lets logout the user + $aio_wp_security->debug_logger->log_debug("Logging user out with login ".$user_login. " because they changed their username."); + $after_logout_url = AIOWPSecurity_Utility::get_current_page_url(); + $after_logout_payload = array('redirect_to' => $after_logout_url, 'msg' => $aio_wp_security->user_login_obj->key_login_msg.'=admin_user_changed'); + //Save some of the logout redirect data to a transient + is_multisite() ? set_site_transient('aiowps_logout_payload', $after_logout_payload, 30 * 60) : set_transient('aiowps_logout_payload', $after_logout_payload, 30 * 60); + + $logout_url = AIOWPSEC_WP_URL.'?aiowpsec_do_log_out=1'; + $logout_url = AIOWPSecurity_Utility::add_query_data_to_url($logout_url, 'al_additional_data', '1'); + + $response['logout_user'] = true; + $response['logout_url'] = $logout_url; + } + } + } else { // An invalid username was entered + $error = __('You entered an invalid username, please enter another value.', 'all-in-one-wp-security-and-firewall'); + } + } else { // No username value was entered + $response['status'] = 'error'; + $error = __('Please enter a value for your username.', 'all-in-one-wp-security-and-firewall'); + } + + if (!empty($error)) { // We have some validation or other error + $response['message'] = $error; + } else { + $response['message'] = __('The username has been successfully changed.', 'all-in-one-wp-security-and-firewall'); + $response['badges'] = $this->get_features_id_and_html(array('user-accounts-change-admin-user')); + $response['content']['change-admin-username-content'] = $aio_wp_security->include_template('wp-admin/user-security/partials/wp-username-content.php', true); + } + + return $response; + } + + /** + * Performs the action to save the login lockout settings. + * + * @param array $data An array containing the data to be saved. + * + * @return array Returns an array containing the status of the operation ('success' or 'error'), + * a message indicating the result of the operation, + * and a badge representing the updated feature details. + */ + public function perform_save_login_lockout_settings($data) { + + $response = array( + 'status' => 'success', + 'values' => array(), + 'info' => array() + ); + + $invalid_fields = array(); + + $max_login_attempt_val = sanitize_text_field($data['aiowps_max_login_attempts']); + if (!is_numeric($max_login_attempt_val) || 1 > $max_login_attempt_val) { + $invalid_fields[] = 'max login attempts'; + $max_login_attempt_val = '3'; // Set it to the default value for this field + } + + $login_retry_time_period = sanitize_text_field($data['aiowps_retry_time_period']); + if (!is_numeric($login_retry_time_period) || 1 > $login_retry_time_period) { + $invalid_fields[] = 'login retry time period'; + $login_retry_time_period = '5'; // Set it to the default value for this field + } + + $lockout_time_length = sanitize_text_field($data['aiowps_lockout_time_length']); + if (!is_numeric($lockout_time_length) || 1 > $lockout_time_length) { + $invalid_fields[] = 'minimum lockout time length'; + $lockout_time_length = '5'; // Set it to the default value for this field + } + + $max_lockout_time_length = sanitize_text_field($data['aiowps_max_lockout_time_length']); + if (!is_numeric($max_lockout_time_length) || 1 > $max_lockout_time_length) { + $invalid_fields[] = 'maximum lockout time length'; + $max_lockout_time_length = '60'; // Set it to the default value for this field + } + + if ($lockout_time_length >= $max_lockout_time_length) { + $invalid_fields[] = 'minimum lockout time length'; + $lockout_time_length = '5'; // Set it to the default value for this field + $max_lockout_time_length = '60'; // Set it to the default value for this field + } + + $email_addresses = isset($data['aiowps_email_address']) ? stripslashes($data['aiowps_email_address']) : get_bloginfo('admin_email'); + $email_addresses_trimmed = AIOWPSecurity_Utility::explode_trim_filter_empty($email_addresses, "\n"); + // Read into array, sanitize, filter empty and keep only unique usernames. + $email_address_list = array_unique( + array_filter( + array_map( + 'sanitize_email', + $email_addresses_trimmed + ), + 'is_email' + ) + ); + + if (isset($data['aiowps_enable_email_notify']) && 1 == $data['aiowps_enable_email_notify'] && 0 == count($email_addresses_trimmed)) { + $invalid_fields[] = 'email addresses'; + } elseif (isset($data['aiowps_enable_email_notify']) && 1 == $data['aiowps_enable_email_notify'] && (0 == count($email_address_list) || count($email_address_list) != count($email_addresses_trimmed))) { + $invalid_fields[] = 'email addresses'; + } + if (isset($data['aiowps_enable_email_notify']) && 0 == count($email_address_list)) { + $email_address_list[] = get_bloginfo('admin_email'); + } + + // Instantly lockout specific usernames + $instantly_lockout_specific_usernames = isset($data['aiowps_instantly_lockout_specific_usernames']) ? $data['aiowps_instantly_lockout_specific_usernames'] : ''; + // Read into array, sanitize, filter empty and keep only unique usernames. + $instantly_lockout_specific_usernames = array_unique( + array_filter( + array_map( + 'sanitize_user', + AIOWPSecurity_Utility::explode_trim_filter_empty($instantly_lockout_specific_usernames) + ), + 'strlen' + ) + ); + + $response['message'] = __('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall'); + + if (!empty($invalid_fields)) { + $invalid_fields = array_unique($invalid_fields); + $invalid_fields = implode(", ", $invalid_fields); + $response['info'][] = sprintf(__('The following options had invalid values and have been set to the defaults: %s', 'all-in-one-wp-security-and-firewall'), $invalid_fields); + } + + $options = array(); + + // Save all the form values to the options + $random_20_digit_string = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(20); // Generate random 20 char string for use during CAPTCHA encode/decode + $options['aiowps_unlock_request_secret_key'] = $random_20_digit_string; + + $options['aiowps_enable_login_lockdown'] = isset($data["aiowps_enable_login_lockdown"]) ? '1' : ''; + $options['aiowps_allow_unlock_requests'] = isset($data["aiowps_allow_unlock_requests"]) ? '1' : ''; + $options['aiowps_max_login_attempts'] = absint($max_login_attempt_val); + $options['aiowps_retry_time_period'] = absint($login_retry_time_period); + $options['aiowps_lockout_time_length'] = absint($lockout_time_length); + $options['aiowps_max_lockout_time_length'] = absint($max_lockout_time_length); + $options['aiowps_set_generic_login_msg'] = isset($data["aiowps_set_generic_login_msg"]) ? '1' : ''; + $options['aiowps_enable_invalid_username_lockdown']= isset($data["aiowps_enable_invalid_username_lockdown"]) ? '1' : ''; + $options['aiowps_instantly_lockout_specific_usernames'] = $instantly_lockout_specific_usernames; + $options['aiowps_enable_email_notify'] = isset($data["aiowps_enable_email_notify"]) ? '1' : ''; + $options['aiowps_enable_php_backtrace_in_email'] = isset($data['aiowps_enable_php_backtrace_in_email']) ? '1' : ''; + $options['aiowps_email_address'] = $email_address_list; + $this->save_settings($options); + + $response['values']['aiowps_max_login_attempts'] = absint($max_login_attempt_val); + $response['values']['aiowps_retry_time_period'] = absint($login_retry_time_period); + $response['values']['aiowps_lockout_time_length'] = absint($lockout_time_length); + $response['values']['aiowps_max_lockout_time_length'] = absint($max_lockout_time_length); + $response['values']['aiowps_email_address'] = implode("\n", $email_address_list); + + $response['badges'] = $this->get_features_id_and_html(array('user-login-login-lockdown')); + + return $response; + } + + /** + * Performs the action to save the login lockout whitelist settings. + * + * @param array $data An array containing the data to be saved. + * The array may contain the following keys: + * - 'aiowps_lockdown_enable_whitelisting': A boolean indicating whether whitelisting is enabled. + * - 'aiowps_lockdown_allowed_ip_addresses': The allowed IP addresses for whitelisting. + * @return array Returns an array containing the status of the operation ('success' or 'error'), + * a message indicating the result of the operation, + * and a badge representing the updated feature details. + */ + public function perform_save_login_lockout_whitelist_settings($data) { + global $aio_wp_security; + + $response = array( + 'status' => 'success' + ); + + $options = array(); + $result = 1; + + if (!empty($data['aiowps_lockdown_allowed_ip_addresses'])) { + $ip_addresses = sanitize_textarea_field(wp_unslash($data['aiowps_lockdown_allowed_ip_addresses'])); + $ip_list_array = AIOWPSecurity_Utility_IP::create_ip_list_array_from_string_with_newline($ip_addresses); + $validated_ip_list_array = AIOWPSecurity_Utility_IP::validate_ip_list($ip_list_array, 'whitelist'); + if (is_wp_error($validated_ip_list_array)) { + $result = -1; + $response['status'] = 'error'; + $response['message'] = AIOWPSecurity_Admin_Menu::show_msg_error_st(nl2br($validated_ip_list_array->get_error_message()), true); + } else { + $allowed_ip_data = implode("\n", $validated_ip_list_array); + $options['aiowps_lockdown_allowed_ip_addresses'] = $allowed_ip_data; + } + } else { + $options['aiowps_lockdown_allowed_ip_addresses'] = ''; //Clear the IP address config value + } + + if (1 == $result) { + $aio_wp_security->configs->set_value('aiowps_lockdown_enable_whitelisting', isset($data["aiowps_lockdown_enable_whitelisting"]) ? '1' : '', true); + $response['message'] = __('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall'); + $response['badges'] = $this->get_features_id_and_html(array('user-login-lockout-ip-whitelisting')); + } + + $this->save_settings($options); + + return $response; + } + + /** + * Performs the action to force logout users. + * + * @param array $data An array containing the data to be saved. + * The array may contain the following keys: + * - 'aiowps_logout_time_period': The time period (in minutes) for logout. + * - 'aiowps_enable_forced_logout': A boolean indicating whether forced logout is enabled. + * @return array Returns an array containing the status of the operation ('success' or 'error'), + * an array of messages indicating the result of the operation, + * the content representing the logout time period, + * and a badge representing the updated feature details. + */ + public function perform_force_logout($data) { + global $aio_wp_security; + $response = array( + 'status' => 'success', + 'info' => array(), + 'values' => array() + ); + + $options = array(); + + + $logout_time_period = sanitize_text_field($data['aiowps_logout_time_period']); + if (isset($data["aiowps_enable_forced_logout"]) && (!is_numeric($logout_time_period) || $logout_time_period < 1)) { + $response['info'][] = __('You entered a non numeric or negative value for the logout time period field, it has been set to the default value.', 'all-in-one-wp-security-and-firewall'); + $logout_time_period = '60'; // Set it to the default value for this field + } + + // Save all the form values to the options + $options['aiowps_logout_time_period'] = absint($logout_time_period); + $options['aiowps_enable_forced_logout'] = isset($data["aiowps_enable_forced_logout"]) ? '1' : ''; + $this->save_settings($options); + + $response['values']['aiowps_logout_time_period'] = absint($logout_time_period); + $response['badges'] = $this->get_features_id_and_html(array('user-login-force-logout')); + $response['message'] = __('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall'); + + if ('1' === $options['aiowps_enable_forced_logout']) { + $response['logout_user'] = $this->check_logout_user(); + $response['logout_url'] = $aio_wp_security->user_login_obj->aiowps_force_logout_action_handler(true); + } + + return $response; + } + + /** + * Performs the action to save the HIBP settings. + * + * @param array $data An array containing the data to be saved. + * + * @return array Returns an array containing the status of the operation ('success' or 'error'), + * a message indicating the result of the operation, + * and a badge representing the updated feature details. + */ + public function perform_save_hibp_settings($data) { + global $aio_wp_security; + + $aio_wp_security->configs->set_value('aiowps_hibp_user_profile_update', isset($data['aiowps_hibp_user_profile_update']) ? '1' : '', true); + $aio_wp_security->configs->set_value('aiowps_http_password_reset', isset($data['aiowps_http_password_reset']) ? '1' : '', true); + $aio_wp_security->configs->save_config(); + + return $this->handle_response(true, false, array('badges' => array('hibp'))); + } + + /** + * Performs the action to disable application password. + * + * @param array $data An array containing the data to be saved. + * The array may contain the following key: + * - 'aiowps_disable_application_password': A boolean indicating whether application password is disabled. + * @return array Returns an array containing the status of the operation ('success' or 'error'), + * a message indicating the result of the operation, + * and a badge representing the updated feature details. + */ + public function perform_disable_application_password($data) { + global $aio_wp_security; + + // Save all the form values to the options + $aio_wp_security->configs->set_value('aiowps_disable_application_password', isset($data['aiowps_disable_application_password']) ? '1' : '', true); + + return array( + 'status' => 'success', + 'message' => __('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall'), + 'badges' => $this->get_features_id_and_html(array('disable-application-password')) + ); + } + + /** + * Performs the action to add salt postfix. + * + * @param array $data An array containing the data to be saved. + * The array may contain the following key: + * - 'aiowps_enable_salt_postfix': A boolean indicating whether salt postfix is enabled. + * @return array Returns an array containing the status of the operation ('success' or 'error'), + * a message indicating the result of the operation, + * and a badge representing the updated feature details. + */ + public function perform_add_salt_postfix($data) { + global $aio_wp_security; + + $response = array( + 'status' => 'success' + ); + + // Save settings + $aiowps_enable_salt_postfix = isset($data['aiowps_enable_salt_postfix']) ? '1' : ''; + if ($aiowps_enable_salt_postfix == $aio_wp_security->configs->get_value('aiowps_enable_salt_postfix')) { + $is_setting_changed = true; + } else { + $is_setting_changed = false; + } + + $aio_wp_security->configs->set_value('aiowps_enable_salt_postfix', $aiowps_enable_salt_postfix, true); + $ret_schedule = $this->schedule_change_auth_keys_and_salt(); + + if (is_wp_error($ret_schedule)) { + $aio_wp_security->debug_logger->log_debug($ret_schedule->get_error_message(), 4); + } + + if ('1' == $aiowps_enable_salt_postfix && $is_setting_changed) { + AIOWPSecurity_Utility::change_salt_postfixes(); + } + + $response['message'] = __('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall'); + $response['badges'] = $this->get_features_id_and_html(array('enable-salt-postfix')); + + return $response; + } + + /** + * Performs actions on logged-in users. + * + * @param array $data An array containing the data for the action to be performed. + * The array may contain the following keys: + * - 'action': The action to be performed on logged-in users (e.g., 'force_user_logout'). + * - 'logged_in_id': The ID of the logged-in user on which the action will be performed. + * @return array Returns an array containing the status of the operation ('success' or 'error'), + * and a message indicating the result of the operation. + */ + public function perform_logged_in_user_action($data) { + global $aio_wp_security; + include_once AIO_WP_SECURITY_PATH.'/admin/wp-security-list-logged-in-users.php'; // For rendering the AIOWPSecurity_List_Table + $user_list = new AIOWPSecurity_List_Logged_In_Users(); + $response = array( + 'status' => 'success' + ); + + if (empty($data['action']) || !in_array($data['action'], array('force_user_logout'))) { // more actions can be added + return array( + 'status' => 'error', + 'message' => __('Invalid action provided for logged in user.', 'all-in-one-wp-security-and-firewall') + ); + } + + if ('force_user_logout' == $data['action']) { + if (empty($data['logged_in_id'])) { + return array( + 'status' => 'error', + 'message' => __('No user ID was provided', 'all-in-one-wp-security-and-firewall') + ); + } + $user_id = strip_tags($data['logged_in_id']); + $error = ''; + + if (!is_numeric($user_id)) { + $error = __("Invalid user ID provided.", 'all-in-one-wp-security-and-firewall'); + } elseif (get_current_user_id() == $user_id) { + $error = __("You cannot log yourself out", 'all-in-one-wp-security-and-firewall'); + } elseif (is_super_admin($user_id)) { + $error = __("Super admins cannot be logged out.", 'all-in-one-wp-security-and-firewall'); + } elseif (!AIOWPSecurity_Utility::is_user_member_of_blog($user_id)) { + $error = __("You cannot log out a user from a different subsite.", 'all-in-one-wp-security-and-firewall'); + } + if ($error) { + return array( + 'message' => $error, + 'status' => 'error' + ); + } + + $users = esc_sql($user_id); + $result = $aio_wp_security->user_login_obj->delete_logged_in_user($users); + + if ($result) { + $user_list->logout_user($users); + $response['message'] = __('The selected user has been logged out successfully.', 'all-in-one-wp-security-and-firewall'); + } else { + $response['message'] = __('Failed to log out the selected user.', 'all-in-one-wp-security-and-firewall'); + $response['status'] = 'error'; + } + + } + + return $response; + } + + /** + * Performs the action to configure manual registration approval settings. + * + * @param array $data An array containing the data to be saved. + * The array may contain the following key: + * - 'aiowps_enable_manual_registration_approval': A boolean indicating whether manual registration approval is enabled. + * @return array Returns an array containing the status of the operation ('success' or 'error'), + * a message indicating the result of the operation, + * and a badge representing the updated feature details. + */ + public function perform_manual_approval_settings($data) { + global $aio_wp_security; + + // Save settings + $aio_wp_security->configs->set_value('aiowps_enable_manual_registration_approval', isset($data["aiowps_enable_manual_registration_approval"]) ? '1' : '', true); + + return array( + 'status' => 'success', + 'message' => __('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall'), + 'badges' => $this->get_features_id_and_html(array('manually-approve-registrations')) + ); + } + + /** + * Performs actions on manual approval items (e.g., approve account, delete account, block IP). + * + * @param array $data An array containing the data for the action to be performed. + * The array may contain the following keys: + * - 'action': The action to be performed on the manual approval item (e.g., 'approve_acct', 'delete_acct', 'block_ip'). + * - 'user_id': The ID of the user for whom the action will be performed (applicable for 'approve_acct' and 'delete_acct' actions). + * - 'ip_address': The IP address to be blocked (applicable for 'block_ip' action). + * @return array Returns an array containing the status of the operation ('success' or 'error'), + * and a message indicating the result of the operation. + */ + public function perform_manual_approval_item_action($data) { + global $aio_wp_security; + + include_once AIO_WP_SECURITY_PATH.'/admin/wp-security-list-registered-users.php'; // For rendering the AIOWPSecurity_List_Table + $user_list = new AIOWPSecurity_List_Registered_Users(); + $status = 'error'; + + $valid_actions = array('approve_acct', 'delete_acct', 'block_ip'); + if (empty($data['action']) || !in_array($data['action'], $valid_actions)) { // more actions can be added + return array( + 'status' => 'error', + 'message' => __('Invalid action provided for registered user.', 'all-in-one-wp-security-and-firewall') + ); + } + + switch ($data['action']) { + case 'approve_acct': + if (empty($data['user_id'])) { + return array( + 'status' => 'error', + 'message' => __('No valid user ID was provided', 'all-in-one-wp-security-and-firewall') + ); + } + $user_id = esc_sql(strip_tags($data['user_id'])); + $meta_key = 'aiowps_account_status'; + $meta_value = 'approved'; // set account status + + // Approve single account + $result = update_user_meta($user_id, $meta_key, $meta_value); + if ($result) { + $user = get_user_by('id', $user_id); + $user_list->send_email_upon_account_activation($user); + $message = __('The selected account was approved successfully.', 'all-in-one-wp-security-and-firewall'); + $status = 'success'; + } elseif (false === $result) { + $aio_wp_security->debug_logger->log_debug("could not approve account ID: $user_id", 4); + $message = __('The selected account could not be approved.', 'all-in-one-wp-security-and-firewall'); + } + break; + case 'delete_acct': + if (empty($data['user_id'])) { + return array( + 'status' => 'error', + 'message' => __('No valid user ID was provided', 'all-in-one-wp-security-and-firewall') + ); + } + + $user_id = esc_sql(strip_tags($data['user_id'])); + // Delete single account + $result = wp_delete_user($user_id); + if (true === $result) { + $message = __('The selected account was deleted successfully.', 'all-in-one-wp-security-and-firewall'); + $status = 'success'; + } else { + $aio_wp_security->debug_logger->log_debug("could not delete account ID: $user_id", 4); + $message = __('The selected account could not be deleted.', 'all-in-one-wp-security-and-firewall'); + } + break; + case 'block_ip': + if (empty($data['ip_address'])) { + return array( + 'status' => 'error', + 'message' => __('No valid IP address was provided', 'all-in-one-wp-security-and-firewall') + ); + } + + $ip = esc_sql(strip_tags($data['ip_address'])); + + if (AIOWPSecurity_Utility_IP::get_user_ip_address() == $ip) { + $message = __('You cannot block your own IP address:', 'all-in-one-wp-security-and-firewall') . ' ' . $ip; + break; + } + + // Block single IP + $result = AIOWPSecurity_Blocking::add_ip_to_block_list($ip, 'registration_spam'); + if (true === $result) { + $message = __('The selected IP was successfully added to the permanent block list.', 'all-in-one-wp-security-and-firewall'); + $message .= ' '.__('View Blocked IPs', 'all-in-one-wp-security-and-firewall').''; + $status = 'success'; + } else { + $aio_wp_security->debug_logger->log_debug("AIOWPSecurity_List_Registered_Users::block_selected_ips() - could not block IP: $ip", 4); + $message = __('The selected IP could not be added to the permanent block list.', 'all-in-one-wp-security-and-firewall'); + } + break; + } + + return array( + 'status' => $status, + 'message' => $message + ); + } + + /** + * Schedule weekly aios_change_auth_keys_and_salt cron event. + * + * @return Boolean|WP_Error True if event successfully scheduled. False or WP_Error on failure. + */ + private function schedule_change_auth_keys_and_salt() { + $previous_time = wp_next_scheduled('aios_change_auth_keys_and_salt'); + + if (false !== $previous_time) { + // Clear schedule so that we don't stack up scheduled backups + wp_clear_scheduled_hook('aios_change_auth_keys_and_salt'); + } + $gmt_offset_in_seconds = floatval(get_option('gmt_offset')) * 3600; + $first_time = strtotime('next Sunday '.apply_filters('aios_salt_change_schedule_time', '3:00 am')) + $gmt_offset_in_seconds; + return wp_schedule_event($first_time, 'weekly', 'aios_change_auth_keys_and_salt'); + } + + /** + * Checks if the current user should be automatically logged out based on last login time. + * + * This method compares the current time with the last login time of the user and determines + * if the user should be logged out based on a configured logout time period. + * + * @return bool Returns true if the user should be logged out, false otherwise. + */ + private function check_logout_user() { + global $aio_wp_security; + + // Get the current user + $current_user = wp_get_current_user(); + $user_id = $current_user->ID; + + // Get the current and last login times + $current_time = current_time('mysql', true); + $login_time = $aio_wp_security->user_login_obj->get_wp_user_aiowps_last_login_time($user_id); + + // Return false if login time is empty (no last login recorded) + if (empty($login_time)) { + return false; + } + + // Calculate the time difference between current time and last login time + $diff = strtotime($current_time) - strtotime($login_time); + + // Get the configured logout time period in seconds + $logout_time_interval_value = $aio_wp_security->configs->get_value('aiowps_logout_time_period'); + $logout_time_interval_val_seconds = $logout_time_interval_value * 60; + + // Return true if the time difference exceeds the logout time interval, indicating the user should be logged out + return $diff > $logout_time_interval_val_seconds; + } + + /** + * Whitelists user's IP address + * + * @return array Returns an array containing the status of the operation ('success' or 'error'), + * a message indicating the result of the operation, + * and a badge representing the updated feature details. + */ + public function perform_whitelist_user_ip() { + $response = array( + 'status' => 'success' + ); + + if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) { + $response['status'] = 'error'; + $response['message'] = __('You don\'t have enough permissions to whitelist your IP address.', 'all-in-one-wp-security-and-firewall'); + return $response; + } + + $aiowps_firewall_allow_list = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::ALLOW_LIST); + + $whitelisted_ips = $aiowps_firewall_allow_list::get_ips(); + $is_whitelisted = $aiowps_firewall_allow_list::is_ip_allowed(); + + if ($is_whitelisted) { + $response['status'] = 'error'; + $response['message'] = __('Your IP address is already whitelisted.', 'all-in-one-wp-security-and-firewall'); + return $response; + } else { + $user_ip = AIOWPSecurity_Utility_IP::get_user_ip_address(); + + if (empty($user_ip)) { + $response['status'] = 'error'; + $response['message'] = __('Your IP address could not be detected.', 'all-in-one-wp-security-and-firewall'); + return $response; + } + + $whitelisted_ips .= (empty($whitelisted_ips) ? '' : "\n") . $user_ip; + + if (!$aiowps_firewall_allow_list::add_ips($whitelisted_ips)) { + $response['status'] = 'error'; + $response['message'] = __('There was an error whitelisting your IP address, please try again.', 'all-in-one-wp-security-and-firewall'); + return $response; + } + + $response['message'] = __('Your IP address has been whitelisted successfully.', 'all-in-one-wp-security-and-firewall'); + return $response; + } + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/family/wp-security-firewall-families.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/family/wp-security-firewall-families.php new file mode 100755 index 00000000..4baa25b0 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/family/wp-security-firewall-families.php @@ -0,0 +1,13 @@ + '6G', 'priority' => 10), + array('name' => 'Blacklist', 'priority' => 1), + array('name' => 'Bruteforce', 'priority' => 0), + array('name' => 'General', 'priority' => 20), + array('name' => 'Bots', 'priority' => 2), +); diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/family/wp-security-firewall-family-builder.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/family/wp-security-firewall-family-builder.php new file mode 100755 index 00000000..fce6d629 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/family/wp-security-firewall-family-builder.php @@ -0,0 +1,33 @@ + $member2['priority']) ? 1 : -1; + }); + + $families = array(); + foreach ($family_list as $member) { + $families[strtolower($member['name'])] = new Family($member['name'], $member['priority']); + } + + return $families; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/family/wp-security-firewall-family-collection.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/family/wp-security-firewall-family-collection.php new file mode 100755 index 00000000..5305d870 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/family/wp-security-firewall-family-collection.php @@ -0,0 +1,49 @@ +families = $families; + } + + /** + * Generator method to iterate over the families + * + * @return iterable + */ + public function get_family() { + foreach ($this->families as $family) { + yield $family; + } + } + + /** + * Adds a new rule to a family member + * + * @param Rule $rule - an active rule to add to its family + * @return void + */ + public function add_rule_to_member(Rule $rule) { + $key = strtolower($rule->family); + if (array_key_exists($key, $this->families)) { + $this->families[$key]->add_rule($rule); + } + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/family/wp-security-firewall-family.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/family/wp-security-firewall-family.php new file mode 100755 index 00000000..d9631ec9 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/family/wp-security-firewall-family.php @@ -0,0 +1,86 @@ +name = $name; + $this->priority = $priority; + $this->rules = array(); + } + + /** + * Adds a rule to the family + * + * @param Rule $rule + * @return void + */ + public function add_rule(Rule $rule) { + $this->rules[] = $rule; + } + + /** + * Applies all the rules in the family + * + * @return void + */ + public function apply_all() { + + if (empty($this->rules)) { + return; + } + + //ensure the rules are ordered by priority + usort($this->rules, function(Rule $rule, Rule $rule2) { + if ($rule->priority == $rule2->priority) { + return 0; + } + return ($rule->priority > $rule2->priority) ? 1 : -1; + }); + + foreach ($this->rules as $rule) { + $rule->apply(); + } + + } + + /** + * Returns the family name if used as a string + * + * @return string + */ + public function __toString() { + return $this->name; + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/traits/file-prefix-trait.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/traits/file-prefix-trait.php new file mode 100755 index 00000000..b1ed55a1 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/traits/file-prefix-trait.php @@ -0,0 +1,30 @@ +path = $path; + $this->init_file(); + } + + /** + * Initialise the file if it doesn't exist + * + * @return void + */ + private function init_file() { + clearstatcache(); + if (!file_exists($this->path)) { + + $dir = dirname($this->path); + if (!file_exists($dir)) Utility::wp_mkdir_p($dir); + + file_put_contents($this->path, self::get_file_content_prefix() . json_encode(array())); + } + } + + /** + * Update the config file with the new prefix whenever the prefix changes. + * + * @return void + */ + public function update_prefix() { + + $valid_prefix = self::get_file_content_prefix(); + $current_prefix = file_get_contents($this->path, false, null, 0, strlen($valid_prefix)); + + if ($current_prefix === $valid_prefix) return; // prefix is valid + + $contents = file_get_contents($this->path); + + $matches = array(); + if (preg_match('/\{.*\}/', $contents, $matches)) { + //update settings + file_put_contents($this->path, $valid_prefix . $matches[0]); + } else { + //reset settings + file_put_contents($this->path, $valid_prefix . json_encode(array())); + } + } + + /** + * Gets the value from the config array + * + * @param string $key + * @return mixed|null + */ + public function get_value($key) { + + $contents = $this->get_contents(); + + if (null === $contents) { + return null; + } + + if (!isset($contents[$key])) { + return null; + } + + return $contents[$key]; + + } + + /** + * Sets a value in our config array + * + * @param string $key + * @param mixed $value + * @return boolean + */ + public function set_value($key, $value) { + + $contents = $this->get_contents(); + + if (null === $contents) { + return false; + } + + $contents[$key] = $value; + + return (false !== file_put_contents($this->path, self::get_file_content_prefix() . json_encode($contents), LOCK_EX)); + } + + /** + * Loads the config array from file + * + * @return string + */ + public function get_contents() { + + clearstatcache(); + if (!file_exists($this->path)) $this->init_file(); + + // __COMPILER_HALT_OFFSET__ doesn't define in a few PHP versions. It's a PHP bug. + // https://bugs.php.net/bug.php?id=70164 + $contents = file_get_contents($this->path, false, null, strlen(self::get_file_content_prefix())); + + if (false === $contents) { + return null; + } + + if (empty($contents)) { + return array(); + } + + return json_decode($contents, true); + } + + /** + * Sets entire firewall config from array. + * + * @param Array $contents + * + * @return Boolean + */ + public function set_contents($contents) { + + if (null === $contents) { + return false; + } + + return (false !== file_put_contents($this->path, self::get_file_content_prefix() . json_encode($contents), LOCK_EX)); + } + + /** + * Returns the path + * + * @return string + */ + public function __toString() { + return $this->path; + } + +} + +// phpcs:enable WordPress.WP.AlternativeFunctions -- WP isn't loaded here. WP API is unavailable diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-constants.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-constants.php new file mode 100755 index 00000000..543780e7 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-constants.php @@ -0,0 +1,213 @@ +constants = array(); + $this->populate_constants(); + } + + /** + * Populates our internal constant array with the defines from wp-config + * + * @return void + */ + protected function populate_constants() { + + $wpconfig = Utility::get_wpconfig_path(); + + clearstatcache(); + if (!file_exists($wpconfig)) return; + + // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- WP isn't loaded. WP_Filesystem cannot be used. + $source = file_get_contents($wpconfig); + + if (false === $source) return; + + $tokens = token_get_all($source); + + //Filter out any unwanted tokens + $tokens = array_values(array_filter($tokens, function($token) { + + //All tokens that are not arrays are allowed + if (!is_array($token)) return true; + + $unwanted_tokens = array( + 'T_COMMENT', + 'T_WHITESPACE', + 'T_DOC_COMMENT', + ); + + return (!in_array(token_name($token[self::TOKEN]), $unwanted_tokens)); + })); + + $token_count = count($tokens); + for ($i = 0; $i < $token_count; $i++) { + + $current = $tokens[$i]; + + if (!is_array($current)) continue; + + if ('T_STRING' === token_name($current[self::TOKEN]) && 'define' === strtolower($current[self::CONTENT])) { + + // Name of the define without the surrounding quotes + $name = substr($tokens[$i + self::DEFINE_NAME_OFFSET][self::CONTENT], 1, -1); + + // Grabs the value of the define + $value = $tokens[$i + self::DEFINE_VALUE_OFFSET]; + + if (!is_array($value)) continue; + + // We need to interpret the data type of the define's value + switch (token_name($value[self::TOKEN])) { + case 'T_CONSTANT_ENCAPSED_STRING': + $this->constants[$name] = substr($value[self::CONTENT], 1, -1); + break; + case 'T_LNUMBER': + $this->constants[$name] = intval($value[self::CONTENT]); + break; + case 'T_DNUMBER': + $this->constants[$name] = floatval($value[self::CONTENT]); + break; + case 'T_STRING': + $this->constants[$name] = filter_var($value[self::CONTENT], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); + break; + default: + continue 2; + } + } + } + + } + + /** + * Access the constants as properties + * + * @param string $name + * @return mixed + */ + public function __get($name) { + return $this[$name]; + } + + /** + * Iterate over the constants + * + * @return iterable + */ + #[\ReturnTypeWillChange] + public function getIterator() { + foreach ($this->constants as $name => $value) yield $name => $value; + foreach (get_defined_constants() as $name => $value) yield $name => $value; + } + + /** + * Gives us array access to the constants + * + * @param mixed $offset + * @return mixed + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) { + if (defined($offset)) { + return constant($offset); + } elseif (isset($this->constants[$offset])) { + return $this->constants[$offset]; + } else { + return null; + } + } + + /** + * Checks if the constant exists + * + * @param mixed $offset + * @return boolean + */ + #[\ReturnTypeWillChange] + public function offsetExists($offset) { + return defined($offset) || isset($this->constants[$offset]); + } + + /** + * Check if constant exists + * + * @param string $name + * @return boolean + */ + public function __isset($name) { + return $this->offsetExists($name); + } + + /** + * Sets the constant. This is disabled as we want it read-only + * + * @param mixed $offset + * @param mixed $value + * @return void + * @throws \Exception - Throws an exception if called to ensure it's read-only. + */ + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Needed for ArrayAccess interface but not used by us as we require read-only + throw new \Exception('Constants are read-only.'); + } + + /** + * Unsets the constant. This is disabled as we want it read-only + * + * @param mixed $offset + * @return void + * @throws \Exception - Throws an exception if called to ensure it's read-only. + */ + #[\ReturnTypeWillChange] + public function offsetUnset($offset) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Needed for ArrayAccess interface but not used by us as we require read-only + throw new \Exception('Constants are read-only.'); + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-debug.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-debug.php new file mode 100755 index 00000000..44fc04d7 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-debug.php @@ -0,0 +1,59 @@ +AIOS_FIREWALL_DEBUG && 'rule_triggered' !== $event) return; + + $details = array( + 'name' => $rule->name, + 'family' => $rule->family, + 'ip' => \AIOS_Helper::get_user_ip_address(), + 'time' => time(), + ); + + // Get any user information + foreach ($_COOKIE as $key => $value) { + if (preg_match('/^wordpress_logged_in_/', $key)) { + $details['potential_user'] = stripslashes($value); + break; + } + } + + $details['request'] = $_SERVER; + unset($details['request']['HTTP_COOKIE']); + + // Uncomment when the firewall log issues have been resolved + //$aiowps_firewall_message_store->set($event, $details); + + // Remove when the firewall log issues have been resolved + $aiowps_firewall_message_store->clear_message_store(); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-event.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-event.php new file mode 100755 index 00000000..c308feb3 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-event.php @@ -0,0 +1,51 @@ +messages = array(); + $this->keys_loaded = array(); + $this->table_name = 'aiowps_message_store'; + } + + /** + * Sets internal message store + * + * @param string $key + * @param mixed $value + * @return void + */ + public function set($key, $value) { + + if (!is_string($key)) return; + + if (!isset($this->messages[$key])) { + $this->messages[$key] = array(); + } + + $this->messages[$key][] = $value; + } + + /** + * Gets the messages associated with a key + * + * @param string $key + * @return array + */ + public function get($key) { + + $is_key_loaded = in_array($key, $this->keys_loaded); + $can_check_database = isset($GLOBALS['wpdb']) && !$is_key_loaded && class_exists('Updraft_Semaphore_3_0'); + + //Load requested messages from the database + if ($can_check_database) { + + $lock = new \Updraft_Semaphore_3_0('aios_message_store_lock_'.$key, 60); + $to_delete = array(); + + if ($lock->lock()) { + + try { + global $wpdb; + + $table = $this->get_table(); + + // If we can't get the table to check the DB, still check our internal store for the key + if (empty($table)) return isset($this->messages[$key]) ? $this->messages[$key] : array(); + + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $rows = $wpdb->get_results($wpdb->prepare("SELECT id, message_value FROM `{$table}` WHERE message_key = %s", $key)); + + if (!empty($rows)) { + + foreach ($rows as $row) { + $values = json_decode($row->message_value, true); + + foreach ($values as $value) $this->set($key, $value); + + $to_delete[] = $row->id; + } + + $this->keys_loaded[] = $key; + } + } catch (\Exception $e) { + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- PCP warning. Necessary for AIOS error reporting system. + error_log("AIOS: Error getting database entries for key '{$key}': {$e->getMessage()}"); + + } catch (\Error $e) { // phpcs:ignore PHPCompatibility.Classes.NewClasses.errorFound -- this won't run on PHP 5.6 so we still want to catch it on other versions + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- PCP warning. Necessary for AIOS error reporting system. + error_log("AIOS: Error getting database entries for key '{$key}': {$e->getMessage()}"); + } finally { + + //Delete IDs of loaded messages + if (!empty($to_delete)) { + $ids = implode(',', $to_delete); + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $wpdb->query("DELETE FROM `{$table}` WHERE id IN ({$ids})"); + } + + $lock->release(); + } + + } + } + + return isset($this->messages[$key]) ? $this->messages[$key] : array(); + } + + /** + * Dumps the message store to the database + * + * @return void + */ + public function dump() { + //No point saving if there are no messages + if (empty($this->messages)) return; + + if (!Utility::attempt_to_access_wpdb()) throw new Exit_Exception('Unable to save the message store to the database: wpdb is inaccessible.'); + + global $wpdb; + + $table = $this->get_table(); + + if (empty($table)) throw new Exit_Exception('Unable to save messages store to the database: unable to get the correct table.'); + + $statement = "INSERT INTO `{$table}` (message_key, message_value, created) VALUES "; + $values = array(); + + foreach ($this->messages as $key => $value) { + $statement .= '(%s, %s, %s),'; + $values[] = $table; + $values[] = $key; + $values[] = json_encode($value); // phpcs:ignore WordPress.WP.AlternativeFunctions.json_encode_json_encode -- This method runs outside the WordPress environment and therefore cannot use WordPress functions. + $values[] = time(); + } + + $statement = rtrim($statement, ','); + + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Prepared above. + $wpdb->query($wpdb->prepare($statement, $values)); + } + + /** + * Returns the table name if it exists + * + * @return string - Table name on success; blank string otherwise + */ + private function get_table() { + global $wpdb; + + if (!$wpdb) return ''; + + $table = $wpdb->get_blog_prefix(0).$this->table_name; + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + if ($table != $wpdb->get_var("SHOW TABLES LIKE '{$table}'")) return ''; + + return $table; + } + + /** + * Clears all the messages from the message store table if it contains data. + * + * @return void + */ + public function clear_message_store() { + global $wpdb; + + $table = $this->get_table(); + + // Check if the table exists and is accessible + if (empty($table)) { + return; + } + + //Check if the table has any rows + // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- PCP warning. Direct query necessary. No caching necessary. + $row_exists = $wpdb->get_var( + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- PCP error. Ignore. + $wpdb->prepare("SELECT EXISTS (SELECT 1 FROM `{$table}` LIMIT 1)") + ); + + // If there are no rows, $row_exists will be 0 + if (!$row_exists) { + return; + } + + // Clear the table (delete all records) + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $wpdb->query($wpdb->prepare("DELETE FROM `{$table}`")); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-singleton-trait.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-singleton-trait.php new file mode 100755 index 00000000..1cf77d83 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/libs/wp-security-firewall-singleton-trait.php @@ -0,0 +1,36 @@ +do_action_forbid(); + $this->do_action_exit(); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/actions/action-forbid-trait.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/actions/action-forbid-trait.php new file mode 100755 index 00000000..f583a3c7 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/actions/action-forbid-trait.php @@ -0,0 +1,17 @@ +permblock_reason = $reason; + } + + /** + * Sets the IP for the perm. block + * + * @param string $ip + * @return void + */ + public function set_perm_block_ip($ip) { + $this->permblock_ip = $ip; + } + + /** + * Permanently ban the IP and exit when the rule condition is satisfied. + * + * @return void + */ + public function do_action() { + + if (!Utility::attempt_to_access_wpdb()) { + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- PCP warning. Part of AIOS error reporting system. + error_log('AIOS: Unable to access wpdb to ban IP address.'); + $this->do_action_forbid_and_exit(); + } + + global $wpdb; + + $table = $wpdb->prefix.'aiowps_permanent_block'; + + $ip = empty($this->permblock_ip) ? \AIOS_Helper::get_user_ip_address() : $this->permblock_ip; + + $data = array( + 'blocked_ip' => $ip, + 'block_reason' => empty($this->permblock_reason) ? 'firewall_generic' : $this->permblock_reason, + 'blocked_date' => current_time('mysql') + ); + + // Check if the IP already exists + // phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery -- PCP error. Table name cannot be done via prepare. + $already_exists = $wpdb->get_var($wpdb->prepare("SELECT blocked_ip FROM `{$table}` WHERE blocked_ip = %s", $ip)); + + // If it does exist, no point adding it again so just forbid and exit + if (!is_null($already_exists)) $this->do_action_forbid_and_exit(); + + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Table name cannot be done via prepare. + if (false === $wpdb->query($wpdb->prepare("INSERT INTO " .$table." (blocked_ip, block_reason, blocked_date, created) VALUES (%s, %s, %s, UNIX_TIMESTAMP())", $data['blocked_ip'], $data['block_reason'], $data['blocked_date']))) { + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- PCP warning. Needed for error reporting. + error_log('AIOS: Unable to insert IP address into table.'); + } + + $this->do_action_forbid_and_exit(); + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/actions/action-redirect-and-exit-trait.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/actions/action-redirect-and-exit-trait.php new file mode 100755 index 00000000..a507e6d8 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/actions/action-redirect-and-exit-trait.php @@ -0,0 +1,23 @@ +do_action_redirect(); + $this->do_action_exit(); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/actions/action-redirect-trait.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/actions/action-redirect-trait.php new file mode 100755 index 00000000..9f3d286d --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/actions/action-redirect-trait.php @@ -0,0 +1,24 @@ +location"); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-block-query-strings-6g.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-block-query-strings-6g.php new file mode 100755 index 00000000..d83d9e03 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-block-query-strings-6g.php @@ -0,0 +1,62 @@ +name = 'Block query strings'; + $this->family = '6G'; + $this->priority = 0; + } + + /** + * Determines whether the rule is active + * + * @return boolean + */ + public function is_active() { + global $aiowps_firewall_config; + return (bool) $aiowps_firewall_config->get_value('aiowps_6g_block_query'); + } + + /** + * The condition to be satisfied for the rule to apply + * + * @return boolean + */ + public function is_satisfied() { + + if (empty($_SERVER['QUERY_STRING'])) return Rule::NOT_SATISFIED; + + //Patterns to match against + $patterns = array( + '/[a-z0-9]{2000,}/i', + '/(eval\()/i', + '/(127\.0\.0\.1)/i', + '/(javascript:)(.*)(;)/i', + '/(base64_encode)(.*)(\()/i', + '/(GLOBALS|REQUEST)(=|\[|%)/i', + '/(<|%3C)(.*)script(.*)(>|%3)/i', + '#(\|\.\.\.|\.\./|~|`|<|>|\|)#i', + '#(boot\.ini|etc/passwd|self/environ)#i', + '/(thumbs?(_editor|open)?|tim(thumb)?)\.php/i', + '/(\'|\")(.*)(drop|insert|md5|select|union)/i', + ); + + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitizing will interfere with 6g rules. + return Rule_Utils::contains_pattern(rawurldecode($_SERVER['QUERY_STRING']), $patterns); + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-block-refs-6g.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-block-refs-6g.php new file mode 100755 index 00000000..75ac3be4 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-block-refs-6g.php @@ -0,0 +1,52 @@ +name = 'Block referrer strings'; + $this->family = '6G'; + $this->priority = 0; + } + + /** + * Determines whether the rule is active + * + * @return boolean + */ + public function is_active() { + global $aiowps_firewall_config; + return (bool) $aiowps_firewall_config->get_value('aiowps_6g_block_referrers'); + } + + /** + * The condition to be satisfied for the rule to apply + * + * @return boolean + */ + public function is_satisfied() { + + if (empty($_SERVER['HTTP_REFERER'])) return Rule::NOT_SATISFIED; + + //Patterns to match against + $patterns = array( + '/[a-z0-9]{2000,}/i', + '/(semalt.com|todaperfeita)/i', + ); + + return Rule_Utils::contains_pattern($_SERVER['HTTP_REFERER'], $patterns); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- This is not a WordPress context. Also this only evaluates to a boolean. + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-block-request-strings-6g.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-block-request-strings-6g.php new file mode 100755 index 00000000..83a7ecb2 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-block-request-strings-6g.php @@ -0,0 +1,67 @@ +name = 'Block request strings'; + $this->family = '6G'; + $this->priority = 0; + } + + /** + * Determines whether the rule is active + * + * @return boolean + */ + public function is_active() { + global $aiowps_firewall_config; + return (bool) $aiowps_firewall_config->get_value('aiowps_6g_block_request'); + } + + /** + * The condition to be satisfied for the rule to apply + * + * @return boolean + */ + public function is_satisfied() { + + if (empty($_SERVER['REQUEST_URI'])) return Rule::NOT_SATISFIED; + + // ensure we get the request uri without the query string + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitizing will interfere with 6g rules. + $uri = (string) parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); + + if ('' == $uri) return Rule::NOT_SATISFIED; + + //Patterns to match against + $patterns = array( + '/[a-z0-9]{2000,}/i', + '#(https?|ftp|php):/#i', + '#(base64_encode)(.*)(\()#i', + '#(=\'|=\%27|/\'/?)\.#i', + '#/(\$(\&)?|\*|\"|\.|,|&|&?)/?$#i', + '#(\{0\}|\(/\(|\.\.\.|\+\+\+|\\"\\")#i', + '#(~|`|<|>|:|;|,|%|\|\s|\{|\}|\[|\]|\|)#i', + '#/(=|\$&|_mm|cgi-|etc/passwd|muieblack)#i', + '#(&pws=0|_vti_|\(null\)|\{\$itemURL\}|echo(.*)kae|etc/passwd|eval\(|self/environ)#i', + '#\.(aspx?|bash|bak?|cfg|cgi|dll|exe|git|hg|ini|jsp|log|mdb|out|sql|svn|swp|tar|rar|rdf)$#i', + '#/(^$|(wp-)?config|mobiquo|phpinfo|shell|sqlpatch|thumb|thumb_editor|thumbopen|timthumb|webshell)\.php#i', + ); + + return Rule_Utils::contains_pattern(rawurldecode($uri), $patterns); + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-block-user-agents-6g.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-block-user-agents-6g.php new file mode 100755 index 00000000..ca11be23 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-block-user-agents-6g.php @@ -0,0 +1,53 @@ +name = 'Block user-agents'; + $this->family = '6G'; + $this->priority = 0; + } + + /** + * Determines whether the rule is active + * + * @return boolean + */ + public function is_active() { + global $aiowps_firewall_config; + return (bool) $aiowps_firewall_config->get_value('aiowps_6g_block_agents'); + } + + /** + * The condition to be satisfied for the rule to apply + * + * @return boolean + */ + public function is_satisfied() { + + if (empty($_SERVER['HTTP_USER_AGENT'])) return Rule::NOT_SATISFIED; + + //Patterns to match against + $patterns = array( + '/[a-z0-9]{2000,}/i', + '/(archive.org|binlar|casper|checkpriv|choppy|clshttp|cmsworld|diavol|dotbot|extract|feedfinder|flicky|g00g1e|harvest|heritrix|httrack|kmccrew|loader|miner|nikto|nutch|planetwork|postrank|purebot|pycurl|python|seekerspider|siclab|skygrid|sqlmap|sucker|turnit|vikspider|winhttp|xxxyy|youda|zmeu|zune)/i', + ); + + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitizing will interfere with 6g rules. + return Rule_Utils::contains_pattern($_SERVER['HTTP_USER_AGENT'], $patterns); + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-request-method-6g.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-request-method-6g.php new file mode 100755 index 00000000..92552efb --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/6g/rule-request-method-6g.php @@ -0,0 +1,53 @@ +name = 'Block request methods'; + $this->family = '6G'; + $this->priority = 0; + + $this->blocked_methods = $aiowps_firewall_config->get_value('aiowps_6g_block_request_methods'); + } + + /** + * Determines whether the rule is active + * + * @return boolean + */ + public function is_active() { + return !empty($this->blocked_methods); + } + + /** + * The condition to be satisfied for the rule to apply + * + * @return boolean + */ + public function is_satisfied() { + return isset($_SERVER['REQUEST_METHOD']) && in_array(strtoupper($_SERVER['REQUEST_METHOD']), $this->blocked_methods); + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/blacklist/rule-ips-blacklist.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/blacklist/rule-ips-blacklist.php new file mode 100755 index 00000000..f2c6d557 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/blacklist/rule-ips-blacklist.php @@ -0,0 +1,65 @@ +name = 'Blocked IPs'; + $this->family = 'Blacklist'; + $this->priority = 0; + $this->blocked_ips = $aiowps_firewall_config->get_value('aiowps_blacklist_ips'); + } + + /** + * Determines whether the rule is active + * + * @global Constants $aiowps_firewall_constants + * + * @return boolean + */ + public function is_active() { + global $aiowps_firewall_constants; + if ($aiowps_firewall_constants->AIOS_DISABLE_BLACKLIST_IP_MANAGER) { + return false; + } else { + return !empty($this->blocked_ips); + } + } + + /** + * The condition to be satisfied for the rule to apply + * + * @return boolean + */ + public function is_satisfied() { + + $user_ip_blocked = \AIOS_Helper::is_user_ip_address_within_list($this->blocked_ips); + + if (true == $user_ip_blocked) return Rule::SATISFIED; + + return Rule::NOT_SATISFIED; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/blacklist/rule-user-agent-blacklist.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/blacklist/rule-user-agent-blacklist.php new file mode 100755 index 00000000..b9c44d80 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/blacklist/rule-user-agent-blacklist.php @@ -0,0 +1,57 @@ +name = 'Blocked user agents'; + $this->family = 'Blacklist'; + $this->priority = 0; + $this->blocked_user_agents = $aiowps_firewall_config->get_value('aiowps_blacklist_user_agents'); + } + + /** + * Determines whether the rule is active + * + * @return boolean + */ + public function is_active() { + return !empty($this->blocked_user_agents) && isset($_SERVER['HTTP_USER_AGENT']); + } + + /** + * The condition to be satisfied for the rule to apply + * + * @return boolean + */ + public function is_satisfied() { + foreach ($this->blocked_user_agents as $block_user_agent) { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitizing will interfere with 6g rules. + if (isset($_SERVER['HTTP_USER_AGENT']) && !empty($block_user_agent) && false !== stripos($_SERVER['HTTP_USER_AGENT'], $block_user_agent)) { + return Rule::SATISFIED; + } + } + return Rule::NOT_SATISFIED; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/bots/rule-ban-post-blank-headers.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/bots/rule-ban-post-blank-headers.php new file mode 100755 index 00000000..5f046c9a --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/bots/rule-ban-post-blank-headers.php @@ -0,0 +1,44 @@ +name = 'Ban POST requests with blank user-agent and referer'; + $this->family = 'Bots'; + $this->priority = 10; + } + + /** + * Determines whether the rule is active + * + * @return boolean + */ + public function is_active() { + global $aiowps_firewall_config; + return (bool) $aiowps_firewall_config->get_value('aiowps_ban_post_blank_headers'); + } + + /** + * The condition to be satisfied for the rule to apply + * + * @return boolean + */ + public function is_satisfied() { + $this->set_perm_block_reason('firewall_post_blank_user_agent_and_referer'); + return isset($_SERVER['REQUEST_METHOD']) && (0 === strcasecmp($_SERVER['REQUEST_METHOD'], "POST")) && empty($_SERVER['HTTP_USER_AGENT']) && empty($_SERVER['HTTP_REFERER']); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- This is not a WordPress context. Also this only evaluates to a boolean. + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/bots/rule-block-fake-googlebots.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/bots/rule-block-fake-googlebots.php new file mode 100755 index 00000000..a75a252c --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/bots/rule-block-fake-googlebots.php @@ -0,0 +1,101 @@ +name = 'Block fake Googlebots'; + $this->family = 'Bots'; + $this->priority = 0; + } + + /** + * Determines whether the rule is active. + * + * @global Config $aiowps_firewall_config + * + * @return boolean + */ + public function is_active() { + global $aiowps_firewall_config; + return (bool) $aiowps_firewall_config->get_value('aiowps_block_fake_googlebots'); + } + + /** + * The condition to be satisfied for the rule to apply. + * + * @global Config $aiowps_firewall_config + * + * @return boolean + */ + public function is_satisfied() { + global $aiowps_firewall_config; + + $user_agent = (isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''); + + if (preg_match('/Googlebot/i', $user_agent, $matches)) { + // If the user agent says it's a Googlebot, start doing checks. + + $ip = \AIOS_Helper::get_user_ip_address(); + + if (empty($ip)) { + return Rule::NOT_SATISFIED; + } + + try { + $name = gethostbyaddr($ip); // Let's get the hostname using the IP address. + + if ($name == $ip || false === $name) { + // gethostbyaddr failed. + $googlebot_ips = $aiowps_firewall_config->get_value('aiowps_googlebot_ip_ranges'); + if (\AIOS_Helper::is_user_ip_address_within_list($googlebot_ips)) { + return Rule::NOT_SATISFIED; + } else { + return Rule::SATISFIED; + } + } + + $host_ip = gethostbyname($name); // Reverse lookup - let's get the IP address using the hostname. + } catch (\Exception $e) { + // gethostbyaddr or gethostbyname not available on site. + $googlebot_ips = $aiowps_firewall_config->get_value('aiowps_googlebot_ip_ranges'); + if (\AIOS_Helper::is_user_ip_address_within_list($googlebot_ips)) { + return Rule::NOT_SATISFIED; + } else { + return Rule::SATISFIED; + } + } catch (\Error $e) { // phpcs:ignore PHPCompatibility.Classes.NewClasses.errorFound -- this won't run on PHP 5.6 so we still want to catch it on other versions + // gethostbyaddr or gethostbyname not available on site. + $googlebot_ips = $aiowps_firewall_config->get_value('aiowps_googlebot_ip_ranges'); + if (\AIOS_Helper::is_user_ip_address_within_list($googlebot_ips)) { + return Rule::NOT_SATISFIED; + } else { + return Rule::SATISFIED; + } + } + + if (preg_match('/^(?:.+\.)?googlebot\.com$/i', $name) || preg_match('/^(?:.+\.)?google\.com$/i', $name) || preg_match('/^(?:.+\.)?googleusercontent\.com$/i', $name)) { + if ($host_ip == $ip) { + return Rule::NOT_SATISFIED; + } else { + return Rule::SATISFIED; + } + } else { + return Rule::SATISFIED; + } + } + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/bruteforce/rule-cookie-prevent-bruteforce.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/bruteforce/rule-cookie-prevent-bruteforce.php new file mode 100755 index 00000000..13ea0c4c --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/bruteforce/rule-cookie-prevent-bruteforce.php @@ -0,0 +1,98 @@ +name = 'Cookie based prevent bruteforce'; + $this->family = 'Bruteforce'; + $this->priority = 0; + } + + /** + * Determines whether the rule is active + * + * @return boolean + */ + public function is_active() { + global $aiowps_firewall_config, $aiowps_firewall_constants; + if ($aiowps_firewall_constants->AIOS_DISABLE_COOKIE_BRUTE_FORCE_PREVENTION) { + return false; + } else { + return (bool) $aiowps_firewall_config->get_value('aios_enable_brute_force_attack_prevention'); + } + } + + /** + * The condition to be satisfied for the rule to apply + * + * @return boolean + */ + public function is_satisfied() { + global $aiowps_firewall_config; + /** + * This rule is not applied at AIOS plugin activation time. + */ + $is_plugins_page = isset($_SERVER['SCRIPT_FILENAME']) && 1 === preg_match('#/wp-admin/(network/)?plugins\.php$#i', $_SERVER['SCRIPT_FILENAME']); + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. A nonce is not available at this point. + $is_activation_action = isset($_GET['action']) && 'activate' === $_GET['action']; + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. A nonce is not available at this point. + $is_target_plugin = isset($_GET['plugin']) && 'all-in-one-wp-security-and-firewall/wp-security.php' === $_GET['plugin']; + + + if ($is_plugins_page && $is_activation_action && $is_target_plugin) { + return Rule::NOT_SATISFIED; + } + + $brute_force_secret_word = $aiowps_firewall_config->get_value('aios_brute_force_secret_word'); + $brute_force_secret_cookie_name = $aiowps_firewall_config->get_value('aios_brute_force_secret_cookie_name'); + $login_page_slug = $aiowps_firewall_config->get_value('aios_login_page_slug'); + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. A nonce is not available at this point. + if (!isset($_GET[$brute_force_secret_word])) { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitizing is not required, as we validate the raw input. + $brute_force_secret_cookie_val = isset($_COOKIE[$brute_force_secret_cookie_name]) ? $_COOKIE[$brute_force_secret_cookie_name] : ''; + $pw_protected_exception = $aiowps_firewall_config->get_value('aios_brute_force_attack_prevention_pw_protected_exception'); + $prevent_ajax_exception = $aiowps_firewall_config->get_value('aios_brute_force_attack_prevention_ajax_exception'); + + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitizing is not required, as we validate the raw input. + if (!empty($_SERVER['REQUEST_URI']) && !hash_equals($brute_force_secret_cookie_val, \AIOS_Helper::get_hash($brute_force_secret_word))) { + + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitizing is not required, as we validate the raw input. + $request_uri = (string) parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); + + // admin section or login page or login custom slug called + $is_admin_or_login = (false != strpos($request_uri, 'wp-admin') || false != strpos($request_uri, 'wp-login') || ('' != $login_page_slug && false != strpos($request_uri, $login_page_slug))) ? 1 : 0; + + // admin side ajax called + $is_admin_ajax_request = ('1' == $prevent_ajax_exception && isset($_SERVER['SCRIPT_NAME']) && ('admin-ajax.php' === basename($_SERVER['SCRIPT_NAME']))) ? 1 : 0; + + // password protected page called + $is_password_protected_access = ('1' == $pw_protected_exception && isset($_GET['action']) && 'postpass' == $_GET['action']) ? 1 : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. A nonce is not available at this point. + + // logout, set password, reset password action called + $is_logout_resetpassword_action = (isset($_GET['action']) && ('logout' == $_GET['action'] || 'rp' == $_GET['action'] || 'resetpass' == $_GET['action'])) ? 1 : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. A nonce is not available at this point. + + // cookie based brute force on and accessing admin without ajax and password protected then redirect + if ($is_admin_or_login && !$is_admin_ajax_request && !$is_password_protected_access && !$is_logout_resetpassword_action) { + $redirect_url = $aiowps_firewall_config->get_value('aios_cookie_based_brute_force_redirect_url'); + $this->location = $redirect_url; + return Rule::SATISFIED; + } + } + } + return Rule::NOT_SATISFIED; + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/general/rule-advanced-character-filter.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/general/rule-advanced-character-filter.php new file mode 100755 index 00000000..61e6f022 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/general/rule-advanced-character-filter.php @@ -0,0 +1,156 @@ +name = 'Advanced character filter'; + $this->family = 'General'; + $this->priority = 10; + } + + /** + * Determines whether the rule is active + * + * @return boolean + */ + public function is_active() { + global $aiowps_firewall_config; + return (bool) $aiowps_firewall_config->get_value('aiowps_advanced_char_string_filter'); + } + + /** + * The condition to be satisfied for the rule to apply + * + * @return boolean + */ + public function is_satisfied() { + + if (empty($_SERVER['REQUEST_URI'])) return Rule::NOT_SATISFIED; + + // ensure we get the request uri without the query string + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitizing will interfere with 6g rules. + $uri = (string) parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); + + return Rule_Utils::contains_pattern($uri, array_merge($this->get_general_characters(), $this->get_common_patterns(), $this->get_specific_exploits())); + } + + /** + * Get the list of 'specific exploits' patterns + * + * @return array + */ + private function get_specific_exploits() { + return array( + '/errors\./i', + '/config\./i', + '/include\./i', + '/display\./i', + '/register\./i', + '/password\./i', + '/maincore\./i', + '/authorize\./i', + '/macromates\./i', + '/head\_auth\./i', + '/submit\_links\./i', + '/change\_action\./i', + '/com\_facileforms\//i', + '/admin\_db\_utilities\./i', + '/admin\.webring\.docs\./i', + '/Table\/Latest\/index\./i', + ); + } + + /** + * Get the list of common patterns + * + * @return array + */ + private function get_common_patterns() { + return array( + '/\_vpi/i', + '/\.inc/i', + '/xAou6/i', + '/db\_name/i', + '/select\(/i', + '/convert\(/i', + '/\/query\//i', + '/ImpEvData/i', + '/\.XMLHTTP/i', + '/proxydeny/i', + '/function\./i', + '/remoteFile/i', + '/servername/i', + '/\&rptmode\=/i', + '/sys\_cpanel/i', + '/db\_connect/i', + '/doeditconfig/i', + '/check\_proxy/i', + '/system\_user/i', + '/\/\(null\)\//i', + '/clientrequest/i', + '/option\_value/i', + '/ref\.outcontrol/i', + ); + } + + /** + * Get the list of general characters + * + * @return array + */ + private function get_general_characters() { + return array( + '/\,/i', + '/\:/i', + '/\;/i', + '/\=/i', + '/\[/i', + '/\]/i', + '/\^/i', + '/\`/i', + '/\{/i', + '/\}/i', + '/\~/i', + '/\"/i', + '/\$/i', + '/\/i', + '/\|/i', + '/\.\./i', + '/\%0/i', + '/\%A/i', + '/\%B/i', + '/\%C/i', + '/\%D/i', + '/\%E/i', + '/\%F/i', + '/\%22/i', + '/\%27/i', + '/\%28/i', + '/\%29/i', + '/\%3C/i', + '/\%3E/i', + '/\%3F/i', + '/\%5B/i', + '/\%5C/i', + '/\%5D/i', + '/\%7B/i', + '/\%7C/i', + '/\%7D/i', + ); + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/general/rule-bad-query-strings.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/general/rule-bad-query-strings.php new file mode 100755 index 00000000..558102e4 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/general/rule-bad-query-strings.php @@ -0,0 +1,56 @@ +name = 'Bad query strings'; + $this->family = 'General'; + $this->priority = 10; + } + + /** + * Determines whether the rule is active + * + * @return boolean + */ + public function is_active() { + global $aiowps_firewall_config; + return (bool) $aiowps_firewall_config->get_value('aiowps_deny_bad_query_strings'); + } + + /** + * The condition to be satisfied for the rule to apply + * + * @return boolean + */ + public function is_satisfied() { + + if (empty($_SERVER['QUERY_STRING'])) return Rule::NOT_SATISFIED; + + $patterns = array( + '/ftp:/i', + '/http:/i', + '/https:/i', + '/mosConfig/i', + '/^.*(globals|encode|loopback).*/i', + "/(\;|'|\"|%22).*(request|insert|union|declare|drop)/i", + ); + + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitizing will interfere with 6g rules. + return Rule_Utils::contains_pattern($_SERVER['QUERY_STRING'], $patterns); + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/general/rule-block-xmlrpc.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/general/rule-block-xmlrpc.php new file mode 100755 index 00000000..3dfa24d2 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/general/rule-block-xmlrpc.php @@ -0,0 +1,44 @@ +name = 'Completely block XMLRPC'; + $this->family = 'General'; + $this->priority = 10; + } + + /** + * Determines whether the rule is active + * + * @return boolean + */ + public function is_active() { + global $aiowps_firewall_config; + return (bool) $aiowps_firewall_config->get_value('aiowps_enable_pingback_firewall'); + } + + /** + * The condition to be satisfied for the rule to apply + * + * @return boolean + */ + public function is_satisfied() { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitizing will interfere with 6g rules. + return (isset($_SERVER['SCRIPT_FILENAME']) && 1 === preg_match('/\/xmlrpc\.php$/i', $_SERVER['SCRIPT_FILENAME'])); + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/general/rule-proxy-comment-posting.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/general/rule-proxy-comment-posting.php new file mode 100755 index 00000000..aa61bd31 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/rules/general/rule-proxy-comment-posting.php @@ -0,0 +1,69 @@ +name = 'Proxy comment posting'; + $this->family = 'General'; + $this->priority = 10; + } + + /** + * Determines whether the rule is active + * + * @return boolean + */ + public function is_active() { + global $aiowps_firewall_config; + return (bool) $aiowps_firewall_config->get_value('aiowps_forbid_proxy_comments'); + } + + /** + * The condition to be satisfied for the rule to apply + * + * @return boolean + */ + public function is_satisfied() { + + //Preconditions for the rule + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitizing will interfere with 6g rules. + $is_comment_form = (isset($_SERVER['SCRIPT_FILENAME']) && 1 === preg_match('/\/wp-comments-post\.php$/i', $_SERVER['SCRIPT_FILENAME'])); + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitizing will interfere with 6g rules. + $is_post = (isset($_SERVER['REQUEST_METHOD']) && 0 === strcasecmp($_SERVER['REQUEST_METHOD'], "POST")); + + if (!$is_post || !$is_comment_form) return Rule::NOT_SATISFIED; + + //Headers that are present if a proxy is being used + $headers = array( + 'HTTP_VIA', + 'HTTP_FORWARDED', + 'HTTP_USERAGENT_VIA', + 'HTTP_X_FORWARDED_FOR', + 'HTTP_X_FORWARDED_HOST', + 'HTTP_PROXY_CONNECTION', + 'HTTP_XPROXY_CONNECTION', + 'HTTP_PC_REMOTE_ADDR', + 'HTTP_CLIENT_IP', + ); + + foreach ($headers as $header) { + if (!empty($_SERVER[$header])) return Rule::SATISFIED; + } + + return Rule::NOT_SATISFIED; + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/wp-security-firewall-rule-builder.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/wp-security-firewall-rule-builder.php new file mode 100755 index 00000000..f9791d31 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/wp-security-firewall-rule-builder.php @@ -0,0 +1,46 @@ +is_active()) { + Event::raise('rule_not_active', $rule, $classname); + continue; + } + + Event::raise('rule_active', $rule, $classname); + yield $rule; + } + } + + /** + * Generates the classname for each rule + * + * @return iterable + */ + private static function get_rule_classname() { + $rec_iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(AIOWPS_FIREWALL_DIR.'/rule/rules/', \FilesystemIterator::SKIP_DOTS)); + + foreach ($rec_iterator as $dir_iterator) { + $matches = array(); + if (preg_match('/^rule-(?.*)\.php$/', $dir_iterator->getFilename(), $matches)) { + yield "AIOWPS\Firewall\Rule_".ucwords(str_replace('-', '_', $matches['rule_name']), '_'); + } + } + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/wp-security-firewall-rule-utils.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/wp-security-firewall-rule-utils.php new file mode 100755 index 00000000..9eb3df9b --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/rule/wp-security-firewall-rule-utils.php @@ -0,0 +1,31 @@ +is_satisfied()) { + + Event::raise('rule_triggered', $this, time()); + $this->do_action(); + + } + + Event::raise('rule_not_triggered', $this, time()); + } + + /** + * Show the rule's name + * + * @return string + */ + public function __toString() { + return $this->name; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/wp-security-firewall-context.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/wp-security-firewall-context.php new file mode 100755 index 00000000..3869aa7f --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/wp-security-firewall-context.php @@ -0,0 +1,104 @@ + $file) { + if (preg_match('/aios-bootstrap\.php$/', $file)) { + return $index; + } + } + return -1; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/wp-security-firewall-loader.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/wp-security-firewall-loader.php new file mode 100755 index 00000000..2fcfe272 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/wp-security-firewall-loader.php @@ -0,0 +1,214 @@ +is_preloader_directly_accessed()) return; + + $this->init(); + + global $aiowps_firewall_constants; + if ($aiowps_firewall_constants->AIOS_NO_FIREWALL) return; + + //Allow list for bypassing PHP rules + if (Allow_List::is_ip_allowed()) return; + + $families = new Family_Collection(Family_Builder::get_families()); + + foreach (Rule_Builder::get_active_rule() as $rule) { + $families->add_rule_to_member($rule); + } + + foreach ($families->get_family() as $member) { + $member->apply_all(); + } + + } catch (Exit_Exception $e) { + $this->log_message($e->getMessage()); + exit(); + } catch (\Exception $e) { + $this->log_message($e->getMessage()); + } catch (\Error $e) { // phpcs:ignore PHPCompatibility.Classes.NewClasses.errorFound -- this won't run on PHP 5.6 so we still want to catch it on other versions + $this->log_message($e->getMessage()); + } + } + + /** + * Performs general initialisation + * + * @return void + */ + public function init() { + + $this->init_includes(); + $this->init_services(); + + new Debug(); + } + + /** + * Detects whether the preloader file (wp-security-firewall.php) was directly accessed + * + * @return boolean + */ + public function is_preloader_directly_accessed() { + return (1 === preg_match('/wp-security-firewall\.php$/', get_included_files()[0])); + } + + /** + * Log our error messages + * + * @param string $message + * @return void + */ + private function log_message($message) { + if (function_exists('do_action')) { + do_action('aios_firewall_loader_log_error', $message, $this); + } + + error_log('AIOS firewall error: ' . $message); + } + + /** + * Initialises our services + * + * @return void + */ + private function init_services() { + + $workspace = $this->get_firewall_workspace(); + + if (empty($workspace)) { + throw new \Exception('unable to locate workspace.'); + } + + $GLOBALS['aiowps_firewall_config'] = new Config($workspace . 'settings.php'); + $GLOBALS['aiowps_firewall_message_store'] = Message_Store::instance(); + $GLOBALS['aiowps_firewall_constants'] = new Constants(); + Allow_List::set_path($workspace.'allowlist.php'); + } + + /** + * Get our workspace directory, i.e., where we save and load data to and from. + * + * @return string + */ + private function get_firewall_workspace() { + global $aiowps_firewall_rules_path; + + $workspace = ''; + + if (!empty($aiowps_firewall_rules_path)) { + $workspace = $aiowps_firewall_rules_path; + } elseif (Context::wordpress_safe()) { + $workspace = \AIOWPSecurity_Utility_Firewall::get_firewall_rules_path(); + } + + return $workspace; + } + + /** + * Registers the autoloader + * + * @return void + */ + private function init_includes() { + + spl_autoload_register(function($class) { + if (0 === strpos($class, "AIOWPS\\Firewall\\")) { //only autoload the firewall's files + + $relative_classname = substr($class, strlen("AIOWPS\\Firewall\\"), strlen($class)-1); + + $classname = str_replace('_', '-', strtolower($relative_classname)); + + $file = "wp-security-firewall-{$classname}.php"; + $rule = "{$classname}.php"; + + $paths = array( + AIOWPS_FIREWALL_DIR."/{$file}", + AIOWPS_FIREWALL_DIR."/family/{$file}", + AIOWPS_FIREWALL_DIR."/rule/{$file}", + AIOWPS_FIREWALL_DIR."/rule/actions/{$classname}.php", + AIOWPS_FIREWALL_DIR."/rule/rules/{$rule}", + AIOWPS_FIREWALL_DIR."/rule/rules/6g/{$rule}", + AIOWPS_FIREWALL_DIR."/rule/rules/bruteforce/{$rule}", + AIOWPS_FIREWALL_DIR."/rule/rules/blacklist/{$rule}", + AIOWPS_FIREWALL_DIR."/rule/rules/general/{$rule}", + AIOWPS_FIREWALL_DIR."/rule/rules/bots/{$rule}", + AIOWPS_FIREWALL_DIR."/libs/{$file}", + AIOWPS_FIREWALL_DIR."/libs/traits/{$classname}.php", + ); + + clearstatcache(); + foreach ($paths as $path) { + if (file_exists($path)) { + include_once($path); + break; + } + } + } + }); + + // Manually include needed files + $classes_dir = dirname(AIOWPS_FIREWALL_DIR); + + $manual_files = array( + $classes_dir.'/wp-security-firewall-resource-unavailable.php', + $classes_dir.'/wp-security-firewall-resource.php', + $classes_dir.'/wp-security-helper.php', + ); + + foreach ($manual_files as $file) { + clearstatcache(); + if (file_exists($file)) include_once $file; + } + + if (Context::wordpress_safe()) { + include_once("{$classes_dir}/wp-security-utility-file.php"); + } + } + + /** + * Gets or creates an instance of this object + * + * @return Loader + */ + public static function get_instance() { + + if (null === self::$instance) { + return new self(); + } + + return self::$instance; + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/wp-security-firewall-utility.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/wp-security-firewall-utility.php new file mode 100755 index 00000000..eb1a2bba --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/firewall/wp-security-firewall-utility.php @@ -0,0 +1,218 @@ +load_firewall(); + define('AIOWPSEC_FIREWALL_DONE', true); +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/grade-system/wp-security-feature-item-manager.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/grade-system/wp-security-feature-item-manager.php new file mode 100755 index 00000000..ac51ee19 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/grade-system/wp-security-feature-item-manager.php @@ -0,0 +1,800 @@ +setup_feature_list(); + $this->initialize_features(); + } + + /** + * This function sets up the feature list + * + * @return void + */ + private function setup_feature_list() { + $feature_list = array( + // Settings menu features + 'wp-generator-meta-tag' => array( + 'name' => __('Remove WP generator meta tag', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_1, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_remove_wp_generator_meta_info' + ) + ), + // User Accounts menu features + 'user-accounts-change-admin-user' => array( + 'name' => __('Change admin username', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_3, + 'level' => $this->sec_level_basic, + 'options' => array( + '' + ), + 'callback' => array($this, 'check_user_accounts_change_admin_user_feature') + ), + 'user-accounts-display-name' => array( + 'name' => __('Change display name', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_1, + 'level' => $this->sec_level_basic, + 'options' => array( + '' + ), + 'callback' => array($this, 'check_user_accounts_display_name_feature') + ), + // User Login menu features + 'user-login-login-lockdown' => array( + 'name' => __('Login lockout', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_4, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_login_lockdown' + ) + ), + 'user-login-force-logout' => array( + 'name' => __('Force logout', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_1, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_forced_logout' + ) + ), + 'hibp' => array( + 'name' => __('HIBP', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_inter, + 'options' => array( + 'aiowps_hibp_user_profile_update', + 'aiowps_http_password_reset', + ) + ), + 'disable-application-password' => array( + 'name' => __('Disable application password', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_inter, + 'options' => array( + 'aiowps_disable_application_password' + ) + ), + 'user-login-lockout-ip-whitelisting' => array( + 'name' => __('Login Lockout IP whitelisting', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_3, + 'level' => $this->sec_level_inter, + 'options' => array( + 'aiowps_lockdown_enable_whitelisting' + ) + ), + // User Registration menu features + 'manually-approve-registrations' => array( + 'name' => __('Registration approval', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_4, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_manual_registration_approval' + ) + ), + 'user-registration-captcha' => array( + 'name' => __('Registration CAPTCHA', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_4, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_registration_page_captcha' + ) + ), + 'registration-honeypot' => array( + 'name' => __('Enable registration honeypot', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_inter, + 'options' => array( + 'aiowps_enable_registration_honeypot' + ) + ), + 'http-authentication-admin-frontend' => array( + 'name' => __('HTTP authentication for admin and frontend', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_http_authentication_admin', + 'aiowps_http_authentication_frontend', + ) + ), + // Database Security menu features + 'db-security-db-prefix' => array( + 'name' => __('Database prefix', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_inter, + 'options' => array( + '' + ), + 'callback' => array($this, 'check_db_security_db_prefix_feature') + ), + // Filesystem Security menu features + 'filesystem-file-permissions' => array( + 'name' => __('File permissions', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_4, + 'level' => $this->sec_level_basic, + 'options' => array( + '' + ), + 'callback' => array($this, 'check_filesystem_permissions_feature') + ), + 'filesystem-file-editing' => array( + 'name' => __('File editing', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_disable_file_editing' + ) + ), + 'auto-delete-wp-files' => array( + 'name' => __('WordPress files access', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_auto_delete_default_wp_files' + ) + ), + // Blacklist Manager menu features + 'blacklist-manager-ip-user-agent-blacklisting' => array( + 'name' => __('IP and user agent blacklisting', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_3, + 'level' => $this->sec_level_advanced, + 'options' => array( + 'aiowps_enable_blacklisting' + ) + ), + // Firewall menu features + 'firewall-basic-rules' => array( + 'name' => __('Enable basic firewall', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_3, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_basic_firewall' + ), + 'feature_condition_callback' => array('AIOWPSecurity_Utility', 'allow_to_write_to_htaccess') + ), + 'firewall-pingback-rules' => array( + 'name' => __('Enable pingback vulnerability protection', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_3, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_pingback_firewall' + ) + ), + 'firewall-block-debug-file-access' => array( + 'name' => __('Block access to debug log file', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_inter, + 'options' => array( + 'aiowps_block_debug_log_file_access' + ), + 'feature_condition_callback' => array('AIOWPSecurity_Utility', 'allow_to_write_to_htaccess') + ), + 'firewall-disable-index-views' => array( + 'name' => __('Disable index views', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_1, + 'level' => $this->sec_level_inter, + 'options' => array( + 'aiowps_disable_index_views' + ), + 'feature_condition_callback' => array('AIOWPSecurity_Utility', 'allow_to_write_to_htaccess') + ), + 'firewall-disable-trace-track' => array( + 'name' => __('Disable trace and track', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_advanced, + 'options' => array( + 'aiowps_disable_trace_and_track' + ), + 'feature_condition_callback' => array('AIOWPSecurity_Utility', 'allow_to_write_to_htaccess') + ), + 'firewall-forbid-proxy-comments' => array( + 'name' => __('Forbid proxy comments', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_advanced, + 'options' => array( + 'aiowps_forbid_proxy_comments' + ) + ), + 'firewall-deny-bad-queries' => array( + 'name' => __('Deny bad queries', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_3, + 'level' => $this->sec_level_advanced, + 'options' => array( + 'aiowps_deny_bad_query_strings' + ) + ), + 'firewall-advanced-character-string-filter' => array( + 'name' => __('Advanced character string filter', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_3, + 'level' => $this->sec_level_advanced, + 'options' => array( + 'aiowps_advanced_char_string_filter' + ) + ), + 'firewall-enable-6g' => array( + 'name' => __('6G firewall', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_4, + 'level' => $this->sec_level_advanced, + 'options' => array( + 'aiowps_enable_6g_firewall', + ) + ), + 'firewall-block-fake-googlebots' => array( + 'name' => __('Block fake Googlebots', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_1, + 'level' => $this->sec_level_advanced, + 'options' => array( + 'aiowps_block_fake_googlebots' + ) + ), + 'prevent-hotlinking' => array( + 'name' => __('Prevent image hotlinking', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_prevent_hotlinking' + ) + ), + 'firewall-enable-404-blocking' => array( + 'name' => __('Enable IP blocking for 404 detection', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_1, + 'level' => $this->sec_level_inter, + 'options' => array( + 'aiowps_enable_404_IP_lockout' + ) + ), + 'firewall-disable-rss-and-atom' => array( + 'name' => __('Disable RSS and ATOM feeds', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_disable_rss_and_atom_feeds' + ) + ), + 'upgrade-unsafe-http-calls' => array( + 'name' => __('Upgrade unsafe HTTP calls', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_inter, + 'options' => array( + 'aiowps_upgrade_unsafe_http_calls' + ) + ), + // Brute Force menu features + 'bf-rename-login-page' => array( + 'name' => __('Enable rename login page', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_inter, + 'options' => array( + 'aiowps_enable_rename_login_page' + ) + ), + 'firewall-enable-brute-force-attack-prevention' => array( + 'name' => __('Enable brute force attack prevention', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_4, + 'level' => $this->sec_level_advanced, + 'options' => array( + 'aiowps_enable_brute_force_attack_prevention' + ) + ), + 'user-login-captcha' => array( + 'name' => __('Login CAPTCHA', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_4, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_login_captcha' + ) + ), + 'lost-password-captcha' => array( + 'name' => __('Lost password CAPTCHA', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_lost_password_captcha' + ) + ), + 'custom-login-captcha' => array( + 'name' => __('Custom login CAPTCHA', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_4, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_custom_login_captcha' + ) + ), + 'password_protected-captcha' => array( + 'name' => __('Password-protected CAPTCHA', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_1, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_password_protected_captcha' + ) + ), + 'whitelist-manager-ip-login-whitelisting' => array( + 'name' => __('Login IP whitelisting', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_3, + 'level' => $this->sec_level_inter, + 'options' => array( + 'aiowps_enable_whitelisting' + ) + ), + 'login-honeypot' => array( + 'name' => __('Enable login honeypot', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_inter, + 'options' => array( + 'aiowps_enable_login_honeypot' + ) + ), + // Spam Prevention menu features + 'comment-form-captcha' => array( + 'name' => __('Comment CAPTCHA', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_4, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_comment_captcha' + ) + ), + 'detect-spambots' => array( + 'name' => __('Detect spambots', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_spambot_detecting' + ) + ), + 'auto-block-spam-ips' => array( + 'name' => __('Auto block spam ips', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_autoblock_spam_ip' + ) + ), + // Scanner menu features + 'scan-file-change-detection' => array( + 'name' => __('File change detection', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_4, + 'level' => $this->sec_level_inter, + 'options' => array( + 'aiowps_enable_automated_fcd_scan' + ) + ), + // Miscellaneous menu features + 'enable-copy-protection' => array( + 'name' => __('Enable Copy Protection', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_1, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_copy_protection' + ) + ), + 'enable-frame-protection' => array( + 'name' => __('Enable iFrame protection', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_1, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_prevent_site_display_inside_frame' + ) + ), + 'disable-users-enumeration' => array( + 'name' => __('Disable users enumeration', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_1, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_prevent_users_enumeration' + ) + ), + 'disallow-unauthorised-requests' => array( + 'name' => __('Disallow unauthorized REST requests', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_1, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_disallow_unauthorized_rest_requests' + ) + ), + 'enable-salt-postfix' => array( + 'name' => __('Enable salt postfix', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_3, + 'level' => $this->sec_level_advanced, + 'options' => array( + 'aiowps_enable_salt_postfix' + ) + ), + // conditional features + 'bp-register-captcha' => array( + 'name' => __('BuddyPress registration CAPTCHA', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_1, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_bp_register_captcha' + ), + 'feature_condition_callback' => array('AIOWPSecurity_Utility', 'is_buddypress_plugin_active'), + ), + 'bbp-new-topic-captcha' => array( + 'name' => __('bbPress new topic CAPTCHA', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_1, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_bbp_new_topic_captcha' + ), + 'feature_condition_callback' => array('AIOWPSecurity_Utility', 'is_bbpress_plugin_active'), + ), + 'woo-login-captcha' => array( + 'name' => __('Woo login CAPTCHA', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_woo_login_captcha' + ), + 'feature_condition_callback' => array('AIOWPSecurity_Utility', 'is_woocommerce_plugin_active'), + ), + 'woo-lostpassword-captcha' => array( + 'name' => __('Woo lost password CAPTCHA', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_woo_lostpassword_captcha' + ), + 'feature_condition_callback' => array('AIOWPSecurity_Utility', 'is_woocommerce_plugin_active'), + ), + 'woo-register-captcha' => array( + 'name' => __('Woo register CAPTCHA', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_woo_register_captcha' + ), + 'feature_condition_callback' => array('AIOWPSecurity_Utility', 'is_woocommerce_plugin_active'), + ), + 'woo-checkout-captcha' => array( + 'name' => __('Woo Checkout CAPTCHA', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_woo_checkout_captcha' + ), + 'feature_condition_callback' => array('AIOWPSecurity_Utility', 'is_woocommerce_plugin_active'), + ), + // Ban POST requests with blank user-agent and referer + 'firewall-ban-post-blank-headers' => array( + 'name' => __('Ban POST requests that have blank user-agent and referer headers', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_2, + 'level' => $this->sec_level_inter, + 'options' => array( + 'aiowps_ban_post_blank_headers' + ) + ), + 'contact-form-7-captcha' => array( + /* translators: %s: Plugin name */ + 'name' => sprintf(__('%s CAPTCHA', 'all-in-one-wp-security-and-firewall'), 'Contact Form 7'), + 'points' => $this->feature_point_1, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enable_contact_form_7_captcha' + ), + 'feature_condition_callback' => array('AIOWPSecurity_Utility', 'is_contact_form_7_plugin_active'), + ), + 'enforce-strong-password' => array( + 'name' => __('Enforce use of strong passwords by users', 'all-in-one-wp-security-and-firewall'), + 'points' => $this->feature_point_1, + 'level' => $this->sec_level_basic, + 'options' => array( + 'aiowps_enforce_strong_password' + ), + ) + ); + + $feature_list = apply_filters('aiowpsecurity_feature_list', $feature_list); + $this->feature_list = array_filter($feature_list, array($this, 'should_add_item')); + } + + /** + * This function will create a feature item object for each feature in the feature list + * + * @return void + */ + private function initialize_features() { + foreach ($this->feature_list as $id => $data) { + $callback = isset($data['callback']) ? $data['callback'] : array($this, 'is_feature_enabled'); + $this->feature_items[$id] = new AIOWPSecurity_Feature_Item($id, $data['name'], $data['points'], $data['level'], $data['options'], $callback); + } + } + + /** + * This function will return the feature item for the passed in ID + * + * @param string $feature_id - the id of the feature item we want to return + * + * @return boolean|AIOWPSecurity_Feature_Item - returns a feature item or false on coding error + */ + public function get_feature_item_by_id($feature_id) { + if (isset($this->feature_items[$feature_id])) return $this->feature_items[$feature_id]; + error_log("AIOS Feature Manager - Feature ID not found (coding error): $feature_id"); + return false; + } + + /** + * Call the callback function associated with the feature item. + * + * @param mixed $feature_item The feature item object. + */ + private function call_feature_callback($feature_item) { + call_user_func($feature_item->callback, $feature_item); + } + + /** + * This function will output the feature details badge HTML + * + * @param string $feature_id - the id of the feature we want to get the badge for + * @param bool $return_instead_of_echo - whether to return the HTML or echo it + * + * @return string|void + */ + public function output_feature_details_badge($feature_id, $return_instead_of_echo = false) { + // Retrieve the feature item by ID + $feature_item = $this->get_feature_item_by_id($feature_id); + + if (!$feature_item) return; + + $this->call_feature_callback($feature_item); + + // Prepare HTML for the feature badge + $max_security_points = $feature_item->item_points; + $current_security_points = $feature_item->is_active() ? $max_security_points : 0; + $security_level = $feature_item->get_security_level_string(); + $protection_level = (0 == $current_security_points) ? 'none' : 'full'; + $status_icon = (0 == $current_security_points) ? 'dashicons-unlock' : 'dashicons-lock'; + + $badge_html = '
'; + $badge_html .= ''; + $badge_html .= ''.$security_level.''; + $badge_html .= ''; + $badge_html .= $current_security_points.'/'.$max_security_points.''; + $badge_html .= '
'; + + if ($return_instead_of_echo) { + return $badge_html; + } else { + echo $badge_html; + } + } + + /** + * This function will calculate the total points for the AJAX save function + * + * @return void + */ + public function calculate_total_feature_points() { + $this->calculate_total_points(); + } + + /** + * This function will setup the feature status and calculate the total points + * + * @return void + */ + public function check_feature_status_and_recalculate_points() { + $this->check_and_set_feature_status(); + $this->calculate_total_points(); + } + + /** + * This function will calculate the total points for the site + * + * @return void + */ + private function calculate_total_points() { + foreach ($this->feature_items as $item) { + if ($item->is_active()) $this->total_points = $this->total_points + intval($item->item_points); + } + } + + /** + * This function will calculate the total achievable points + * + * @return void + */ + private function calculate_total_achievable_points() { + foreach ($this->feature_items as $item) { + $this->total_achievable_points = $this->total_achievable_points + intval($item->item_points); + } + } + + /** + * This function will return the total points for the site + * + * @return int - the total points for the site + */ + public function get_total_site_points() { + if (empty($this->total_points)) $this->calculate_total_points(); + return $this->total_points; + } + + /** + * This function will return the total achievable points + * + * @return int - the total achievable points + */ + public function get_total_achievable_points() { + if (empty($this->total_achievable_points)) $this->calculate_total_achievable_points(); + return $this->total_achievable_points; + } + + /** + * This function will loop over each feature item, checking if it's enabled and setting it's feature status + * + * @return void + */ + private function check_and_set_feature_status() { + foreach ($this->feature_items as $item) { + call_user_func($item->callback, $item); + } + } + + /** + * This function will check if the feature database value is active and set the feature status + * + * @param AIOWPSecurity_Feature_Item $item - the item we want to check is active + * + * @return void + */ + private function is_feature_enabled($item) { + global $aio_wp_security; + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + + $enabled = false; + foreach ($item->feature_options as $option) { + if ('1' == $aiowps_firewall_config->get_value($option) || '1' == $aio_wp_security->configs->get_value($option)) $enabled = true; + } + + if ($enabled) { + $item->set_feature_status($this->feature_active); + } else { + $item->set_feature_status($this->feature_inactive); + } + } + + /** + * This function will check if the default admin user exists and set the feature status + * + * @param AIOWPSecurity_Feature_Item $item - the item we want to check is active + * + * @return void + */ + private function check_user_accounts_change_admin_user_feature($item) { + if (AIOWPSecurity_Utility::check_user_exists('admin')) { + $item->set_feature_status($this->feature_inactive); + } else { + $item->set_feature_status($this->feature_active); + } + } + + /** + * This function will check if the username and nicknames are identical and set the feature status + * + * @param AIOWPSecurity_Feature_Item $item - the item we want to check is active + * + * @return void + */ + private function check_user_accounts_display_name_feature($item) { + if (AIOWPSecurity_Utility::check_identical_login_and_nick_names()) { + $item->set_feature_status($this->feature_inactive); + } else { + $item->set_feature_status($this->feature_active); + } + } + + /** + * This function will check if the default database prefix is in use and set the feature status + * + * @param AIOWPSecurity_Feature_Item $item - the item we want to check is active + * + * @return void + */ + private function check_db_security_db_prefix_feature($item) { + global $wpdb; + $site_id = get_current_blog_id(); + $default_prefix = (1 === $site_id) ? 'wp_' : "wp_{$site_id}_"; + if ($default_prefix === $wpdb->prefix) { + $item->set_feature_status($this->feature_inactive); + } else { + $item->set_feature_status($this->feature_active); + } + } + + /** + * This function will check the filesystem permissions and set the feature status + * + * @param AIOWPSecurity_Feature_Item $item - the item we want to check is active + * + * @return void + */ + private function check_filesystem_permissions_feature($item) { + //TODO + $is_secure = 1; + $files_dirs_to_check = AIOWPSecurity_Utility_File::get_files_and_dirs_to_check(); + + foreach ($files_dirs_to_check as $file_or_dir) { + $actual_perm = AIOWPSecurity_Utility_File::get_file_permission($file_or_dir['path']); + $is_secure = $is_secure*AIOWPSecurity_Utility_File::is_file_permission_secure($file_or_dir['permissions'], $actual_perm); + } + + //Only if all of the files' permissions are deemed secure give this a thumbs up + if (1 == $is_secure) { + $item->set_feature_status($this->feature_active); + } else { + $item->set_feature_status($this->feature_inactive); + } + } + + /** + * This function will check if an item should be added to the feature list + * + * @param array $item - the item we want to check if it should be added + * @return bool + */ + public static function should_add_item($item) { + if (empty($item['feature_condition_callback'])) { + return true; + } elseif (is_callable($item['feature_condition_callback'])) { + return call_user_func($item['feature_condition_callback']); + } else { + error_log("Callback function set but not callable (coding error). Feature: " . $item['name']); + return false; + } + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/grade-system/wp-security-feature-item.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/grade-system/wp-security-feature-item.php new file mode 100755 index 00000000..1ea89f58 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/grade-system/wp-security-feature-item.php @@ -0,0 +1,78 @@ +feature_id = $feature_id; + $this->feature_name = $feature_name; + $this->item_points = $item_points; + $this->security_level = $security_level; + $this->feature_options = $feature_options; + $this->callback = $callback; + } + + /** + * This function will set the status of the feature + * + * @param string $status - the status of the feature + * + * @return void + */ + public function set_feature_status($status) { + $this->feature_status = $status; + } + + /** + * This function will return the string version of the level + * + * @return string - the string value of the level + */ + public function get_security_level_string() { + $level_string = ""; + if ("1" == $this->security_level) { + $level_string = __('Basic', 'all-in-one-wp-security-and-firewall'); + } elseif ("2" == $this->security_level) { + $level_string = __('Intermediate', 'all-in-one-wp-security-and-firewall'); + } elseif ("3" == $this->security_level) { + $level_string = __('Advanced', 'all-in-one-wp-security-and-firewall'); + } + return $level_string; + } + + /** + * This function will return a boolean to indicate if the feature is on or not + * + * @return boolean - true if the feature is on otherwise false + */ + public function is_active() { + return ('active' == $this->feature_status); + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/index.html b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/index.html new file mode 100755 index 00000000..e69de29b diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/index.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/index.php new file mode 100755 index 00000000..a64ea405 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/index.php @@ -0,0 +1,4 @@ +commands = new AIOWPSecurity_Commands(); + } + + /** + * Magic method to pass on the command to AIOWPSecurity_Commands + * + * @param string $name - command name + * @param array $arguments - command parameters + * + * @return array - response + */ + public function __call($name, $arguments) { + if (!is_callable(array($this->commands, $name))) { + return $this->_generic_error_response('aios_no_such_command', $name); + } + + $result = call_user_func_array(array($this->commands, $name), $arguments); + + if (is_wp_error($result)) { + return $this->_generic_error_response($result->get_error_code(), $result->get_error_data()); + } else { + return $this->_response($result); + } + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/updraftcentral.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/updraftcentral.php new file mode 100755 index 00000000..8c0c0370 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/updraftcentral.php @@ -0,0 +1,43 @@ + 'REMOTE_ADDR', + '1' => 'HTTP_CF_CONNECTING_IP', + '2' => 'HTTP_X_FORWARDED_FOR', + '3' => 'HTTP_X_FORWARDED', + '4' => 'HTTP_CLIENT_IP', + '5' => 'HTTP_X_REAL_IP', + '6' => 'HTTP_X_CLUSTER_CLIENT_IP', + ); + } + + /** + * Get AIOS custom admin notice ids. + * + * @return array + */ + public static function custom_admin_notice_ids() { + return array( + 'automated-database-backup', + 'ip-retrieval-settings', + 'load-firewall-resources-failed', + 'end-of-support-php-56', + ); + } + + /** + * Get notice ids for notices that have transformed HTACESS rules to PHP. + * + * @return array notice ids. + */ + public static function htaccess_to_php_feature_notice_ids() { + return array( + 'login-whitelist-disabled-on-upgrade', + 'ip-blacklist-settings-on-upgrade', + 'upgrade-firewall-tab-rules', + ); + } + + /** + * Get locale codes that are more than 2 char long supported by Google ReCaptcha. + * + * @return array + */ + public static function get_google_recaptcha_locale_codes() { + /** + * Google reCaptcha accepts 2 char language codes and also more than 2 char language codes. + * Most are 2 chars in length e.g. 'ar' for Arabic. + * Few are more than 2 char in length e.g 'de-AT' for German (Austria) + * + * Below is the list of more than 2 char language codes supported by Google reCaptcha. + * if determine_locale() detects any of the below we return it, otherwise, + * we would return the 2 letter code. + */ + return array( + 'zh-HK', // Chinese (Hong Kong). + 'zh-CN', // Chinese (Simplified). + 'zh-TW', // Chinese (Traditional). + 'en-GB', // UK. + 'fr-CA', // French (Canadian). + 'de-AT', // German (Austria). + 'de-CH', // German (Switzerland). + 'pt-BR', // Portuguese (Brazil). + 'pt-PT', // Portuguese (Portugal). + ); + } + + /** + * Get IP Lookup services. + * + * @return array + */ + public static function get_ip_lookup_services() { + return array( + 'ipify' => 'http://api.ipify.org/', + 'ipecho' => 'http://ipecho.net/plain', + 'ident' => 'http://ident.me', + 'tnedi' => 'http://tnedi.me', + ); + } + + /** + * Get Reverse IP Lookup services. + * + * @return array + */ + public static function get_reverse_ip_lookup_services() { + return array( + 'ip-api' => 'http://ip-api.com/json/%s', + 'ipinfo' => 'https://ipinfo.io/%s/json' + ); + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-ajax.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-ajax.php new file mode 100755 index 00000000..6e459749 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-ajax.php @@ -0,0 +1,253 @@ +commands_object = new AIOWPSecurity_Commands(); + + add_action('wp_ajax_aios_ajax', array($this, 'handle_ajax_requests')); + add_action('wp_ajax_nopriv_get_antibot_keys', array($this->commands_object, 'get_antibot_keys')); + } + + /** + * Return singleton instance + * + * @return AIOWPSecurity_Ajax Returns AIOWPSecurity_Ajax object + */ + public static function get_instance() { + static $instance = null; + if (null === $instance) { + $instance = new self(); + } + return $instance; + } + + /** + * Handles ajax requests + * + * @return void + */ + public function handle_ajax_requests() { + $this->set_nonce(); + $this->set_subaction(); + $this->set_data(); + + $result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($this->nonce, 'wp-security-ajax-nonce'); + if (is_wp_error($result)) { + wp_send_json(array( + 'result' => false, + 'error_code' => $result->get_error_code(), + 'error_message' => $result->get_error_message(), + )); + } + + if (is_multisite() && !current_user_can('manage_network_options')) { + if (!$this->is_valid_multisite_command()) { + $this->send_invalid_multisite_command_error_response(); + } + } + + if ($this->is_invalid_command()) { + $this->add_invalid_command_error_log_entry(); + $this->set_invalid_command_error_response(); + } else { + $this->execute_command(); + $this->set_error_response_on_wp_error(); + $this->maybe_set_results_as_null(); + } + + $this->json_encode_results(); + + $json_last_error = json_last_error(); + if ($json_last_error) { + $this->set_error_response_on_json_encode_error($json_last_error); + } + + echo $this->results; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variable is an array containing escaped data. + die; + } + + /** + * Sets nonce property value + * + * @return void + */ + private function set_nonce() { + // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput -- It's the actual nonce. It does not need sanitizing. + $this->nonce = empty($_POST['nonce']) ? '' : $_POST['nonce']; + } + + /** + * Sets subaction property value + * + * @return void + */ + private function set_subaction() { + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce already checked. + $this->subaction = empty($_POST['subaction']) ? '' : sanitize_text_field(wp_unslash($_POST['subaction'])); + } + + /** + * Sets data property value + * + * @return void + */ + private function set_data() { + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce already checked. + $this->data = isset($_POST['data']) ? wp_unslash($_POST['data']) : null; + } + + /** + * Checks whether it is multisite setup and command is valid multisite command + * + * @return bool + */ + private function is_valid_multisite_command() { + /** + * Filters the commands allowed to the sub site admins. Other commands are only available to network admin. Only used in a multisite context. + */ + $allowed_commands = apply_filters('aios_multisite_allowed_commands', array( + 'delete_audit_log', + 'delete_locked_ip_record', + 'clear_debug_logs', + 'unlock_ip', + 'blocked_ip_list_unblock_ip', + 'lock_ip', + 'dismiss_notice', + )); + + return in_array($this->subaction, $allowed_commands); + } + + /** + * Sends the invalid multisite command error response + * + * @return void + */ + private function send_invalid_multisite_command_error_response() { + wp_send_json(array( + 'result' => false, + 'error_code' => 'update_failed', + 'error_message' => __('Options can only be saved by network admin', 'all-in-one-wp-security-and-firewall') + )); + } + + /** + * Checks if applied ajax command is an invalid command or not + * + * @return bool Returns true if ajax command is an invalid command, false otherwise + */ + private function is_invalid_command() { + return !is_callable(array($this->commands_object, $this->subaction)); + } + + /** + * Log an error message for invalid ajax command + * + * @return void + */ + private function add_invalid_command_error_log_entry() { + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Part of error reporting. + error_log("AIOS: ajax_handler: no such command (" . $this->subaction . ")"); + } + + /** + * Set `results` property with error response array for invalid ajax command + * + * @return void + */ + private function set_invalid_command_error_response() { + $this->results = array( + 'result' => false, + 'error_code' => 'command_not_found', + /* translators: %s: Subaction */ + 'error_message' => sprintf(__('The command "%s" was not found', 'all-in-one-wp-security-and-firewall'), $this->subaction) + ); + } + + /** + * Execute the ajax command + * + * @return void + */ + private function execute_command() { + $this->results = call_user_func(array($this->commands_object, $this->subaction), $this->data); + } + + /** + * Set `results` property with error message + * + * @return void + */ + private function set_error_response_on_wp_error() { + if (is_wp_error($this->results)) { + $this->results = array( + 'result' => false, + 'error_code' => $this->results->get_error_code(), + 'error_message' => $this->results->get_error_message(), + 'error_data' => $this->results->get_error_data(), + ); + } + } + + /** + * Set `results` property to null, if it is not yet set + * + * @return void + */ + private function maybe_set_results_as_null() { + // if nothing was returned for some reason, set as result null. + if (empty($this->results)) { + $this->results = array( + 'result' => null + ); + } + } + + /** + * Sets `results` property with json encode error + * + * @param int $json_last_error + * + * @return void + */ + private function set_error_response_on_json_encode_error($json_last_error) { + $this->results = array( + 'result' => false, + 'error_code' => $json_last_error, + 'error_message' => 'json_encode error : ' . $json_last_error, + 'error_data' => '', + ); + + $this->results = wp_json_encode($this->results); + } + + /** + * Json encode the `results` property value + * + * @return void + */ + private function json_encode_results() { + $this->results = wp_json_encode($this->results); + } + } + +endif; diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-audit-event-handler.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-audit-event-handler.php new file mode 100755 index 00000000..47a67c20 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-audit-event-handler.php @@ -0,0 +1,159 @@ +add_bulk_events($events); + }, 10, 4); + add_action('aiowps_clean_old_events', array($this, 'delete_old_events'), 10); + + if (!wp_next_scheduled('aiowps_clean_old_events')) { + wp_schedule_event(time(), 'daily', 'aiowps_clean_old_events'); + } + + AIOWPSecurity_Audit_Events::add_event_actions(); + } + + /** + * This function records an event in the audit log + * + * @global AIO_WP_Security $aio_wp_security + * + * @param string $event_type - the event type + * @param array $details - details about the event + * @param string $event_level - the event level + * @param string $username - the username, this is only used if there is no user logged in + * + * @return void + */ + public function record_event($event_type, $details, $event_level = 'info', $username = '') { + + if (!function_exists('wp_get_current_user')) { + global $aio_wp_security; + + $aio_wp_security->debug_logger->log_debug("AIOWPSecurity_Audit_Event_Handler::record_event() called before plugins_loaded hook has run.", 4); + return; + } + + $record_event = apply_filters('aios_audit_log_record_event', true, $event_type, $details, $event_level, $username); + + if (!$record_event) return; + + $user = wp_get_current_user(); + $username = (is_a($user, 'WP_User') && 0 !== $user->ID) ? $user->user_login : $username; + $ip = apply_filters('aios_audit_log_event_user_ip', AIOWPSecurity_Utility_IP::get_user_ip_address()); + $data = apply_filters('aios_audit_log_event_user_country_code', array('ip' => $ip)); + $country_code = isset($data['country_code']) ? $data['country_code'] : ''; + $stacktrace = maybe_serialize(AIOWPSecurity_Utility::normalise_call_stack_args(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS))); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace -- Required for the stacktrace to work. + $network_id = get_current_network_id(); + $site_id = get_current_blog_id(); + $details = wp_json_encode($details, true); + + $this->add_new_event($network_id, $site_id, $username, $ip, $event_level, $event_type, $details, $stacktrace, $country_code); + } + + /** + * This function adds the event to the audit log database table + * + * @param integer $network_id - the id of the current network + * @param integer $site_id - the id of the current site + * @param string $username - the username of the user who triggered the event + * @param string $ip - the IP address of the user + * @param string $event_level - the event level + * @param string $event_type - the event type + * @param string $details - details about the event + * @param string $stacktrace - the event stacktrace + * @param string $country_code - the country code + * + * @return void + */ + private function add_new_event($network_id, $site_id, $username, $ip, $event_level, $event_type, $details, $stacktrace, $country_code) { + global $wpdb; + + $wpdb->query($wpdb->prepare("INSERT INTO ".AIOWPSEC_TBL_AUDIT_LOG." (network_id, site_id, username, ip, level, event_type, details, stacktrace, created, country_code) VALUES (%d, %d, %s, %s, %s, %s, %s, %s, UNIX_TIMESTAMP(), %s)", $network_id, $site_id, $username, $ip, $event_level, $event_type, $details, $stacktrace, $country_code)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared -- We can't use %i because our plugin supports wordpress < 6.2. + } + + /** + * This function adds multiple events to the audit log database table + * + * @param array $events - each event in the array must contain the keys (network_id, site_id, username, ip, level, event_type, details, stacktrace and created) + * + * @return void + */ + private function add_bulk_events($events) { + global $wpdb; + + $sql = "INSERT INTO ".AIOWPSEC_TBL_AUDIT_LOG." (network_id, site_id, username, ip, level, event_type, details, stacktrace, created, country_code) VALUES "; + $values = array(); + + foreach ($events as $event) { + $sql .= "(%d, %d, %s, %s, %s, %s, %s, %s, %d, %s),"; + + $record_event = apply_filters('aios_audit_log_record_event', true, $event['event_type'], $event['details'], $event['level'], $event['username']); + if (!$record_event) continue; + + $event['ip'] = apply_filters('aios_audit_log_event_user_ip', $event['ip']); + $data = apply_filters('aios_audit_log_event_user_country_code', array('ip' => $event['ip'])); + $event['country_code'] = isset($data['country_code']) ? $data['country_code'] : ''; + $values[] = $event['network_id']; + $values[] = $event['site_id']; + $values[] = $event['username']; + $values[] = $event['ip']; + $values[] = $event['level']; + $values[] = $event['event_type']; + $values[] = $event['details']; + $values[] = $event['stacktrace']; + $values[] = $event['created']; + $values[] = $event['country_code']; + } + + // remove last ',' character from query + $sql = rtrim($sql, ','); + + $wpdb->query($wpdb->prepare($sql, $values)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared -- The sql query is being dynamically built. + } + + /** + * This method will try to delete all audit logs older than 3 months from the database. + * + * @return void + */ + public function delete_old_events() { + global $wpdb; + + $after_days = 90; + + if (defined('AIOWPSEC_PURGE_AUDIT_LOGS_AFTER_DAYS')) { + $after_days = abs(AIOWPSEC_PURGE_AUDIT_LOGS_AFTER_DAYS); + } + + $after_days = empty($after_days) ? 90 : $after_days; + $older_than_date = strtotime("-{$after_days} days", time()); + + $wpdb->query($wpdb->prepare("DELETE FROM ".AIOWPSEC_TBL_AUDIT_LOG." WHERE created < %s", $older_than_date)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared -- We can't use %i because our plugin supports wordpress < 6.2. + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-audit-events.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-audit-events.php new file mode 100755 index 00000000..1614470f --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-audit-events.php @@ -0,0 +1,641 @@ + __('Core updated', 'all-in-one-wp-security-and-firewall'), + 'plugin_installed' => __('Plugin installed', 'all-in-one-wp-security-and-firewall'), + 'plugin_activated' => __('Plugin activated', 'all-in-one-wp-security-and-firewall'), + 'plugin_updated' => __('Plugin updated', 'all-in-one-wp-security-and-firewall'), + 'plugin_deactivated' => __('Plugin deactivated', 'all-in-one-wp-security-and-firewall'), + 'plugin_deleted' => __('Plugin deleted', 'all-in-one-wp-security-and-firewall'), + 'theme_installed' => __('Theme installed', 'all-in-one-wp-security-and-firewall'), + 'theme_activated' => __('Theme activated', 'all-in-one-wp-security-and-firewall'), + 'theme_updated' => __('Theme updated', 'all-in-one-wp-security-and-firewall'), + 'theme_deleted' => __('Theme deleted', 'all-in-one-wp-security-and-firewall'), + 'translation_updated' => __('Translation updated', 'all-in-one-wp-security-and-firewall'), + 'entity_changed' => __('Entity changed', 'all-in-one-wp-security-and-firewall'), + 'successful_login' => __('Successful login', 'all-in-one-wp-security-and-firewall'), + 'successful_logout' => __('Successful logout', 'all-in-one-wp-security-and-firewall'), + 'failed_login' => __('Failed login', 'all-in-one-wp-security-and-firewall'), + 'user_registration' => __('User registration', 'all-in-one-wp-security-and-firewall'), + 'user_deleted' => __('User deleted', 'all-in-one-wp-security-and-firewall'), + 'user_removed' => __('User removed from blog', 'all-in-one-wp-security-and-firewall'), + 'table_migration' => __('Table migration', 'all-in-one-wp-security-and-firewall'), + 'rule_triggered' => __('Rule triggered', 'all-in-one-wp-security-and-firewall'), + 'rule_not_triggered' => __('Rule not triggered', 'all-in-one-wp-security-and-firewall'), + 'rule_active' => __('Rule active', 'all-in-one-wp-security-and-firewall'), + 'rule_not_active' => __('Rule not active', 'all-in-one-wp-security-and-firewall'), + 'password_reset' => __('Password reset', 'all-in-one-wp-security-and-firewall'), + ); + } + + /** + * Adds a core updated event to the audit log + * + * @param string $new_version - the wp version we updated to + * + * @return void + */ + public static function core_updated($new_version) { + global $wp_version; + + $details = array( + 'core_updated' => array( + 'old_version' => $wp_version, + 'new_version' => $new_version + ) + ); + do_action('aiowps_record_event', 'core_updated', $details, 'info'); + } + + /** + * Adds a plugin installed event to the audit log + * + * @param WP_Upgrader $upgrader - WP_Upgrader instance + * @param array $hook_extra - Array of bulk item update data + * + * @return void + */ + public static function plugin_installed($upgrader, $hook_extra) { + // If this is empty then we have no way to know if this is a plugin/theme install/update so create an entity changed event + if (empty($hook_extra)) { + self::event_entity_changed($upgrader); + return; + } + if ('plugin' !== $hook_extra['type'] || 'install' !== $hook_extra['action']) return; + self::$installed_plugin_info = $upgrader->new_plugin_data; + self::event_plugin_changed('installed', '', ''); + } + + /** + * Adds a plugin activated event to the audit log + * + * @param string $plugin - Path to the plugin file relative to the plugins directory + * @param boolean $network_activation - Whether to enable the plugin for all sites in the network or just the current site + * + * @return void + */ + public static function plugin_activated($plugin, $network_activation) { + $network = $network_activation ? 'network' : ''; + self::event_plugin_changed('activated', $plugin, $network); + } + + /** + * Adds a plugin updated event to the audit log + * + * @param WP_Upgrader $upgrader - WP_Upgrader instance + * @param array $hook_extra - Array of bulk item update data + * + * @return void + */ + public static function plugin_updated($upgrader, $hook_extra) { + // If this is empty then we have no way to know if this is a plugin/theme install/update so return as we catch this in plugin_installed() + if (empty($hook_extra)) return; + if ('plugin' !== $hook_extra['type'] || 'update' !== $hook_extra['action']) return; + if (isset($hook_extra['plugin'])) { + $plugin = $hook_extra['plugin']; + self::event_plugin_changed('updated', $plugin, ''); + } elseif (isset($hook_extra['plugins'])) { + foreach ($hook_extra['plugins'] as $plugin) { + self::event_plugin_changed('updated', $plugin, ''); + } + } + } + + /** + * Adds a plugin deactivated event to the audit log + * + * @param string $plugin - Path to the plugin file relative to the plugins directory + * @param boolean $network_deactivation - Whether to disable the plugin for all sites in the network or just the current site + * + * @return void + */ + public static function plugin_deactivated($plugin, $network_deactivation) { + $network = $network_deactivation ? 'network' : ''; + self::event_plugin_changed('deactivated', $plugin, $network, 'warning'); + } + + /** + * Records the plugin info of the plugin that is about to be deleted + * + * @param string $plugin - Path to the plugin file relative to the plugins directory + * + * @return void + */ + public static function plugin_delete($plugin) { + $filename = WP_PLUGIN_DIR . '/' . $plugin; + if (!file_exists($filename)) return; + + self::$removed_plugin_info = get_plugin_data($filename); + } + + /** + * Adds a plugin deleted event to the audit log + * + * @param string $plugin - Path to the plugin file relative to the plugins directory + * @param boolean $deleted - Whether the plugin deletion was successful + * + * @return void + */ + public static function plugin_deleted($plugin, $deleted) { + if ($deleted) self::event_plugin_changed('deleted', $plugin, '', 'warning'); + } + + /** + * This function will construct the event details and send it to be recorded + * + * @param string $action - the action taken (activated, deactivated) + * @param string $plugin - Path to the plugin file relative to the plugins directory + * @param string $network - status of if the plugin was network activated/deactivated + * @param string $level - the log level + * + * @return void + */ + private static function event_plugin_changed($action, $plugin, $network, $level = 'info') { + if ('deleted' == $action) { + $info = self::$removed_plugin_info; + } elseif ('installed' == $action) { + $info = self::$installed_plugin_info; + } else { + $filename = WP_PLUGIN_DIR . '/' . $plugin; + if (!file_exists($filename)) return; + $info = get_plugin_data($filename); + } + + $name = empty($info['Name']) ? 'Unknown' : $info['Name']; + $version = empty($info['Version']) ? '0.0.0' : $info['Version']; + + $details = array( + 'plugin' => array( + 'name' => $name, + 'version' => $version, + 'action' => $action, + 'network' => $network + ) + ); + do_action('aiowps_record_event', 'plugin_' . $action, $details, $level); + } + + /** + * Adds a theme installed event to the audit log + * + * @param WP_Upgrader $upgrader - WP_Upgrader instance + * @param array $hook_extra - Array of bulk item update data + * + * @return void + */ + public static function theme_installed($upgrader, $hook_extra) { + // If this is empty then we have no way to know if this is a plugin/theme install/update so return as we catch this in plugin_installed() + if (empty($hook_extra)) return; + if ('theme' !== $hook_extra['type'] || 'install' !== $hook_extra['action']) return; + self::$installed_theme_info = $upgrader->new_theme_data; + self::event_theme_changed('installed', '', ''); + } + + /** + * Adds a theme activated event to the audit log + * + * @param string $new_name - Name of the new active theme + * + * @return void + */ + public static function theme_activated($new_name) { + $details = array( + 'theme' => array( + 'name' => $new_name, + 'action' => 'activated', + ) + ); + do_action('aiowps_record_event', 'theme_activated', $details); + } + + /** + * Adds a theme updated event to the audit log + * + * @param WP_Upgrader $upgrader - WP_Upgrader instance + * @param array $hook_extra - Array of bulk item update data + * + * @return void + */ + public static function theme_updated($upgrader, $hook_extra) { + // If this is empty then we have no way to know if this is a plugin/theme install/update so return as we catch this in plugin_installed() + if (empty($hook_extra)) return; + if ('theme' !== $hook_extra['type'] || 'update' !== $hook_extra['action']) return; + if (isset($hook_extra['theme'])) { + $theme = $hook_extra['theme']; + self::event_theme_changed('updated', $theme, ''); + } elseif (isset($hook_extra['themes'])) { + foreach ($hook_extra['themes'] as $theme) { + self::event_theme_changed('updated', $theme, ''); + } + } + } + + /** + * Records the theme info of the plugin that is about to be deleted + * + * @param string $theme - Path to the theme file relative to the themes directory + * + * @return void + */ + public static function theme_delete($theme) { + $info_object = wp_get_theme($theme); + $info = array( + 'Name' => $info_object->get('Name'), + 'Version' => $info_object->get('Version'), + ); + self::$removed_theme_info = $info; + } + + /** + * Adds a theme deleted event to the audit log + * + * @param string $theme - Path to the theme file relative to the themes directory + * @param boolean $deleted - Whether the theme deletion was successful + * + * @return void + */ + public static function theme_deleted($theme, $deleted) { + if ($deleted) self::event_theme_changed('deleted', $theme, '', 'warning'); + } + + /** + * This function will construct the event details and send it to be recorded + * + * @param string $action - the action taken (activated, deactivated) + * @param string $theme - Path to the theme file relative to the themes directory + * @param string $network - status of if the theme was network activated/deactivated + * @param string $level - the log level + * + * @return void + */ + private static function event_theme_changed($action, $theme, $network, $level = 'info') { + if ('deleted' == $action) { + $info = self::$removed_theme_info; + } elseif ('installed' == $action) { + $info = self::$installed_theme_info; + } else { + $info_object = wp_get_theme($theme); + $info = array( + 'Name' => $info_object->get('Name'), + 'Version' => $info_object->get('Version'), + ); + } + + $name = empty($info['Name']) ? 'Unknown' : $info['Name']; + $version = empty($info['Version']) ? '0.0.0' : $info['Version']; + + $details = array( + 'theme' => array( + 'name' => $name, + 'version' => $version, + 'action' => $action, + 'network' => $network + ) + ); + do_action('aiowps_record_event', 'theme_' . $action, $details, $level); + } + + /** + * Adds a translation updated event to the audit log + * + * @param WP_Upgrader $upgrader - WP_Upgrader instance + * @param array $hook_extra - Array of bulk item update data + * + * @return void + */ + public static function translation_updated($upgrader, $hook_extra) { + + // If this is empty then we have no way to know if this is a plugin/theme/translation install/update so return as we catch this in plugin_installed() + if (empty($hook_extra)) return; + + if ('translation' !== $hook_extra['type'] || 'update' !== $hook_extra['action']) return; + + if (!isset($hook_extra['translations']) || empty($hook_extra['translations'])) return; + + foreach ($hook_extra['translations'] as $info) { + $details = array( + 'translation_updated' => $info + ); + do_action('aiowps_record_event', 'translation_updated', $details, 'info'); + } + } + + /** + * Adds a entity changed event to the audit log + * + * @param WP_Upgrader $upgrader - WP_Upgrader instance + * + * @return void + */ + public static function event_entity_changed($upgrader) { + + $entity = (isset($upgrader->result) && isset($upgrader->result['destination_name'])) ? $upgrader->result['destination_name'] : false; + + $details = array( + 'entity_changed' => array( + 'entity' => $entity, + ) + ); + do_action('aiowps_record_event', 'entity_changed', $details, 'warning'); + } + + /** + * Adds all the firewall rule events to the audit log + * + * @return void + */ + public static function rule_event() { + $aiowps_firewall_message_store = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::MESSAGE_STORE); + $events = array(); + foreach (array('active', 'not_active', 'triggered', 'not_triggered') as $event) { + $data = $aiowps_firewall_message_store->get('rule_'.$event); + + if (empty($data)) continue; + + foreach ($data as $rule) { + + $details = array( + 'firewall_event' => array( + 'event' => $event, + 'rule_name' => $rule['name'], + 'rule_family' => $rule['family'], + ) + ); + + $blog_id = AIOWPSecurity_Utility::get_blog_id_from_request($rule['request']); + + $rule['request'] = apply_filters('aios_audit_filter_request', $rule['request'], $event); + + $events[] = array( + 'network_id' => get_current_network_id(), + 'site_id' => $blog_id, + 'username' => (isset($rule['potential_user']) ? AIOWPSecurity_Utility::verify_username($rule['potential_user']) : false), + 'ip' => $rule['ip'], + 'level' => 'triggered' === $event ? 'warning' : 'info', + 'event_type' => 'rule_'.$event, + 'details' => wp_json_encode($details, true), + 'stacktrace' => (isset($rule['request']) ? print_r($rule['request'], true) : ''), // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r -- PCP warning. Part of AOIS error reporting system. + 'created' => $rule['time'] + ); + } + } + + if (empty($events)) return; + + do_action('aiowps_bulk_record_events', $events); + } + + /** + * Adds a password reset event to the audit log + * + * @param object $user_data - Object containing user's data + */ + public static function password_reset($user_data) { + + $user_login = (false === $user_data) ? 'unknown' : $user_data->user_login; + + $details = array( + 'password_reset' => array( + 'user_login' => $user_login + ) + ); + do_action('aiowps_record_event', 'password_reset', $details, 'warning'); + } + + /** + * Adds a user deleted event to the audit log + * + * @param int $user_id - the id of the deleted user + * @param int|null $reassign - the id of the user to reassign data to or null + * @param object $user_data - Object containing user's data + * + * @return void + */ + public static function user_deleted($user_id, $reassign, $user_data) { + + $user_login = (false === $user_data) ? 'unknown' : $user_data->user_login; + + $details = array( + 'user_deleted' => array( + 'user_id' => $user_id, + 'reassign' => $reassign, + 'user_login' => $user_login + + ) + ); + do_action('aiowps_record_event', 'user_deleted', $details, 'warning'); + } + + /** + * Adds a user removed event to the audit log + * + * @param int $user_id - the id of the removed user + * @param int $blog_id - the id of the blog the user was removed from + * @param int $reassign - the id of the user to reassign data to or null + * + * @return void + */ + public static function user_removed_from_blog($user_id, $blog_id, $reassign) { + $user_data = get_user_by('ID', $user_id); + $user_login = is_a($user_data, 'WP_User') && 0 !== $user_data->ID ? $user_data->user_login : 'unknown'; + + $details = array( + 'user_removed' => array( + 'user_id' => $user_id, + 'blog_id' => $blog_id, + 'reassign' => $reassign, + 'user_login' => $user_login + + ) + ); + do_action('aiowps_record_event', 'user_removed', $details, 'warning'); + } + + /** + * Adds a failed login event to the audit log + * + * @param string $username - the username for the failed login attempt + * + * @return void + */ + public static function event_failed_login($username) { + $user = is_email($username) ? get_user_by('email', $username) : get_user_by('login', $username); + $details = array( + 'failed_login' => array( + 'imported' => false, + 'username' => $username, + 'known' => true, + ) + ); + if (is_a($user, 'WP_User')) { + do_action('aiowps_record_event', 'failed_login', $details, 'warning', $username); + } else { + $details['failed_login']['known'] = false; + do_action('aiowps_record_event', 'failed_login', $details, 'warning', $username); + } + } + + /** + * Adds a user registration event to the audit log + * + * @param integer $user_id - the user ID of the newly registered user + * @param string $type - the type of registration valid values (admin, pending, registered) + * + * @return void + */ + public static function event_user_registration($user_id, $type) { + $registered_user = get_user_by('ID', $user_id); + $registered_username = is_a($registered_user, 'WP_User') && 0 !== $registered_user->ID ? $registered_user->user_login : ''; + + $details = array( + 'user_registration' => array( + 'registered_username' => $registered_username, + 'type' => $type, + ) + ); + + if ('admin' == $type) { + $admin_user = wp_get_current_user(); + $admin_username = is_a($admin_user, 'WP_User') ? $admin_user->user_login : ''; + $details['user_registration']['admin_username'] = $admin_username; + do_action('aiowps_record_event', 'user_registration', $details, 'info'); + } elseif ('pending' == $type) { + do_action('aiowps_record_event', 'user_registration', $details, 'info', $registered_username); + } elseif ('registered' == $type) { + do_action('aiowps_record_event', 'user_registration', $details, 'info', $registered_username); + } + } + + /** + * Adds a successful login event to the audit log + * + * @param string $username - the username for the successful login + * + * @return void + */ + public static function event_successful_login($username) { + $details = array( + 'successful_login' => array( + 'username' => $username, + ) + ); + do_action('aiowps_record_event', 'successful_login', $details, 'info', $username); + } + + /** + * Adds a successful logout event to the audit log + * + * @param string $username - the username for the successful logout + * @param boolean $force_logout - if the logout was a force logout + * + * @return void + */ + public static function event_successful_logout($username, $force_logout = false) { + $details = array( + 'successful_logout' => array( + 'username' => $username, + 'force_logout' => $force_logout ? __('(force logout)', 'all-in-one-wp-security-and-firewall') : '' + ) + ); + do_action('aiowps_record_event', 'successful_logout', $details, 'info', $username); + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-audit-text-handler.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-audit-text-handler.php new file mode 100755 index 00000000..8b1dec19 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-audit-text-handler.php @@ -0,0 +1,238 @@ + $info['event'], + 'rule_name' => $info['rule_name'], + 'rule_family' => $info['rule_family'], + ); + break; + } + + // Add a link to the rule, if present + if (isset($info['location'])) { + $output .= "

".__('Configure this rule', 'all-in-one-wp-security-and-firewall').''; + } + + return is_array($output) ? wp_json_encode($output) : $output; + } + + /** + * Return the text version of 'password_reset' event + * + * @param array $info + * @return string + */ + public static function password_reset_to_text($info) { + /* translators: %s: User login */ + return sprintf(__('Password for user account: `%s` successfully changed', 'all-in-one-wp-security-and-firewall'), $info['user_login']); + } + + /** + * Return the text version of 'user_deleted' event + * + * @param array $info + * @return string + */ + public static function user_deleted_to_text($info) { + if (empty($info['reassign'])) { + /* translators: 1: User login, 2: User ID */ + return sprintf(__('User account: %1$s with ID: `%2$s` has been deleted', 'all-in-one-wp-security-and-firewall'), $info['user_login'], $info['user_id']); + } else { + /* translators: 1: User login, 2: User ID, 3: Reassign */ + return sprintf(__('User account: `%1$s` with ID: `%2$s` has been deleted and all content has been reassigned to user with ID: `%3$s`', 'all-in-one-wp-security-and-firewall'), $info['user_login'], $info['user_id'], $info['reassign']); + } + } + + /** + * Return the text version of 'user_removed' event + * + * @param array $info + * @return string + */ + public static function user_removed_to_text($info) { + if (empty($info['reassign'])) { + /* translators: 1: User login, 2: User ID, 3: Blog ID */ + return sprintf(__('User account: %1$s with ID: `%2$s` has been removed from the blog with ID: `%3$s`', 'all-in-one-wp-security-and-firewall'), $info['user_login'], $info['user_id'], $info['blog_id']); + } else { + /* translators: 1: User login, 2: User ID, 3: Blog ID, 4: Reassign */ + return sprintf(__('User account: `%1$s` with ID: `%2$s` has been removed from the blog with ID: `%3$s` and all content has been reassigned to user with ID: `%4$s`', 'all-in-one-wp-security-and-firewall'), $info['user_login'], $info['user_id'], $info['blog_id'], $info['reassign']); + } + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-base-tasks.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-base-tasks.php new file mode 100755 index 00000000..c5935336 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-base-tasks.php @@ -0,0 +1,43 @@ +get_col("SELECT blog_id FROM $wpdb->blogs"); + foreach ($blog_ids as $blog_id) { + switch_to_blog($blog_id); + static::run_for_a_site(); + restore_current_blog(); + } + } else { + static::run_for_a_site(); + } + } + + /** + * Run uninstallation task for a single site. + * + * This method must be implemented in child classes. + * Since static abstract methods are not allowed in PHP, we enforce it at runtime. + * + * @throws Exception If not overridden in a child class. + * @return void + */ + protected static function run_for_a_site() { + throw new Exception( + sprintf('%s : Child classes must implement run_for_a_site() method.', get_called_class()) + ); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-bootstrap.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-bootstrap.php new file mode 100755 index 00000000..ca57abef --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-bootstrap.php @@ -0,0 +1,207 @@ +file_path); + + if (!isset($info['dirname'])) { + return new WP_Error( + 'file_no_directory', + 'No directory has been set', + $this->file_path + ); + } + + // phpcs:disable WordPress.WP.AlternativeFunctions -- wp_filesystem not recommended for firewall. + if (!is_writable($info['dirname'])) { + return new WP_Error( + 'file_directory_not_writable', + 'The directory has incorrect write permissions. Please double check its permissions and try again.', + $info['dirname'] + ); + } + + return (false !== @file_put_contents($this->file_path, $this->get_contents())); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore this + // phpcs:enable WordPress.WP.AlternativeFunctions -- wp_filesystem not recommended for firewall. + } + + /** + * Checks whether the bootstrap contents are valid + * + * @param string $contents + * @return boolean + */ + protected function is_content_valid($contents) { + + //Ensure we're using the correct version of the file + $version = $this->get_bootstrap_version(); + + if (false === $version) return false; + + if ($version['full_version'] !== $this->version) return false; + + //Ensure the required paths are valid + $regexes = array('/file_exists\((?\'.*\')\)/isU', '/include_once\((?\'.*\')\)/isU'); + $firewall_path_str = $this->get_firewall_path_str(); + + foreach ($regexes as $regex) { + + if (preg_match($regex, $contents, $matches)) { + + if ($firewall_path_str !== $matches['file_path']) return false; + + } + } + + return true; + } + + /** + * Returns the bootstrap version from file + * + * @return array|boolean Array with the version information; false otherwise. + */ + protected function get_bootstrap_version() { + + $contents = @file_get_contents($this->file_path); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore this + + if (false === $contents) return false; + + if (preg_match('/@version (?(?\d{1,})\.(?\d{1,})\.(?\d{1,}))$/m', $contents, $matches)) { + return $matches; + } + + return false; + } + + /** + * Get the firewall path string that contains "__DIR__" for home dir, if plugin dir isn't a symbolic link.. + * + * @return string The firewall path string. + */ + private function get_firewall_path_str() { + $firewall_path = AIOWPSecurity_Utility_Firewall::get_firewall_path(); + $firewall_path_str = $this->get_path_str_for_given_absolute_path($firewall_path); + return $firewall_path_str; + } + + /** + * Get path string to write bootstrap file from given path. + * + * @param string $path a path that we want to write to the bootstrap file. + * @return string The path that can be written in the bootstrap file. + */ + private function get_path_str_for_given_absolute_path($path) { + $home_path = AIOWPSecurity_Utility_File::get_home_path(); + // If the plugin is symbolic linked, then the plugin's firewall path is not started with home_path. + $path_str = (0 === strpos($path, $home_path)) ? "__DIR__.'/".substr($path, strlen($home_path))."'" : "'".$path."'"; + return $path_str; + } + + /** + * Get the firewall rules path string that contains "__DIR__" for home dir, if plugin dir isn't a symbolic link. + * + * @return string The firewall rule path string. + */ + private function get_firewall_rules_path_str() { + $firewall_rules_path = AIOWPSecurity_Utility_Firewall::get_firewall_rules_path(); + $firewall_rules_path_str = $this->get_path_str_for_given_absolute_path($firewall_rules_path); + return $firewall_rules_path_str; + } + + /** + * The regex pattern that demarcates our contents + * + * @return string + */ + protected function get_regex_pattern() { + return '#// Begin AIOWPSEC Firewall(.*)// End AIOWPSEC Firewall#isU'; + } + + /** + * Bootstrap file contents to insert + * + * @return string + */ + public function get_contents() { + $firewall_path_str = $this->get_firewall_path_str(); + $firewall_rules_path_str = $this->get_firewall_rules_path_str(); + + // Any extra data we want to have accessible to the firewall + $data = array( + 'ABSPATH' => wp_normalize_path(ABSPATH) + ); + + $code = "get_warning_message(); + + $directive = AIOWPSecurity_Utility_Firewall::get_already_set_directive(); + + if (!empty($directive) && $directive !== $this->file_path) { + $directive = wp_normalize_path($directive); + $code .= "// Previously set auto_prepend_file\n"; + $code .= "if (file_exists('{$directive}')) {\n"; + $code .= "\tinclude_once('{$directive}');\n"; + $code .= "}\n"; + } + + + $code .= '$GLOBALS[\'aiowps_firewall_rules_path\'] = '.$firewall_rules_path_str.";\n\n"; + + // write any other data we need + $code .= "\$GLOBALS['aiowps_firewall_data'] = array(\n"; + foreach ($data as $name => $value) { + $code .= "\t'{$name}' => '{$value}',\n"; + } + $code .= ");\n\n"; //close data array + + $code .= "// Begin AIOWPSEC Firewall\n"; + $code .= "if (file_exists({$firewall_path_str})) {\n"; + $code .= "\tinclude_once({$firewall_path_str});\n"; + $code .= "}\n"; + $code .= "// End AIOWPSEC Firewall\n"; + + return $code; + } + + /** + * Gets our warning message for users + * + * @return string + */ + protected function get_warning_message() { + + $warning = "/** \n"; + $warning .= " * @version {$this->version}\n"; + $warning .= " * WARNING: Please do not delete this file.\n"; + $warning .= " * \n"; + $warning .= " * This will cause PHP to throw a fatal error and render your site unusable.\n"; + $warning .= " * \n"; + $warning .= " * To safely delete this file, please check both your .user.ini file and your php.ini file and ensure this file is not set in the auto_prepend_file directive.\n"; + $warning .= " * \n"; + $warning .= " * Please ask your web hosting provider if you need guidance with executing the aforementioned steps.\n"; + $warning .= " */\n"; + + return $warning; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-file.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-file.php new file mode 100755 index 00000000..7561ba9b --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-file.php @@ -0,0 +1,202 @@ +file_path = $file_path; + } + + /** + * Insert the contents to the managed file + * + * @return boolean|WP_Error true if success; false if failed + */ + abstract public function insert_contents(); + + /** + * Returns the contents to be inserted into the managed file + * + * @return string + */ + abstract public function get_contents(); + + /** + * Returns the regex pattern that separates our contents from others the file may contain + * + * @return string + */ + abstract protected function get_regex_pattern(); + + /** + * Checks whether the file's contents are valid + * + * @param string $contents + * @return boolean + */ + abstract protected function is_content_valid($contents); + + /** + * Updates the contents of the managed file + * + * @return boolean|WP_Error true if updated; false if not updated + */ + public function update_contents() { + // phpcs:ignore WordPress.WP.AlternativeFunctions -- wp_filesystem not recommended. + if (!is_readable($this->file_path) || !is_writable($this->file_path)) { + return new WP_Error( + 'file_wrong_permissions', + 'The file has incorrect read or write permissions. Please double check its permissions and try again.', + $this->file_path + ); + } + + $contents = @file_get_contents($this->file_path); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore this + + if (false === $contents) { + return new WP_Error( + 'file_unable_to_read', + 'Unable to read the file. Please double check its permissions and try again.', + $this->file_path + ); + } + + $matches = array(); + $match_count = preg_match_all($this->get_regex_pattern(), $contents, $matches); + + if (empty($matches[1]) || false === $match_count) { + return false; + } + + //checks whether an update is required + $requires_update = false; + $match = ''; + foreach ($matches[1] as $match) { + + $requires_update = !$this->is_content_valid($match); + + if (true === $requires_update) { + break; + } + } + + //perform the update + if ($requires_update) { + + $block_removed = $this->remove_contents(); + $block_inserted = $this->insert_contents(); + + return (true === $block_removed && true === $block_inserted); + } + + return false; + } + + /** + * Checks whether the file contains our contents + * + * @return boolean|WP_Error true if found; false if not found + */ + public function contains_contents() { + + clearstatcache(); + if (!file_exists($this->file_path)) { + return new WP_Error( + 'file_does_not_exist', + 'The file does not exist.', + $this->file_path + ); + } + + if (!is_readable($this->file_path)) { + return new WP_Error( + 'file_wrong_permissions', + 'The file has incorrect read permissions. Please double check its permissions and try again.', + $this->file_path + ); + } + + $contents = @file_get_contents($this->file_path); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore this + + if (false === $contents) { + return new WP_Error( + 'file_unable_to_read', + 'Unable to read the file. Please double check its permissions and try again.', + $this->file_path + ); + } + + return (1 === preg_match($this->get_regex_pattern(), $contents)); + } + + /** + * Removes our contents from the file + * + * @return boolean|WP_Error + */ + public function remove_contents() { + + if (!is_readable($this->file_path) || !is_writable($this->file_path)) { + return new WP_Error( + 'file_wrong_permissions', + 'The file has incorrect read or write permissions. Please double check its permissions and try again.', + $this->file_path + ); + } + + $contents = @file_get_contents($this->file_path); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore this + + if (false === $contents) { + return new WP_Error( + 'file_unable_to_read', + 'Unable to read the file. Please double check its permissions and try again.', + $this->file_path + ); + } + + $removed = 0; + $contents = preg_replace($this->get_regex_pattern(), "", $contents, -1, $removed); + + if (null === $contents) { + return new WP_Error( + 'file_unable_to_alter', + 'Unable to alter the file.', + $this->file_path + ); + } + + if (false === @file_put_contents($this->file_path, $contents, LOCK_EX)) { // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore this + return new WP_Error( + 'file_unable_to_write', + 'Unable to write to the file. Please double check its permissions and try again.', + $this->file_path + ); + } + + return $removed > 0; + } + + /** + * By default returns the full path to the file being managed + * + * @return string + */ + public function __toString() { + return $this->file_path; + } + +} //end of class diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-htaccess.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-htaccess.php new file mode 100755 index 00000000..4673f3f8 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-htaccess.php @@ -0,0 +1,91 @@ +file_path + ); + } + + return (false !== @file_put_contents($this->file_path, $this->get_contents(), FILE_APPEND)); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore this + } + + /** + * Checks whether the file's contents are valid + * + * @param string $contents + * @return boolean + */ + protected function is_content_valid($contents) { + + $regex = '/php_value auto_prepend_file \'(.*)\'/isU'; + $bootstrap_path = AIOWPSecurity_Utility_Firewall::get_bootstrap_path(); + + $matches = array(); + + if (preg_match_all($regex, $contents, $matches)) { + $match = ''; + foreach ($matches[1] as $match) { + + if ($bootstrap_path !== $match) { + return false; + } + } + + } else { + return false; + } + + return true; + } + + /** + * The regex pattern that demarcates our contents + * + * @return string + */ + protected function get_regex_pattern() { + return '/\r?\n?# Begin AIOWPSEC Firewall(.*?)# End AIOWPSEC Firewall/is'; + } + + /** + * Our contents; the required apache directives for auto prepending a file + * + * @return string + */ + public function get_contents() { + $bootstrap_path = AIOWPSecurity_Utility_Firewall::get_bootstrap_path(); + + $directives = "\n# Begin AIOWPSEC Firewall\n"; + $directives .= "\t\n"; + $directives .= "\t\tphp_value auto_prepend_file '{$bootstrap_path}'\n"; + $directives .= "\t\n"; + $directives .= "\t\n"; + $directives .= "\t\tphp_value auto_prepend_file '{$bootstrap_path}'\n"; + $directives .= "\t\n"; + $directives .= "\t\n"; + $directives .= "\t\tphp_value auto_prepend_file '{$bootstrap_path}'\n"; + $directives .= "\t\n"; + $directives .= "# End AIOWPSEC Firewall"; + + return $directives; + } + + +} //end of class diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-litespeed.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-litespeed.php new file mode 100755 index 00000000..4a96f466 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-litespeed.php @@ -0,0 +1,29 @@ +\n"; + $directives .= "\t\tphp_value auto_prepend_file '{$bootstrap_path}'\n"; + $directives .= "\t\n"; + $directives .= "\t\n"; + $directives .= "\t\tphp_value auto_prepend_file '{$bootstrap_path}'\n"; + $directives .= "\t\n"; + $directives .= "# End AIOWPSEC Firewall"; + + return $directives; + } + + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-muplugin.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-muplugin.php new file mode 100755 index 00000000..711d4eaf --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-muplugin.php @@ -0,0 +1,93 @@ +file_path); + + if (!isset($info['dirname'])) { + return new WP_Error( + 'file_no_directory', + 'No directory has been set', + $this->file_path + ); + } + + if (false === wp_mkdir_p($info['dirname'])) { + return new WP_Error( + 'file_no_directory_created', + 'Unable to create the directory', + $info['dirname'] + ); + } + + return (false !== @file_put_contents($this->file_path, $this->get_contents())); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents -- WP_Filesystem is not appropriate here. + } + + /** + * Checks whether the mu-plugin contents are valid + * + * @param string $contents + * @return boolean + */ + protected function is_content_valid($contents) { + + //The regexes we extract the paths from + $regexes = array('/file_exists\(\'(.*)\'\)/isU', '/include_once\(\'(.*)\'\)/isU'); + $regex = ''; + $bootstrap_path = AIOWPSecurity_Utility_Firewall::get_bootstrap_path(); + + foreach ($regexes as $regex) { + $matches = array(); + $result = preg_match($regex, $contents, $matches); + + if (empty($matches[1]) || false === $result) { + continue; + } + + if ($bootstrap_path !== $matches[1]) { + return false; + } + + } + + return true; + } + + /** + * The regex pattern that demarcates our contents + * + * @return string + */ + protected function get_regex_pattern() { + return '#// Begin AIOWPSEC Firewall(.*)// End AIOWPSEC Firewall#isU'; + } + + /** + * Our firewall code to insert + * + * @return string + */ + public function get_contents() { + $bootstrap_path = AIOWPSecurity_Utility_Firewall::get_bootstrap_path(); + + $code = "file_path, $this->get_contents(), FILE_APPEND)); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore this + } + + /** + * Checks whether the user.ini file contents are valid + * + * @param string $contents + * @return boolean + */ + protected function is_content_valid($contents) { + + $regex = '/auto_prepend_file=\'(.*)\'/isU'; + $bootstrap_path = AIOWPSecurity_Utility_Firewall::get_bootstrap_path(); + + $match = array(); + $result = preg_match($regex, $contents, $match); + + if (empty($match[1]) || false === $result) { + return false; + } + + if ($bootstrap_path !== $match[1]) { + return false; + } + + return true; + + } + + /** + * Our regex pattern that demarcates our contents + * + * @return string + */ + protected function get_regex_pattern() { + return '/\r?\n?# Begin AIOWPSEC Firewall(.*?)# End AIOWPSEC Firewall/is'; + } + + /** + * Directives inserted into user.ini + * + * @return string + */ + public function get_contents() { + $bootstrap_path = AIOWPSecurity_Utility_Firewall::get_bootstrap_path(); + + $directive = "\n# Begin AIOWPSEC Firewall\n"; + $directive .= "auto_prepend_file='{$bootstrap_path}'\n"; + $directive .= "# End AIOWPSEC Firewall"; + + return $directive; + } + + /** + * Extends the contains_contents function to check for already set directives + * + * @return boolean|WP_Error + */ + public function contains_contents() { + $contains = parent::contains_contents(); + + if (false === $contains) { + $directive_userini = AIOWPSecurity_Utility_Firewall::get_already_set_directive($this->file_path); + $directive = AIOWPSecurity_Utility_Firewall::get_already_set_directive(); + + if ((AIOWPSecurity_Utility_Firewall::get_bootstrap_path() === $directive) || (AIOWPSecurity_Utility_Firewall::get_bootstrap_path() === $directive_userini)) { + return true; + } + } + + return $contains; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-wpconfig.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-wpconfig.php new file mode 100755 index 00000000..6fc2cf27 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-block-wpconfig.php @@ -0,0 +1,103 @@ +file_path) || !is_writable($this->file_path)) { + return new WP_Error( + 'file_wrong_permissions', + 'The file has incorrect read or write permissions. Please double check its permissions and try again.', + $this->file_path + ); + } + + //Take a backup of the file first + if (false === AIOWPSecurity_Utility_File::backup_and_rename_wp_config($this->file_path)) { + return new WP_Error( + 'file_unable_to_backup', + 'We were unable to take a backup of your file.', + $this->file_path + ); + } + + $wp_config = file($this->file_path, FILE_IGNORE_NEW_LINES); + + if (false === $wp_config) { + return new WP_Error( + 'file_no_contents', + 'Unable to access the file\'s contents', + $this->file_path + ); + } + + array_shift($wp_config); + array_unshift($wp_config, $this->get_contents()); + + return (false !== @file_put_contents($this->file_path, implode(PHP_EOL, $wp_config), LOCK_EX)); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore this + } + + /** + * Checks the validity of the content + * + * @param string $contents - contents we're checking + * @return boolean true if content is valid; false if invalid + */ + protected function is_content_valid($contents) { + //The regexes we extract the paths from + $regexes = array('/file_exists\(\'(.*)\'\)/isU', '/include_once\(\'(.*)\'\)/isU'); + $regex = ''; + $bootstrap_path = AIOWPSecurity_Utility_Firewall::get_bootstrap_path(); + + foreach ($regexes as $regex) { + $matches = array(); + $result = preg_match($regex, $contents, $matches); + + if (empty($matches[1]) || false === $result) { + continue; + } + + if ($bootstrap_path !== $matches[1]) { + return false; + } + } + + return true; + } + + /** + * The particular regex that demarcates our contents + * + * @return string + */ + protected function get_regex_pattern() { + return '#\r?\n?// Begin AIOWPSEC Firewall(.*?)// End AIOWPSEC Firewall#is'; + } + + /** + * Our firewall code to insert + * + * @return string + */ + public function get_contents() { + $bootstrap_path = AIOWPSecurity_Utility_Firewall::get_bootstrap_path(); + + $code = "prepare('SELECT blocked_ip FROM '.AIOWPSEC_TBL_PERM_BLOCK.' WHERE block_reason=%s', $block_reason); + } + + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $result = $wpdb->get_results($sql, $output_type); + //The result returned by wp function is multi-dim array. Let's return a simple single dimensional array of ip addresses + if (!empty($result)) { + foreach ($result as $item) { + $blocked_ip_array[] = $item['blocked_ip']; + } + } + return $blocked_ip_array; + } + + /** + * Checks if an IP address is blocked permanently according to the database + * + * @param int $ip_address + * + * @return bool + */ + public static function is_ip_blocked($ip_address) { + global $wpdb; + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $blocked_record = $wpdb->get_row($wpdb->prepare('SELECT * FROM '.AIOWPSEC_TBL_PERM_BLOCK.' WHERE blocked_ip=%s', $ip_address)); + return !empty($blocked_record); + } + + /** + * Will add an IP address to the permanent block list + * + * @param int $ip_address + * @param string $reason + * @return bool - TRUE or FALSE on error + */ + public static function add_ip_to_block_list($ip_address, $reason = '') { + global $wpdb, $aio_wp_security; + $user = wp_get_current_user(); + $roles_allowed_to_block_ips = apply_filters('aio_roles_allowed_to_block_ips', array('administrator', 'editor', 'author')); + if ('spam_discard' != $reason && array_intersect($roles_allowed_to_block_ips, $user->roles) && AIOWPSecurity_Utility_IP::get_user_ip_address() == $ip_address) { + return false; + } + + //Check if this IP address is already in the block list + $blocked = AIOWPSecurity_Blocking::is_ip_blocked($ip_address); + $time_now = current_time('mysql'); + if (empty($blocked)) { + //Add this IP to the blocked table + $data = array( + 'blocked_ip'=>$ip_address, + 'block_reason'=>$reason, + 'blocked_date'=>$time_now + ); + $data = apply_filters('aiowps_pre_add_to_permanent_block', $data); + $perm_block_tbl_name = AIOWPSEC_TBL_PERM_BLOCK; + $country_origin = isset($data['country_origin']) ? $data['country_origin'] : ''; + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.QuotedSimplePlaceholder, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $sql = $wpdb->prepare("INSERT INTO ".$perm_block_tbl_name." (blocked_ip, block_reason, blocked_date, country_origin, created) VALUES ('%s', '%s', '%s', '%s', UNIX_TIMESTAMP())", $data['blocked_ip'], $data['block_reason'], $data['blocked_date'], $country_origin); + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore. + $res = $wpdb->query($sql); + if (false === $res) { + $aio_wp_security->debug_logger->log_debug("AIOWPSecurity_Blocking::add_ip_to_block_list - Error inserting record into AIOWPSEC_TBL_PERM_BLOCK table for IP ".$ip_address); + return false; + } + return true; + } + return true; + } + + public static function unblock_ip($ip_address) { + global $wpdb; + $where = array('blocked_ip' => $ip_address); + // phpcs:ignore WordPress.DB -- PCP error. Direct call necessary. No caching needed. + $result = $wpdb->delete(AIOWPSEC_TBL_PERM_BLOCK, $where); + return $result; + } + + /** + * Will check the current visitor IP against the blocked table + * If IP present will block the visitor from viewing the site + */ + public static function check_visitor_ip_and_perform_blocking() { + global $aio_wp_security; + $visitor_ip = AIOWPSecurity_Utility_IP::get_user_ip_address(); + $ip_type = WP_Http::is_ip_address($visitor_ip); + if (empty($ip_type)) { + $aio_wp_security->debug_logger->log_debug("do_general_ip_blocking_tasks: ".$visitor_ip." is not a valid IP!", 4); + return; + } + + //Check if this IP address is in the block list + $blocked = AIOWPSecurity_Blocking::is_ip_blocked($visitor_ip); + //TODO - future feature: add blocking whitelist and check + + if (empty($blocked)) { + return; //Visitor IP is not blocked - allow page to load + } else { + //block this visitor!! + $redirect_url = sanitize_url(apply_filters('aios_blocked_request_redirect_url', 'http://127.0.0.1')); + AIOWPSecurity_Utility::redirect_to_url($redirect_url); + } + return; + + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-captcha.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-captcha.php new file mode 100755 index 00000000..8c580dab --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-captcha.php @@ -0,0 +1,941 @@ +upgrade_captcha_options(); + add_action('login_enqueue_scripts', array($this, 'aiowps_login_enqueue')); + add_filter('script_loader_tag', array($this, 'add_cfasync_data_attribute_to_captcha_tag'), 10, 2); + + + if (AIOWPSecurity_Utility::is_contact_form_7_plugin_active() && '1' == $aio_wp_security->configs->get_value('aiowps_enable_contact_form_7_captcha')) { + add_action('wpcf7_admin_init', array($this, 'add_contact_form_7_captcha_tag_generator_button'), 100, 0); + add_filter('wpcf7_contact_form_properties', array($this, 'add_contact_form_7_captcha')); + add_filter('wpcf7_validate', array($this, 'verify_contact_form_7_captcha'), 10, 2); + } + } + + + /** + * This method modifies the script tag output by adding 'data-cfasync="false"' attribute, + * which is used to disable Cloudflare Rocket Loader for the specified captcha script handle. + * + * @param string $tag - The generated HTML tag for the script. + * @param string $handle - The script handle being processed. + * + * @return string The modified HTML tag with 'data-cfasync="false"' if applicable. + */ + public function add_cfasync_data_attribute_to_captcha_tag($tag, $handle) { + global $aio_wp_security; + + // Get the default captcha from AIO WP Security configurations + $default_captcha = $aio_wp_security->configs->get_value('aiowps_default_captcha'); + + // Check if the current script handle matches the default captcha handle + if ($default_captcha === $handle) { + if (!preg_match('/\sdata-cfasync\s*=\s*["\']false["\']/', $tag)) { + // Add 'data-cfasync="false"' attribute to the script tag + $tag = str_replace('src=', 'data-cfasync="false" src=', $tag); + } + } + + // Return the modified or original script tag + return $tag; + } + + /** + * This function handles upgrading captcha options + * + * @return void + */ + private function upgrade_captcha_options() { + global $aio_wp_security; + + if (!empty($aio_wp_security->configs->get_value('aiowps_default_captcha'))) return; + + // Upgrade the default captcha option + if ($aio_wp_security->configs->get_value('aiowps_default_recaptcha')) { + $aio_wp_security->configs->set_value('aiowps_default_recaptcha', ''); + $aio_wp_security->configs->set_value('aiowps_default_captcha', 'google-recaptcha-v2'); + } elseif ('1' == $aio_wp_security->configs->get_value('aiowps_enable_login_captcha') || '1' == $aio_wp_security->configs->get_value('aiowps_enable_registration_page_captcha')) { + $aio_wp_security->configs->set_value('aiowps_default_captcha', 'simple-math'); + } else { + $aio_wp_security->configs->set_value('aiowps_default_captcha', 'none'); + } + } + + /** + * This function will return an array of supported CAPTCHA options + * + * @return array - an array of supported CAPTCHA options + */ + public function get_supported_captchas() { + return array( + 'none' => 'No CAPTCHA', + 'cloudflare-turnstile' => 'Cloudflare Turnstile', + 'google-recaptcha-v2' => 'Google reCAPTCHA V2', + 'simple-math' => 'Simple math CAPTCHA' + ); + } + + /** + * This function will return an array of supported CAPTCHA themes + * + * @return array - an array of supported CAPTCHA themes + */ + public function get_captcha_themes() { + return array( + 'auto' => __('Auto', 'all-in-one-wp-security-and-firewall'), + 'light' => __('Light', 'all-in-one-wp-security-and-firewall'), + 'dark' => __('Dark', 'all-in-one-wp-security-and-firewall'), + ); + } + + /** + * Enqueues the CAPTCHA script for the default CAPTCHA on the standard WP login page + * + * @return void + */ + public function aiowps_login_enqueue() { + global $aio_wp_security; + + if ($aio_wp_security->is_login_lockdown_by_const()) return; + + if ('1' != $aio_wp_security->configs->get_value('aiowps_enable_login_captcha') && '1' != $aio_wp_security->configs->get_value('aiowps_enable_registration_page_captcha')) return; + + $default_captcha = $aio_wp_security->configs->get_value('aiowps_default_captcha'); + + switch ($default_captcha) { + case 'cloudflare-turnstile': + case 'google-recaptcha-v2': + wp_enqueue_script($default_captcha, $this->get_captcha_script_url($default_captcha), array()); + // Below is needed to provide some space for the CAPTCHA form (otherwise it appears partially hidden on RHS) + wp_add_inline_style('login', "#login { width: 340px; }"); + break; + default: + break; + } + } + + /** + * If the user is not on the WooCommerce account page, enqueue the CAPTCHA script in the wp_head for general pages + * Caters for scenarios when CAPTCHA is used on wp comments or custom wp login form pages + * + * @return void + */ + public function add_captcha_script() { + global $aio_wp_security; + + // Do NOT enqueue if this is the main WooCommerce account login page because for WooCommerce page we "explicitly" render the reCAPTCHA widget + $is_woo = false; + + // We don't want to load for Woo account page because we have a special function for this + if (function_exists('is_account_page')) $is_woo = is_account_page(); + + if (!empty($is_woo)) return; + + $default_captcha = $aio_wp_security->configs->get_value('aiowps_default_captcha'); + + switch ($default_captcha) { + case 'cloudflare-turnstile': + case 'google-recaptcha-v2': + wp_enqueue_script($default_captcha, $this->get_captcha_script_url($default_captcha), array()); + break; + default: + break; + } + } + + /** + * Renders CAPTCHA on form produced by the wp_login_form() function, ie, custom wp login form + * + * @param string $cust_html_code + * + * @return string + */ + public function insert_captcha_custom_login($cust_html_code) { + global $aio_wp_security; + + if ($aio_wp_security->is_login_lockdown_by_const()) return ''; + + $default_captcha = $aio_wp_security->configs->get_value('aiowps_default_captcha'); + + switch ($default_captcha) { + case 'cloudflare-turnstile': + case 'google-recaptcha-v2': + $cust_html_code .= $this->get_captcha_form($default_captcha, 0, true); + return $cust_html_code; + break; + case 'simple-math': + $maths_captcha_input_id = uniqid('aiowps-captcha-answer-'); // Generate a unique DOM-safe ID for the maths captcha input field to avoid duplicate IDs (when multiple forms appear on the same page). + $cap_form = '

'; + $cap_form .= '

'; + $maths_question_output = $aio_wp_security->captcha_obj->generate_maths_question($maths_captcha_input_id); + $cap_form .= $maths_question_output . '

'; + + $cust_html_code .= $cap_form; + return $cust_html_code; + break; + default: + return ''; + break; + } + } + + /** + * Inserts captcha into the password-protected page form. + * + * @param string $cust_html_code The HTML code for the password form. + * @return string The modified HTML code with the captcha inserted. + */ + public function insert_captcha_password_protected($cust_html_code) { + global $post, $aio_wp_security; + + $loginurl = esc_url(site_url('/wp-login.php?action=postpass')); + + $label = 'pwbox-' . empty($post->ID) ? rand() : $post->ID; + $default_captcha = $aio_wp_security->configs->get_value('aiowps_default_captcha'); + + $cust_html_code = '
+
+ + + '; + switch ($default_captcha) { + case 'cloudflare-turnstile': + case 'google-recaptcha-v2': + $cust_html_code .= $this->get_captcha_form($default_captcha, 0, true); + $this->add_captcha_script(); + break; + case 'simple-math': + $maths_captcha_input_id = uniqid('aiowps-captcha-answer-'); // Generate a unique DOM-safe ID for the maths captcha input field to avoid duplicate IDs (when multiple forms appear on the same page). + $captcha_form = '

'; + $captcha_form .= '

'; + $maths_question_output = $aio_wp_security->captcha_obj->generate_maths_question($maths_captcha_input_id); + $captcha_form .= $maths_question_output . '

'; + $cust_html_code .= $captcha_form; + break; + default: + break; + } + $cust_html_code .= ' +
+
'; + return $cust_html_code; + } + + /** + * Validates the password form on password protected pages with captcha. + * + * @return void + */ + public function validate_password_protected_password_form_with_captcha() { + // Check password protected page captcha + $verify = $this->verify_captcha_submit(); + if (!$verify) { + wp_die(__('Captcha verification failed.', 'all-in-one-wp-security-and-firewall'). ' ' . __('Please try again.', 'all-in-one-wp-security-and-firewall')); + } + } + + /** + * Insert CAPTCHA question form on WooCommerce my account page forms or other forms. + * + * This function determines the type of CAPTCHA to display based on the configured default CAPTCHA type. + * It handles special cases for WooCommerce "my account" page where both login and register forms need + * CAPTCHAs rendered explicitly. For other forms, it renders CAPTCHA normally. + * + * @global object $aio_wp_security The global instance of the aio_wp_security class, which holds configuration settings. + * + * @return void + */ + public function insert_captcha_question_form() { + global $aio_wp_security; + + $default_captcha = $aio_wp_security->configs->get_value('aiowps_default_captcha'); + + switch ($default_captcha) { + case 'cloudflare-turnstile': + case 'google-recaptcha-v2': + // WooCommerce "my account" page needs special consideration, ie, + // need to display two CAPTCHA forms on same page (for login and register forms) + // For this case we use the "explicit" CAPTCHA display + $calling_hook = current_filter(); + if ('woocommerce_login_form' == $calling_hook || 'woocommerce_lostpassword_form' == $calling_hook || 'woocommerce_after_checkout_billing_form' == $calling_hook) { + $this->get_captcha_form($default_captcha, 1); + return; + } + + if ('woocommerce_register_form' == $calling_hook) { + $this->get_captcha_form($default_captcha, 1); + return; + } + + // For all other forms simply display CAPTCHA as normal + $this->display_captcha_form($default_captcha); + break; + case 'simple-math': + // Display plain maths CAPTCHA form + $this->display_captcha_form($default_captcha); + break; + default: + break; + } + } + + /** + * For WooCommerce my account page - display two separate CAPTCHA forms "explicitly" + * + * @return void + */ + public function print_captcha_api_woo() { + global $aio_wp_security; + + + //captcha should only show for woo account and checkout page + if ((function_exists('is_account_page') && !is_account_page()) && (function_exists('is_checkout') && !is_checkout()) && !apply_filters('aios_print_captcha_api_woo', false)) return; + + $default_captcha = $aio_wp_security->configs->get_value('aiowps_default_captcha'); + + if ('cloudflare-turnstile' == $default_captcha) : + $site_key = esc_html($aio_wp_security->configs->get_value('aiowps_turnstile_site_key')); + ?> + + configs->get_value('aiowps_recaptcha_site_key')); + ?> + + + configs->get_value('aiowps_enable_bp_register_captcha') == '1' && defined('BP_VERSION')) { + //if buddy press feature active add action hook so buddy press can display our errors properly on bp registration form + do_action('bp_aiowps-captcha-answer_errors'); + } + + switch ($default_captcha) { + case 'cloudflare-turnstile': + if ('1' == $aio_wp_security->configs->get_value('aios_cloudflare_turnstile_invalid_configuration')) return; + if ($return_instead_of_echo) return $this->get_captcha_form($default_captcha, 0, $return_instead_of_echo); + $this->get_captcha_form($default_captcha); + break; + case 'google-recaptcha-v2': + if ('1' == $aio_wp_security->configs->get_value('aios_google_recaptcha_invalid_configuration')) return; + if ($return_instead_of_echo) return $this->get_captcha_form($default_captcha, 0, $return_instead_of_echo); + $this->get_captcha_form($default_captcha); + break; + case 'simple-math': + $maths_captcha_input_id = uniqid('aiowps-captcha-answer-'); // Generate a unique DOM-safe ID for the maths captcha input field to avoid duplicate IDs (when multiple forms appear on the same page). + $cap_form = '

'; + $cap_form .= '

'; + $maths_question_output = $this->generate_maths_question($maths_captcha_input_id); + $cap_form .= $maths_question_output . '

'; + if ($return_instead_of_echo) return $cap_form; + echo $cap_form; + break; + } + } + + /** + * It generates a random math problem, stores the answer in the database, and returns the math problem + * + * @param string $maths_captcha_input_id A unique identifier used for the captcha input field's ID attribute to prevent duplicate IDs in the DOM (e.g., when multiple forms exist on a page). + * + * @return string - contains the HTML for the captcha. + */ + private function generate_maths_question($maths_captcha_input_id) { + global $aio_wp_security; + //For now we will only do plus, minus, multiplication + $equation_string = ''; + $operator_type = array('+', '−', '×'); + + $operand_display = array('word', 'number'); + + //let's now generate an equation + $operator = $operator_type[rand(0, 2)]; + + if ('×' === $operator) { + //Don't make the question too hard if multiplication + $first_digit = rand(1, 5); + $second_digit = rand(1, 5); + } else { + $first_digit = rand(1, 20); + $second_digit = rand(1, 20); + } + + if ('word' == $operand_display[rand(0, 1)]) { + $first_operand = $this->number_word_mapping($first_digit); + } else { + $first_operand = $first_digit; + } + + if ('word' == $operand_display[rand(0, 1)]) { + $second_operand = $this->number_word_mapping($second_digit); + } else { + $second_operand = $second_digit; + } + + //Let's calculate the result and construct the equation string + if ('+' === $operator) { + //Addition + $result = $first_digit+$second_digit; + $equation_string .= $first_operand . ' ' . $operator . ' ' . $second_operand . ' = '; + } elseif ('−' === $operator) { + //Subtraction + //If we are going to be negative let's swap operands around + if ($first_digit < $second_digit) { + $equation_string .= $second_operand . ' ' . $operator . ' ' . $first_operand . ' = '; + $result = $second_digit-$first_digit; + } else { + $equation_string .= $first_operand . ' ' . $operator . ' ' . $second_operand . ' = '; + $result = $first_digit-$second_digit; + } + } elseif ('×' === $operator) { + //Multiplication + $equation_string .= $first_operand . ' ' . $operator . ' ' . $second_operand . ' = '; + $result = $first_digit*$second_digit; + } + + //Let's encode correct answer + $captcha_secret_string = $aio_wp_security->configs->get_value('aiowps_captcha_secret_key'); + $current_time = time(); + $enc_result = base64_encode($current_time.$captcha_secret_string.$result); + $random_str = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(10); + if (is_multisite()) { + update_site_option('aiowps_captcha_string_info_'.$random_str, $enc_result); + update_site_option('aiowps_captcha_string_info_time_'.$random_str, $current_time); + } else { + update_option('aiowps_captcha_string_info_'.$random_str, $enc_result, false); + update_option('aiowps_captcha_string_info_time_'.$random_str, $current_time, false); + } + $equation_string .= ''; + $equation_string .= ''; + $equation_string .= ''; + return $equation_string; + } + + /** + * This function takes a number and returns the word that represents that number + * + * @param integer $num - the number we want to map to a word + * + * @return string - the mapped word + */ + private function number_word_mapping($num) { + $number_map = array( + 1 => __('one', 'all-in-one-wp-security-and-firewall'), + 2 => __('two', 'all-in-one-wp-security-and-firewall'), + 3 => __('three', 'all-in-one-wp-security-and-firewall'), + 4 => __('four', 'all-in-one-wp-security-and-firewall'), + 5 => __('five', 'all-in-one-wp-security-and-firewall'), + 6 => __('six', 'all-in-one-wp-security-and-firewall'), + 7 => __('seven', 'all-in-one-wp-security-and-firewall'), + 8 => __('eight', 'all-in-one-wp-security-and-firewall'), + 9 => __('nine', 'all-in-one-wp-security-and-firewall'), + 10 => __('ten', 'all-in-one-wp-security-and-firewall'), + 11 => __('eleven', 'all-in-one-wp-security-and-firewall'), + 12 => __('twelve', 'all-in-one-wp-security-and-firewall'), + 13 => __('thirteen', 'all-in-one-wp-security-and-firewall'), + 14 => __('fourteen', 'all-in-one-wp-security-and-firewall'), + 15 => __('fifteen', 'all-in-one-wp-security-and-firewall'), + 16 => __('sixteen', 'all-in-one-wp-security-and-firewall'), + 17 => __('seventeen', 'all-in-one-wp-security-and-firewall'), + 18 => __('eighteen', 'all-in-one-wp-security-and-firewall'), + 19 => __('nineteen', 'all-in-one-wp-security-and-firewall'), + 20 => __('twenty', 'all-in-one-wp-security-and-firewall'), + ); + return $number_map[$num]; + } + + /** + * This function will return the CAPTCHA script URL + * + * @param string $default_captcha - the default CAPTCHA + * + * @return string - the CAPTCHA script URL + */ + private function get_captcha_script_url($default_captcha) { + $url = ''; + switch ($default_captcha) { + case 'cloudflare-turnstile': + $url = 'https://challenges.cloudflare.com/turnstile/v0/api.js'; + break; + case 'google-recaptcha-v2': + $url = 'https://www.google.com/recaptcha/api.js?hl=' . $this->get_google_recaptcha_compatible_site_locale(); + break; + default: + break; + } + + return $url; + } + + /** + * This function will return the CAPTCHA form + * + * @param string $default_captcha - the default CAPTCHA + * @param integer $include_wc_id - the WooCommerce form id to include, if 0 no id is included if 1 dynamic id included + * @param boolean $return_instead_of_echo - if we should return the form rather than echo it to page + * + * @return string - can return the CAPTCHA form + */ + public function get_captcha_form($default_captcha, $include_wc_id = 0, $return_instead_of_echo = false) { + global $aio_wp_security; + static $aios_wc_element_id; + $captcha_form = ''; + $captcha_data_callback = ''; + $wc_form_id = !empty($include_wc_id) ? 'id="woo_recaptcha_'.(++$aios_wc_element_id).'"' : ''; + $captcha_data_callback = apply_filters('aios_captcha_data_callback', false) ? ' data-callback="data_callback"' : ''; + + switch ($default_captcha) { + case 'cloudflare-turnstile': + $site_key = esc_html($aio_wp_security->configs->get_value('aiowps_turnstile_site_key')); + $turnstile_theme = esc_html($aio_wp_security->configs->get_value('aiowps_turnstile_theme')); + if (empty($turnstile_theme)) $turnstile_theme = 'auto'; + $captcha_form = '
'; + break; + case 'google-recaptcha-v2': + $site_key = esc_html($aio_wp_security->configs->get_value('aiowps_recaptcha_site_key')); + $captcha_form = '
'; + break; + default: + return ''; + break; + } + + if ($return_instead_of_echo) return $captcha_form; + echo $captcha_form; + } + + /** + * Verifies the math or Google reCAPTCHA v2 forms + * Returns TRUE if correct answer. + * Returns FALSE on wrong CAPTCHA result or missing data. + * + * @return boolean + */ + public function verify_captcha_submit() { + global $aio_wp_security; + + $default_captcha = $aio_wp_security->configs->get_value('aiowps_default_captcha'); + + switch ($default_captcha) { + case 'cloudflare-turnstile': + // Cloudflare Turnstile enabled + if ('1' == $aio_wp_security->configs->get_value('aios_cloudflare_turnstile_invalid_configuration')) return true; + + // Expected CAPTCHA field in $_POST but got none! + if (!array_key_exists('cf-turnstile-response', $_POST)) return false; + + $cf_turnstile_response = isset($_POST['cf-turnstile-response']) ? stripslashes($_POST['cf-turnstile-response']) : ''; + $verify_captcha = $this->verify_turnstile_recaptcha($cf_turnstile_response); + return $verify_captcha; + break; + case 'google-recaptcha-v2': + // Google reCAPTCHA enabled + if ('1' == $aio_wp_security->configs->get_value('aios_google_recaptcha_invalid_configuration')) return true; + + // Expected CAPTCHA field in $_POST but got none! + if (!array_key_exists('g-recaptcha-response', $_POST)) return false; + + $g_recaptcha_response = isset($_POST['g-recaptcha-response']) ? stripslashes($_POST['g-recaptcha-response']) : ''; + $verify_captcha = $this->verify_google_recaptcha($g_recaptcha_response); + return $verify_captcha; + break; + case 'simple-math': + // Math CAPTCHA is enabled + if (!array_key_exists('aiowps-captcha-answer', $_POST)) return false; + $captcha_answer = isset($_POST['aiowps-captcha-answer']) ? stripslashes($_POST['aiowps-captcha-answer']) : ''; + + $verify_captcha = $this->verify_math_captcha_answer($captcha_answer); + return $verify_captcha; + break; + default: + return true; + break; + } + } + + /** + * Verifies the math CAPTCHA answer entered by the user + * + * @param type $captcha_answer + * + * @return boolean + */ + private function verify_math_captcha_answer($captcha_answer = '') { + global $aio_wp_security; + $captcha_secret_string = $aio_wp_security->configs->get_value('aiowps_captcha_secret_key'); + $captcha_temp_string = sanitize_text_field($_POST['aiowps-captcha-temp-string']); + $submitted_encoded_string = base64_encode($captcha_temp_string.$captcha_secret_string.$captcha_answer); + $trans_handle = sanitize_text_field($_POST['aiowps-captcha-string-info']); + if (is_multisite()) { + $captcha_string_info_option = get_site_option('aiowps_captcha_string_info_'.$trans_handle); + } else { + $captcha_string_info_option = get_option('aiowps_captcha_string_info_'.$trans_handle); + } + if ($submitted_encoded_string === $captcha_string_info_option) { + return true; + } else { + return false; // wrong answer was entered + } + } + + /** + * Send a query to Cloudflare API to verify Turnstile submission + * + * @param string $resp_token + * + * @return boolean + */ + private function verify_turnstile_recaptcha($resp_token = '') { + global $aio_wp_security; + + $url = $this->cloudflare_verify_turnstile_url; + $secret = $aio_wp_security->configs->get_value('aiowps_turnstile_secret_key'); + return $this->verify_captcha_response($url, $secret, $resp_token); + } + + /** + * Send a query to Google API to verify reCAPTCHA submission + * + * @param string $resp_token + * + * @return boolean + */ + private function verify_google_recaptcha($resp_token = '') { + global $aio_wp_security; + + $url = $this->google_verify_recaptcha_url; + $secret = $aio_wp_security->configs->get_value('aiowps_recaptcha_secret_key'); + return $this->verify_captcha_response($url, $secret, $resp_token); + } + + /** + * This function sends a remote request to verify the captcha response. + * + * @param string $url - The URL to the CAPTCHA API. + * @param string $secret - The secret key you got from the CAPTCHA provider. + * @param string $resp_token - The value of the CAPTCHA response form field. + * + * @return boolean - true if valid otherwise false + */ + private function verify_captcha_response($url, $secret, $resp_token) { + + $is_humanoid = false; + + if (empty($resp_token)) return $is_humanoid; + + $ip_address = AIOWPSecurity_Utility_IP::get_user_ip_address(); + $response = wp_safe_remote_post($url, array( + 'body' => array( + 'secret' => $secret, + 'response' => $resp_token, + 'remoteip' => $ip_address, + ), + )); + + if (wp_remote_retrieve_response_code($response) != 200) return $is_humanoid; + + $response = wp_remote_retrieve_body($response); + $response = json_decode($response, true); + + if (isset($response['success']) && true == $response['success']) $is_humanoid = true; + + // We did not get a success response so check for the "timeout-or-duplicate" error code because it's possible we have sent this request a second time if another plugin has recalled the WP authentication code and this error code means the captcha has already been solved so return success + if (isset($response['error-codes']) && in_array('timeout-or-duplicate', $response['error-codes'])) $is_humanoid = true; + + return $is_humanoid; + } + + /** + * Get site locale code for Google reCaptcha. + * + * @return string The site locale code. + */ + private function get_google_recaptcha_compatible_site_locale() { + $google_recaptcha_locale_codes = AIOS_Abstracted_Ids::get_google_recaptcha_locale_codes(); + $locale = str_replace('_', '-', determine_locale()); + + if (in_array($locale, $google_recaptcha_locale_codes, true)) { + return $locale; + } + + // Return 2 letter locale code. + $locale = explode('-', $locale); + return $locale[0]; + } + + /** + * Verify Cloudflare Turnstile configuration. + * + * @param String $site_key + * @param String $secret_key + * + * @return Boolean + */ + public function cloudflare_turnstile_verify_configuration($site_key, $secret_key) { + if (empty($site_key) || empty($secret_key)) return false; + return true; + } + + /** + * Verify Google reCAPTCHA configuration. + * + * @param String $site_key + * @param String $secret_key + * + * @return Boolean + */ + public function google_recaptcha_verify_configuration($site_key, $secret_key) { + $site_key_verify_params = array('k' => $site_key, 'size' => 'checkbox'); + $site_key_verify_url = esc_url(add_query_arg($site_key_verify_params, 'https://www.google.com/recaptcha/api2/anchor')); + $site_key_verify_response_body = wp_remote_retrieve_body(wp_remote_get($site_key_verify_url)); + + $secret_key_verify_params = array('secret' => $secret_key); + $secret_key_verify_url = esc_url(add_query_arg($secret_key_verify_params, $this->google_verify_recaptcha_url)); + $secret_key_verify_response_body = wp_remote_retrieve_body(wp_remote_get($secret_key_verify_url)); + $secret_key_verify_json = json_decode($secret_key_verify_response_body, true); + + if (false !== strpos($site_key_verify_response_body, 'Invalid site key') || is_null($secret_key_verify_json) || (isset($secret_key_verify_json['error-codes']) && in_array('invalid-input-secret', $secret_key_verify_json['error-codes']))) { + return false; + } else { + return true; + } + } + + /** + * This function adds captcha to contact form 7 + * + * @param array $form_properties - this is the array containing properties for the form + * + * @return array $form_properties - containing the edited form with the captcha if everything is set + */ + public function add_contact_form_7_captcha($form_properties) { + global $aio_wp_security; + + if (!class_exists('WPCF7_RECAPTCHA') || is_admin()) return $form_properties; // if wpc7_recaptcha does not exist or the call is from the admin page + + $recaptcha_service = WPCF7_RECAPTCHA::get_instance(); + + // if recaptcha is active return form + if ($recaptcha_service->is_active()) return $form_properties; + + $default_captcha = $aio_wp_security->configs->get_value('aiowps_default_captcha'); + + // check if default captcha configuration is correct + if (!$this->verify_captcha_configuration($default_captcha)) { + $aio_wp_security->debug_logger->log_debug("The captcha $default_captcha is not correctly configured", 4); + return $form_properties; + } + $form = isset($form_properties['form']) ? $form_properties['form'] : ''; + if (empty($form)) return $form_properties; + + // enqueue script + wp_enqueue_script($default_captcha, $this->get_captcha_script_url($default_captcha), array()); + + $field = $this->display_captcha_form($default_captcha, true); + $field .= ""; // add validation field for the captcha + $captcha_shortcode = sprintf('[%s]', AIOWPSEC_CAPTCHA_SHORTCODE); + + if (false !== strpos($form, $captcha_shortcode)) { + $replacement_string = $captcha_shortcode; + } else { + $replacement_string = '[submit'; + // if shortcode doesn't exist in form then use the submit button as placement for the captcha + if (false !== stripos($form, $replacement_string)) { + $field .= $replacement_string; + } else { + $pattern = '/]+type\s*=\s*(["\']?)submit\\1[^>]*>/i'; + + if (preg_match($pattern, $form, $matches)) { + $field .= $matches[0]; + $replacement_string = $matches[0]; + } + } + } + // replace first occurence of replacement string + $form = preg_replace('/' . preg_quote($replacement_string, '/') . '/', $field, $form, 1); + $form_properties['form'] = $form; + + return $form_properties; + } + + /** + * This verifies contact form 7 captcha + * + * @param WPCF7_Validation $result - This is the form result from contact form 7 plugin + * @return WPCF7_Validation - The validation for a contact form 7 form + */ + public function verify_contact_form_7_captcha($result) { + if (!class_exists('WPCF7_Submission') || !class_exists('WPCF7_RECAPTCHA')) return $result; + + $recaptcha_service = WPCF7_RECAPTCHA::get_instance(); + // if recaptcha is active return result + if ($recaptcha_service->is_active()) return $result; + + $post = WPCF7_Submission::get_instance(); + $message = __('Your CAPTCHA answer was incorrect - please try again.', 'all-in-one-wp-security-and-firewall'); + + if (!empty($post)) { + $data = $post->get_posted_data(); + $field_name = $this->get_contact_form_7_captcha_post_field_name(); + + if (empty($field_name) || false === array_key_exists($field_name, $data)) return $result; // if field name is empty or field doesn't exist return + + if (empty($data[$field_name])) { + $result->invalidate(array('type' => 'captcha', 'name' => 'aiowps-captcha'), $message); + return $result; + } + + $verify = $this->verify_captcha_submit(); + if (!$verify) { + $result->invalidate(array('type' => 'captcha', 'name' => 'aiowps-captcha'), $message); + return $result; + } + } + + return $result; + } + + /** + * This function gets the field name for the captcha + * + * @return string - The field name for the CAPTCHA if the feature is activated, an empty string if it's not + */ + private function get_contact_form_7_captcha_post_field_name() { + global $aio_wp_security; + + $default_captcha = $aio_wp_security->configs->get_value('aiowps_default_captcha'); + $field = ''; + + switch ($default_captcha) { + case 'cloudflare-turnstile': + $field = 'cf-turnstile-response'; + break; + case 'google-recaptcha-v2': + $field = 'g-recaptcha-response'; + break; + case 'simple-math': + $field = 'aiowps-captcha-answer'; + break; + } + + return $field; + } + + /** + * This checks if the default captcha is configured correctly + * + * @param string $default_captcha - the default CAPTCHA + * + * @return bool - True if the captcha configuration is correct, otherwise false. + */ + public function verify_captcha_configuration($default_captcha) { + global $aio_wp_security; + + if (empty($default_captcha)) return false; + + $verify = true; + + switch ($default_captcha) { + case 'cloudflare-turnstile': + $verify = $this->cloudflare_turnstile_verify_configuration($aio_wp_security->configs->get_value('aiowps_turnstile_site_key'), $aio_wp_security->configs->get_value('aiowps_turnstile_secret_key')); + break; + case 'google-recaptcha-v2': + $verify = $this->google_recaptcha_verify_configuration($aio_wp_security->configs->get_value('aiowps_recaptcha_site_key'), $aio_wp_security->configs->get_value('aiowps_recaptcha_secret_key')); + break; + } + + return $verify; + } + + /** + * This function adds the aiowps contact form 7 CAPTCHA + * + * @return void + */ + public function add_contact_form_7_captcha_tag_generator_button() { + if (!class_exists('WPCF7_TagGenerator')) return; + + $tag_generator = WPCF7_TagGenerator::get_instance(); + $tag_generator->add('aios-captcha', sprintf(__('%s captcha', 'all-in-one-wp-security-and-firewall'), 'aios'), array($this, 'contact_form_7_tag_generator_button'), ''); + } + + /** + * This function is the callback for adding the captcha tag + * + * @return void + */ + public function contact_form_7_tag_generator_button() { + $type = AIOWPSEC_CAPTCHA_SHORTCODE; + ?> +
+
+ +
+
+
+ +
+ +
+
+ verify_captcha_submit()) { + $errors[] = sprintf(__('%s: Your answer was incorrect - please try again.', 'all-in-one-wp-security-and-firewall'), '' . __('ERROR', 'all-in-one-wp-security-and-firewall') . ''); + } + + return $errors; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-cleanup.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-cleanup.php new file mode 100755 index 00000000..f3345fd8 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-cleanup.php @@ -0,0 +1,48 @@ +aiowps_feature_mgr)) return true; + + $this->aiowps_feature_mgr = new AIOWPSecurity_Feature_Item_Manager(); + + $initialized = true; + + return true; + } + + /** + * Retrieves the feature manager object. + * + * This method initializes the feature manager if necessary and returns the + * AIOWPSecurity_Feature_Item_Manager instance. If the initialization fails or + * the feature manager object is empty, it returns a WP_Error. + * + * @return AIOWPSecurity_Feature_Item_Manager|WP_Error + */ + private function get_feature_mgr_object() { + + $do_init = $this->feature_mgr_init(); + + if (true === $do_init && !empty($this->aiowps_feature_mgr)) return $this->aiowps_feature_mgr; + + return new WP_Error('not_initialized', __('The feature item manager could not be initialized.', 'all-in-one-wp-security-and-firewall')); + } + + /** + * Get IP address of given method. + * + * @param array $data - the request data + * + * @return array|WP_Error - an array response or a WP_Error if there was an error + */ + public function get_ip_address_of_given_method($data) { + $ip_method_id = $data['ip_retrieve_method']; + $ip_retrieve_methods = AIOS_Abstracted_Ids::get_ip_retrieve_methods(); + if (isset($ip_retrieve_methods[$ip_method_id])) { + return array( + 'ip_address' => isset($_SERVER[$ip_retrieve_methods[$ip_method_id]]) ? sanitize_text_field(wp_unslash($_SERVER[$ip_retrieve_methods[$ip_method_id]])) : '', + ); + } else { + return new WP_Error('aios-invalid-ip-retrieve-method', __('Invalid IP retrieve method.', 'all-in-one-wp-security-and-firewall')); + } + die; + } + + /** + * Dismiss a notice + * + * @param array $data - the request data contains the notice to dismiss + * + * @return array + */ + public function dismiss_notice($data) { + global $aio_wp_security; + + $time_now = $aio_wp_security->notices->get_time_now(); + + if (in_array($data['notice'], array('dismissdashnotice', 'dismiss_season'))) { + $aio_wp_security->configs->set_value($data['notice'], $time_now + (366 * 86400)); + } elseif (in_array($data['notice'], array('dismiss_page_notice_until', 'dismiss_notice'))) { + $aio_wp_security->configs->set_value($data['notice'], $time_now + (84 * 86400)); + } elseif ('dismiss_review_notice' == $data['notice']) { + if (empty($data['dismiss_forever'])) { + $aio_wp_security->configs->set_value($data['notice'], $time_now + (84 * 86400)); + } else { + $aio_wp_security->configs->set_value($data['notice'], $time_now + (100 * 365.25 * 86400)); + } + } elseif ('dismiss_automated_database_backup_notice' == $data['notice']) { + $aio_wp_security->delete_automated_backup_configs(); + } elseif ('dismiss_ip_retrieval_settings_notice' == $data['notice']) { + $aio_wp_security->configs->set_value($data['notice'], 1); + } elseif ('dismiss_ip_retrieval_settings_notice' == $data['notice']) { + $aio_wp_security->configs->set_value('aiowps_is_login_whitelist_disabled_on_upgrade', 1); + } elseif ('dismiss_login_whitelist_disabled_on_upgrade_notice' == $data['notice']) { + if (isset($data['turn_it_back_on']) && '1' == $data['turn_it_back_on']) { + $aio_wp_security->configs->set_value('aiowps_enable_whitelisting', '1'); + } + $aio_wp_security->configs->delete_value('aiowps_is_login_whitelist_disabled_on_upgrade'); + } elseif ('dismiss_ip_blacklist_notice' == $data['notice']) { + if (isset($data['turn_it_back_on']) && '1' == $data['turn_it_back_on']) { + $aio_wp_security->configs->set_value('aiowps_enable_blacklisting', '1'); + AIOWPSecurity_Configure_Settings::set_blacklist_ip_firewall_configs(); + AIOWPSecurity_Configure_Settings::set_user_agent_firewall_configs(); + } + $aio_wp_security->configs->delete_value('aiowps_is_ip_blacklist_settings_notice_on_upgrade'); + } elseif ('dismiss_firewall_settings_disabled_on_upgrade_notice' == $data['notice']) { + $is_reactivated = (isset($data['turn_it_back_on']) && '1' == $data['turn_it_back_on']); + if ($is_reactivated) { + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + $active_settings = $aio_wp_security->configs->get_value('aiowps_firewall_active_upgrade'); + + if (!empty($active_settings)) { + $active_settings = json_decode($active_settings); + if (!empty($active_settings)) { + foreach ($active_settings as $setting) { + $aiowps_firewall_config->set_value($setting, true); + } + } + } + } + + $aio_wp_security->configs->delete_value('aiowps_firewall_active_upgrade'); + } elseif ('php_56_eol_dismiss_forever' == $data['notice']) { + $aio_wp_security->configs->set_value('php_56_eol_dismiss_forever', $time_now + (100 * 365.25 * 86400)); + } + + + $aio_wp_security->configs->save_config(); + + return array(); + } + + + /** + * This is a helper function to save settings options using key/value pairs + * + * @param array $options - An array of options to save to the config + * @param null $callback - A callback function to call when the options are saved + * + * @return bool + */ + public function save_settings($options, $callback = null) { + global $aio_wp_security; + + $aiowps_feature_mgr = $this->get_feature_mgr_object(); + if (is_wp_error($aiowps_feature_mgr)) return false; + + + foreach ($options as $key => $value) { + $aio_wp_security->configs->set_value($key, $value); + } + //commit the config changes + $aio_wp_security->configs->save_config(); + + if (is_callable($callback)) { + call_user_func($callback, $options); + } + + $aiowps_feature_mgr->calculate_total_feature_points(); + + return true; + } + + /** + * This is a helper function to get the output feature details badge + * + * @param string $feature_id - the id of the feature we want to get the badge for + * + * @return string + */ + public function get_feature_details_badge($feature_id) { + $aiowps_feature_mgr = $this->get_feature_mgr_object(); + if (is_wp_error($aiowps_feature_mgr)) return ''; + return $aiowps_feature_mgr->output_feature_details_badge($feature_id, true); + } + + /** + * Retrieves the IDs and HTML content for features. + * + * This method processes an array of features and returns an associative array containing + * the IDs and corresponding HTML content for each feature badge. + * + * @param array $features - An array containing the features to retrieve IDs and HTML for. + * + * @return array An associative array containing the IDs and HTML content for each feature badge. + */ + public function get_features_id_and_html($features) { + $result = array(); + foreach ($features as $feature) { + $result[] = array( + 'id' => '#' . $feature . '-badge', + 'html' => $this->get_feature_details_badge($feature) + ); + } + + return $result; + } + + /** + * Prepares and returns a structured response for AJAX commands. + * + * @param bool $success Indicates whether the operation was successful (true for success, false for failure). + * @param string|bool $message The message to include in the response (optional). + * If false, no message is passed with the response. + * If empty string, it defaults to a success or error message based on the $success flag. + * @param array $args Optional. An associative array of additional response data, such as badges, info, values, or content. + * + * @return array The constructed response array containing status, message, and any additional data from $args. + */ + public function handle_response($success, $message = '', $args = array()) { + $response = array( + 'status' => $success ? 'success' : 'error', + ); + + if (false !== $message) { + $response['message'] = $this->get_message($success, $message); + } + + $allowed_keys = array('badges', 'info', 'values', 'content', 'extra_args'); + foreach ($allowed_keys as $key) { + if (!empty($args[$key])) { + $response[$key] = 'badges' === $key ? $this->get_features_id_and_html($args[$key]) : $args[$key]; + } + } + + return $response; + } + + /** + * Get the appropriate message based on success flag and provided message. + * + * @param bool $success Indicates whether the operation was successful. + * @param string $message The provided message. + * + * @return string The final message to be used in the response. + */ + private function get_message($success, $message) { + if ('' === $message) { + return $success ? __('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall') : __('The settings update was unsuccessful.', 'all-in-one-wp-security-and-firewall'); + } + return $message; + } + + /** + * Get antibot keys for the spam detection + * + * @return array + */ + public function get_antibot_keys() { + global $aio_wp_security; + + $response = array( + 'status' => 'success', + 'data' => array(), + ); + + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- PCP warning. It is the nonce. + $nonce = empty($_POST['nonce']) ? '' : sanitize_key(wp_unslash($_POST['nonce'])); + if (!wp_verify_nonce($nonce, 'wp-security-ajax-nonce')) { + $response['status'] = false; + $response['error_code'] = 'invalid_nonce'; + $response['error_message'] = 'Invalid nonce (wp-security-ajax-nonce) provided for this action.'; + } else { + $key_map_arr = AIOWPSecurity_Comment::generate_antibot_keys(true); + $response['data'] = $key_map_arr[0]; + if ('1' == $aio_wp_security->configs->get_value('aiowps_spambot_detect_usecookies')) { + AIOWPSecurity_Comment::insert_antibot_keys_in_cookie(); + } + } + + echo wp_json_encode($response); + exit; + } + + /** + * This function will send the diagnostic report email + * + * @param array $data - the request data + * + * @return array + */ + public function send_report_email($data) { + global $aio_wp_security; + + // Sanitize the email address first. + $sanitized_email = !empty($data['report_email']) ? sanitize_email($data['report_email']) : ''; + + if ('' === $sanitized_email || !is_email($sanitized_email)) { + return array( + 'status' => 'error', + 'message' => __('Invalid email address.', 'all-in-one-wp-security-and-firewall'), + ); + } + + $result = $aio_wp_security->debug_obj->send_report($sanitized_email, wp_kses_post(html_entity_decode($data['report_sections']))); + + if ($result) { + return array( + 'status' => 'success', + 'message' => __('The diagnostic report has been sent successfully.', 'all-in-one-wp-security-and-firewall'), + ); + } + + return array( + 'status' => 'error', + 'message' => __('There was an error sending the diagnostic report.', 'all-in-one-wp-security-and-firewall'), + ); + } + + /** + * Returns an array of translations used by the AIOS plugin. Primarily used for UpdraftCentral consumption. + * + * @param array $params - The parameters passed to the function. + * + * @return array - The AIOS translations array + */ + public function get_js_translation($params) { + $translations = array(); + + if (isset($params['return_formatted_response'])) { + return array( + 'error' => false, + 'data' => array( + 'translations' => $translations, + ) + ); + } + + return $translations; + } + + /** + * Get multiple widgets data. Primarily used for UpdraftCentral consumption. + * + * @param array $args - The arguments containing the widgets to retrieve data for. + * + * @return array - An array containing error status and data for each widget. + */ + public function get_widgets_data($args) { + // Widgets. + $widgets = isset($args['widgets']) ? $args['widgets'] : array(); + + // Return early if no widgets supplied. + if (!is_array($widgets) || empty($widgets)) { + return array('error' => false, 'data' => array()); + } + + // Get the data for each widget. + $data = array(); + + // Loop through the widgets and get their data. + foreach ($widgets as $widget) { + $method = 'get_' . $widget . '_data'; + + if (method_exists($this, $method)) { + $data[$widget] = $this->$method($args); + } + } + + return array('error' => false, 'data' => $data); + } + + /** + * Get the AIOS premium upsell data for UDC widget. + * + * @return array + */ + public function get_is_premium_data() { + $is_premium = AIOWPSecurity_Utility_Permissions::is_premium_installed(); + $upgrade_to_premium_data = array(); + + if (false === $is_premium) { + $upgrade_to_premium_data = array( + 'heading' => __('AIOS premium', 'all-in-one-wp-security-and-firewall'), + 'checklist' => array( + __('Advanced malware scanning', 'all-in-one-wp-security-and-firewall'), + __('Real-time response time monitoring', 'all-in-one-wp-security-and-firewall'), + __('Custom two-factor authentication', 'all-in-one-wp-security-and-firewall'), + __('404 error protection & bot blocking', 'all-in-one-wp-security-and-firewall'), + __('Country-based traffic blocking', 'all-in-one-wp-security-and-firewall'), + __('Country whitelist management', 'all-in-one-wp-security-and-firewall'), + __('Guaranteed premium support', 'all-in-one-wp-security-and-firewall'), + ), + 'cta' => array( + 'text' => __('Upgrade Now', 'all-in-one-wp-security-and-firewall'), + 'url' => 'https://teamupdraft.com/all-in-one-security/pricing/', + ), + ); + } + + return array( + 'is_premium' => $is_premium, + 'upgrade_to_premium_data' => $upgrade_to_premium_data, + ); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-comment.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-comment.php new file mode 100755 index 00000000..014654bd --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-comment.php @@ -0,0 +1,216 @@ +configs->get_value('aiowps_enable_trash_spam_comments') && absint($aio_wp_security->configs->get_value('aiowps_trash_spam_comments_after_days'))) { + $date_before = absint($aio_wp_security->configs->get_value('aiowps_trash_spam_comments_after_days')).' days ago'; + $comment_ids = get_comments(array( + 'fields' => 'ids', + 'status' => 'spam', + 'date_query' => array( + array( + 'before' => $date_before, + 'inclusive' => true, + ), + ) + )); + + if (!empty($comment_ids)) { + foreach ($comment_ids as $comment_id) { + wp_trash_comment($comment_id); + } + } + } + } + + /** + * Delete ip from aiowps_permanent_block table once the comment's spam status changed. + * + * @param object $comment_data comment object. + */ + public function comment_spam_status_change($comment_data) { + global $wpdb, $aio_wp_security; + $comment_ip = $comment_data->comment_author_IP; + // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- Direct query necessary. No caching required. + $total_spam_comment = $wpdb->get_var( + $wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->comments} WHERE comment_author_IP = %s AND comment_approved = 'spam'", $comment_ip) + ); + $min_comment_before_block = $aio_wp_security->configs->get_value('aiowps_spam_ip_min_comments_block'); + if ($total_spam_comment < $min_comment_before_block) { + $where = array('blocked_ip' => $comment_ip, 'block_reason' => 'spam'); + // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- Direct query necessary. No caching required. + $wpdb->delete(AIOWPSEC_TBL_PERM_BLOCK, $where, array('%s')); + } + } + + /** + * Checks if comment posted by spambot. + * + * @return boolean. + */ + public static function is_comment_spam_detected() { + $return = false; + if (!is_user_logged_in()) { + if (empty($_SERVER['HTTP_REFERER']) || false === stristr(sanitize_url(wp_unslash($_SERVER['HTTP_REFERER'])), wp_parse_url(home_url(), PHP_URL_HOST)) || empty($_SERVER['HTTP_USER_AGENT'])) { + $return = true; + } elseif (self::is_bot_detected()) { + $return = true; + } + } + return apply_filters('aiowps_is_comment_spam_detected', $return); + } + + /** + * Check if bot posted comment form based on form posted fields and cookie values + * + * @return boolean + */ + public static function is_bot_detected() { + global $aio_wp_security; + $return = false; + $key_map_arr = self::generate_antibot_keys(); + foreach ($key_map_arr[0] as $key) { + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- PCP warning. Nonce checked in earlier function. + if (empty($_POST[$key[0]]) || sanitize_text_field(wp_unslash($_POST[$key[0]])) != $key[1]) { + $return = true; + break; + } + } + if (!$return && '1' == $aio_wp_security->configs->get_value('aiowps_spambot_detect_usecookies')) { + foreach ($key_map_arr[1] as $key) { + if (AIOWPSecurity_Utility::get_cookie_value($key[0]) != $key[1]) { + $return = true; + break; + } + } + } + return apply_filters('aios_is_bot_detected', $return); + } + + /** + * Set cookies in browser for antibot check + * + * @return void + */ + public static function insert_antibot_keys_in_cookie() { + $key_map_arr = self::generate_antibot_keys(); + $expiry_seconds = AIOS_UPDATE_ANTIBOT_KEYS_AFTER_DAYS * 86400; + if (!empty($key_map_arr[1])) { + foreach ($key_map_arr[1] as $key) { + AIOWPSecurity_Utility::set_cookie_value($key[0], $key[1], $expiry_seconds); + } + } + } + + /** + * Comment Form to post back hidden fields for antibot check + * + * @return string + */ + public static function insert_antibot_keys_in_comment_form() { + $html_antibot_hidden_fields = '

%1$s

'; + $antibot_hidden_fields = ''; + $key_map_arr = self::generate_antibot_keys(); + foreach ($key_map_arr[0] as $key) { + $antibot_hidden_fields .=''; + } + if (isset($key_map_arr[2])) { + $antibot_hidden_fields .=''; + } + wp_register_script('aios-front-js', AIO_WP_SECURITY_URL. '/js/wp-security-front-script.js', array('jquery'), AIO_WP_SECURITY_VERSION, true); + wp_enqueue_script('aios-front-js'); + wp_localize_script('aios-front-js', 'AIOS_FRONT', array( + 'ajaxurl' => admin_url('admin-ajax.php'), // URL to wp-admin/admin-ajax.php to process the request + 'ajax_nonce' => wp_create_nonce('wp-security-ajax-nonce'), + )); + $html_antibot_hidden_fields = sprintf($html_antibot_hidden_fields, $antibot_hidden_fields); + return $html_antibot_hidden_fields; + } + + /** + * Get antibot key-value pairs to check on post back + * + * @param boolean $update generate and save in database + * + * @return array + */ + public static function generate_antibot_keys($update = false) { + $key_map_arr = get_site_option('aios_antibot_key_map_info'); + if (!$update && is_array($key_map_arr)) { + return $key_map_arr; + } + if ($update && is_array($key_map_arr) && isset($key_map_arr[2]) && $key_map_arr[2] > time()) { + return $key_map_arr; + } + $key_map_arr = array(); + + // values for to check post back key + $max = wp_rand(2, 4); + for ($i = 1; $i <= $max; $i++) { + $string1 = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(8); + $string2 = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(12); + $key_map_arr[0][] = array($string1, $string2); + } + + // values for to check for cookie back key + $max = wp_rand(2, 4); + for ($i = 1; $i <= $max; $i++) { + $string1 = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(8); + $string2 = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(12); + $key_map_arr[1][] = array($string1, $string2); + } + // expiration time of keys + $current_time = time(); + $key_map_arr[2] = (($current_time - ($current_time % 86400)) + AIOS_UPDATE_ANTIBOT_KEYS_AFTER_DAYS * 86400); + update_site_option('aios_antibot_key_map_info', $key_map_arr); + return $key_map_arr; + } + + /** + * Update antibot key-value pairs to rotate values so it is not valid forever + * + * @return void + */ + public function update_antibot_keys() { + if ((intval(gmdate('z')) % AIOS_UPDATE_ANTIBOT_KEYS_AFTER_DAYS) == 0) self::generate_antibot_keys(true); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-config.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-config.php new file mode 100755 index 00000000..cc48759d --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-config.php @@ -0,0 +1,109 @@ +configs = get_option('aio_wp_security_configs'); + } + + public function get_value($key) { + return isset($this->configs[$key]) ? $this->configs[$key] : ''; + } + + /** + * Gets for main site config value for a given $key. + * + * @param string $key + * + * @return string|array + */ + public function get_site_value($key) { + if (is_multisite() && !is_main_site()) { + $mainsite_aio_config = get_blog_option(get_main_site_id(), 'aio_wp_security_configs'); + return isset($mainsite_aio_config[$key]) ? $mainsite_aio_config[$key] : ''; + } else { + return $this->get_value($key); + } + } + + /** + * Sets a given config $value for a given $key. + * + * @param string $key + * @param mixed $value + * @param boolean $save_config - Whether or not to also save the $configs array to the database. + * + * @return boolean + */ + public function set_value($key, $value, $save_config = false) { + $this->configs[$key] = $value; + + if ($save_config) { + return $this->save_config(); + } else { + return true; + } + } + + public function add_value($key, $value) { + if (!is_array($this->configs)) { + $this->configs = array(); + } + + if (array_key_exists($key, $this->configs)) { + //Don't update the value for this key + } else {//It is safe to update the value for this key + $this->configs[$key] = $value; + } + } + + /** + * Save configuration that are set. + * + * @return boolean True on save config, Otherwise false. + */ + public function save_config() { + return update_option('aio_wp_security_configs', $this->configs); + } + + /** + * Remove key element from config. + * + * @param String $key config key + * + * @return boolean True if removed, otherwise false. + */ + public function delete_value($key) { + if (!is_array($this->configs)) { + $this->configs = array(); + } + + if (array_key_exists($key, $this->configs)) { + unset($this->configs[$key]); + if (!isset($this->configs[$key])) { + return true; + } + } + + return false; + } + + public static function get_instance() { + if (empty(self::$_this)) { + self::$_this = new AIOWPSecurity_Config(); + self::$_this->load_config(); + return self::$_this; + } + return self::$_this; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-configure-settings.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-configure-settings.php new file mode 100755 index 00000000..e8280513 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-configure-settings.php @@ -0,0 +1,739 @@ +configs->set_value('aiowps_enable_debug', '');//Checkbox + + //PHP backtrace + $aio_wp_security->configs->set_value('aiowps_enable_php_backtrace_in_email', '');//Checkbox + + //WP Generator Meta Tag feature + $aio_wp_security->configs->set_value('aiowps_remove_wp_generator_meta_info', '');//Checkbox + + //Prevent Image Hotlinks + $aio_wp_security->configs->set_value('aiowps_prevent_hotlinking', '');//Checkbox + //General Settings Page + + //User password feature + + //Lockout feature + $aio_wp_security->configs->set_value('aiowps_enable_login_lockdown', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_allow_unlock_requests', '1'); // Checkbox + $aio_wp_security->configs->set_value('aiowps_max_login_attempts', '3'); + $aio_wp_security->configs->set_value('aiowps_retry_time_period', '5'); + $aio_wp_security->configs->set_value('aiowps_lockout_time_length', '5'); + $aio_wp_security->configs->set_value('aiowps_max_lockout_time_length', '60'); + $aio_wp_security->configs->set_value('aiowps_set_generic_login_msg', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enable_email_notify', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_email_address', $blog_email_address);//text field + $aio_wp_security->configs->set_value('aiowps_enable_forced_logout', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_logout_time_period', '60'); + $aio_wp_security->configs->set_value('aiowps_enable_invalid_username_lockdown', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_instantly_lockout_specific_usernames', array()); // Textarea (list of strings) + $aio_wp_security->configs->set_value('aiowps_unlock_request_secret_key', AIOWPSecurity_Utility::generate_alpha_numeric_random_string(20));//Hidden secret value which will be used to do some unlock request processing. This will be assigned a random string generated when lockdown settings saved + $aio_wp_security->configs->set_value('aiowps_lockdown_enable_whitelisting', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_lockdown_allowed_ip_addresses', ''); + + // HTTP authentication + $aio_wp_security->configs->set_value('aiowps_http_authentication_admin', ''); // Checkbox + $aio_wp_security->configs->set_value('aiowps_http_authentication_frontend', ''); // Checkbox + $aio_wp_security->configs->set_value('aiowps_http_authentication_username', 'root'); + $aio_wp_security->configs->set_value('aiowps_http_authentication_password', 'password'); + $aio_wp_security->configs->set_value('aiowps_http_authentication_failure_message', '

Unauthorized

'); + + // CAPTCHA feature + $aio_wp_security->configs->set_value('aiowps_default_captcha', ''); + $aio_wp_security->configs->set_value('aiowps_enable_login_captcha', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enable_custom_login_captcha', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enable_password_protected_captcha', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enable_woo_login_captcha', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enable_woo_lostpassword_captcha', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enable_woo_register_captcha', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enable_woo_checkout_captcha', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enable_lost_password_captcha', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enable_contact_form_7_captcha', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_captcha_secret_key', AIOWPSecurity_Utility::generate_alpha_numeric_random_string(20)); // Hidden secret value which will be used to do some CAPTCHA processing. This will be assigned a random string generated when CAPTCHA settings saved + + //Login Whitelist feature + $aio_wp_security->configs->set_value('aiowps_enable_whitelisting', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_allowed_ip_addresses', ''); + + //User registration + $aio_wp_security->configs->set_value('aiowps_enable_manual_registration_approval', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enable_registration_page_captcha', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enable_registration_honeypot', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enforce_strong_password', '');//Checkbox + + //DB Security feature + //$aio_wp_security->configs->set_value('aiowps_new_manual_db_pefix', ''); //text field + $aio_wp_security->configs->set_value('aiowps_enable_random_prefix', '');//Checkbox + + //Filesystem Security feature + AIOWPSecurity_Utility::enable_file_edits(); + $aio_wp_security->configs->set_value('aiowps_disable_file_editing', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_prevent_default_wp_file_access', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_auto_delete_default_wp_files', ''); // Checkbox + $aio_wp_security->configs->set_value('aiowps_system_log_file', 'error_log'); + + //Blacklist feature + $aio_wp_security->configs->set_value('aiowps_enable_blacklisting', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_banned_ip_addresses', ''); + $aio_wp_security->configs->set_value('aiowps_banned_user_agents', ''); + + //Firewall features + $aio_wp_security->configs->set_value('aiowps_enable_basic_firewall', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_max_file_upload_size', AIOS_FIREWALL_MAX_FILE_UPLOAD_LIMIT_MB); //Default + $aio_wp_security->configs->set_value('aiowps_disable_xmlrpc_pingback_methods', '');//Checkbox - Disables only pingback methods in XMLRPC functionality + $aio_wp_security->configs->set_value('aiowps_disable_rss_and_atom_feeds', ''); // Checkbox + $aio_wp_security->configs->set_value('aiowps_block_debug_log_file_access', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_disable_index_views', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_disable_trace_and_track', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enable_5g_firewall', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enable_6g_firewall', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enable_custom_rules', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_place_custom_rules_at_top', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_custom_rules', ''); + + // Upgrade unsafe HTTP calls + $aio_wp_security->configs->set_value('aiowps_upgrade_unsafe_http_calls', ''); // Checkbox + $aio_wp_security->configs->set_value('aiowps_upgrade_unsafe_http_calls_url_exceptions', ''); + + //404 detection + $aio_wp_security->configs->set_value('aiowps_enable_404_logging', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enable_404_IP_lockout', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_404_lockout_time_length', '60'); + $aio_wp_security->configs->set_value('aiowps_404_lock_redirect_url', 'http://127.0.0.1'); + + //Brute Force features + $aio_wp_security->configs->set_value('aiowps_enable_rename_login_page', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enable_login_honeypot', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_disable_application_password', '');//Checkbox + + $aio_wp_security->configs->set_value('aiowps_enable_brute_force_attack_prevention', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_brute_force_secret_word', ''); + $aio_wp_security->configs->set_value('aiowps_cookie_brute_test', ''); + $aio_wp_security->configs->set_value('aiowps_cookie_based_brute_force_redirect_url', 'http://127.0.0.1'); + $aio_wp_security->configs->set_value('aiowps_brute_force_attack_prevention_pw_protected_exception', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_brute_force_attack_prevention_ajax_exception', '');//Checkbox + + //Maintenance menu - Visitor lockout feature + $aio_wp_security->configs->set_value('aiowps_site_lockout', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_site_lockout_msg', '');//Text area/msg box + + // Spam prevention menu + $aio_wp_security->configs->set_value('aiowps_enable_comment_captcha', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enable_autoblock_spam_ip', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_spam_ip_min_comments_block', ''); + $aio_wp_security->configs->set_value('aiowps_enable_bp_register_captcha', ''); + $aio_wp_security->configs->set_value('aiowps_enable_bbp_new_topic_captcha', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_enable_spambot_detecting', ''); + $aio_wp_security->configs->set_value('aiowps_spambot_detect_usecookies', ''); + $aio_wp_security->configs->set_value('aiowps_spam_comments_should', ''); + + $aio_wp_security->configs->set_value('aiowps_enable_trash_spam_comments', ''); + $aio_wp_security->configs->set_value('aiowps_trash_spam_comments_after_days', '14'); + + //Filescan features + //File change detection feature + $aio_wp_security->configs->set_value('aiowps_enable_automated_fcd_scan', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_fcd_scan_frequency', '4'); + $aio_wp_security->configs->set_value('aiowps_fcd_scan_interval', '2'); //Dropdown box where (0,1,2) => (hours,days,weeks) + $aio_wp_security->configs->set_value('aiowps_fcd_exclude_filetypes', ''); + $aio_wp_security->configs->set_value('aiowps_fcd_exclude_files', ''); + $aio_wp_security->configs->set_value('aiowps_send_fcd_scan_email', '');//Checkbox + $aio_wp_security->configs->set_value('aiowps_fcd_scan_email_address', $blog_email_address); + $aio_wp_security->configs->set_value('aiowps_fcds_change_detected', false); //used to display a global alert on site when file change detected + + //Misc Options + //Copy protection feature + $aio_wp_security->configs->set_value('aiowps_copy_protection', '');//Checkbox + //Prevent others from displaying your site in iframe + $aio_wp_security->configs->set_value('aiowps_prevent_site_display_inside_frame', '');//Checkbox + //Prevent users enumeration + $aio_wp_security->configs->set_value('aiowps_prevent_users_enumeration', '');//Checkbox + + //REST API Security + $aio_wp_security->configs->set_value('aiowps_disallow_unauthorized_rest_requests', '');//Checkbox + $aio_wp_security->configs->set_value('aios_roles_disallowed_rest_requests', array()); + $aio_wp_security->configs->set_value('aios_whitelisted_rest_routes', array()); + + // IP retrieval setting + $aio_wp_security->configs->set_value('aiowps_ip_retrieve_method', '0'); // Default is $_SERVER['REMOTE_ADDR'] + + // Cloudflare Turnstile + $aio_wp_security->configs->set_value('aiowps_turnstile_site_key', ''); + $aio_wp_security->configs->set_value('aiowps_turnstile_secret_key', ''); + + // Google reCAPTCHA + $aio_wp_security->configs->set_value('aiowps_recaptcha_site_key', ''); + $aio_wp_security->configs->set_value('aiowps_recaptcha_secret_key', ''); + $aio_wp_security->configs->set_value('aiowps_default_recaptcha', ''); // Not used since 5.1.2 + + // Deactivation Handler + $aio_wp_security->configs->set_value('aiowps_on_uninstall_delete_db_tables', '1'); //Checkbox + $aio_wp_security->configs->set_value('aiowps_on_uninstall_delete_configs', '1'); //Checkbox + + // Reset the PHP 5.6 end of support notice + $aio_wp_security->configs->delete_value('php_56_eol_dismiss_forever'); + + //TODO - keep adding default options for any fields that require it + + if (is_main_site()) { + $aiowps_firewall_config->set_value('aiowps_enable_pingback_firewall', false);//Checkbox - blocks all access to XMLRPC + $aiowps_firewall_config->set_value('aiowps_forbid_proxy_comments', false);//Checkbox + $aiowps_firewall_config->set_value('aiowps_deny_bad_query_strings', false);//Checkbox + $aiowps_firewall_config->set_value('aiowps_advanced_char_string_filter', false);//Checkbox + $aiowps_firewall_config->set_value('aiowps_ban_post_blank_headers', false); // Checkbox + $aiowps_firewall_config->set_value('aiowps_block_fake_googlebots', false); // Checkbox + $aiowps_firewall_config->set_value('aiowps_googlebot_ip_ranges', array()); + + self::turn_off_all_6g_firewall_configs(); + self::set_cookie_based_bruteforce_firewall_configs(); + self::set_user_agent_firewall_configs(); + self::set_ip_retrieve_method_configs(); + self::set_blacklist_ip_firewall_configs(); + } + + // Save it + return $aio_wp_security->configs->save_config(); + } + + /** + * Add config settings. + * + * @return Void + */ + public static function add_option_values() { + + global $aio_wp_security; + + $blog_email_address = get_bloginfo('admin_email'); //Get the blog admin email address - we will use as the default value + + $aio_wp_security->configs->load_config(); + + //Debug + $aio_wp_security->configs->add_value('aiowps_enable_debug', '');//Checkbox + + //PHP backtrace + $aio_wp_security->configs->add_value('aiowps_enable_php_backtrace_in_email', '');//Checkbox + + //WP Generator Meta Tag feature + $aio_wp_security->configs->add_value('aiowps_remove_wp_generator_meta_info', '');//Checkbox + + //Prevent Image Hotlinks + $aio_wp_security->configs->add_value('aiowps_prevent_hotlinking', '');//Checkbox + + //General Settings Page + + //User password feature + + //Lockout feature + $aio_wp_security->configs->add_value('aiowps_enable_login_lockdown', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_allow_unlock_requests', '1'); // Checkbox + $aio_wp_security->configs->add_value('aiowps_max_login_attempts', '3'); + $aio_wp_security->configs->add_value('aiowps_retry_time_period', '5'); + $aio_wp_security->configs->add_value('aiowps_lockout_time_length', '5'); + $aio_wp_security->configs->add_value('aiowps_max_lockout_time_length', '60'); + $aio_wp_security->configs->add_value('aiowps_set_generic_login_msg', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_enable_email_notify', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_email_address', $blog_email_address);//text field + $aio_wp_security->configs->add_value('aiowps_enable_forced_logout', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_logout_time_period', '60'); + $aio_wp_security->configs->add_value('aiowps_enable_invalid_username_lockdown', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_instantly_lockout_specific_usernames', array()); // Textarea (list of strings) + $aio_wp_security->configs->add_value('aiowps_unlock_request_secret_key', AIOWPSecurity_Utility::generate_alpha_numeric_random_string(20));//Hidden secret value which will be used to do some unlock request processing. This will be assigned a random string generated when lockdown settings saved + $aio_wp_security->configs->add_value('aiowps_lockdown_enable_whitelisting', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_lockdown_allowed_ip_addresses', ''); + + // HTTP authentication + $aio_wp_security->configs->add_value('aiowps_http_authentication_admin', ''); // Checkbox + $aio_wp_security->configs->add_value('aiowps_http_authentication_frontend', ''); // Checkbox + $aio_wp_security->configs->add_value('aiowps_http_authentication_username', 'root'); + $aio_wp_security->configs->add_value('aiowps_http_authentication_password', 'password'); + $aio_wp_security->configs->add_value('aiowps_http_authentication_failure_message', '

Unauthorized

'); + + //Login Whitelist feature + $aio_wp_security->configs->add_value('aiowps_enable_whitelisting', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_allowed_ip_addresses', ''); + + // CAPTCHA feature + $aio_wp_security->configs->add_value('aiowps_default_captcha', ''); + $aio_wp_security->configs->add_value('aiowps_enable_login_captcha', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_enable_custom_login_captcha', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_enable_password_protected_captcha', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_enable_woo_login_captcha', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_enable_woo_register_captcha', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_enable_woo_checkout_captcha', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_enable_woo_lostpassword_captcha', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_enable_contact_form_7_captcha', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_captcha_secret_key', AIOWPSecurity_Utility::generate_alpha_numeric_random_string(20)); // Hidden secret value which will be used to do some CAPTCHA processing. This will be assigned a random string generated when CAPTCHA settings saved + + //User registration + $aio_wp_security->configs->add_value('aiowps_enable_manual_registration_approval', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_enable_registration_page_captcha', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_enable_registration_honeypot', ''); // Checkbox + $aio_wp_security->configs->add_value('aiowps_enforce_strong_password', ''); // Checkbox + + //DB Security feature + //$aio_wp_security->configs->add_value('aiowps_new_manual_db_pefix', ''); //text field + $aio_wp_security->configs->add_value('aiowps_enable_random_prefix', '');//Checkbox + + //Filesystem Security feature + $aio_wp_security->configs->add_value('aiowps_disable_file_editing', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_prevent_default_wp_file_access', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_auto_delete_default_wp_files', ''); // Checkbox + $aio_wp_security->configs->add_value('aiowps_system_log_file', 'error_log'); + + //Blacklist feature + $aio_wp_security->configs->add_value('aiowps_enable_blacklisting', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_banned_ip_addresses', ''); + + //Firewall features + $aio_wp_security->configs->add_value('aiowps_enable_basic_firewall', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_max_file_upload_size', AIOS_FIREWALL_MAX_FILE_UPLOAD_LIMIT_MB); + $aio_wp_security->configs->add_value('aiowps_disable_xmlrpc_pingback_methods', '');//Checkbox - Disables only pingback methods in XMLRPC functionality + $aio_wp_security->configs->add_value('aiowps_disable_rss_and_atom_feeds', ''); // Checkbox + $aio_wp_security->configs->add_value('aiowps_block_debug_log_file_access', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_disable_index_views', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_disable_trace_and_track', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_enable_5g_firewall', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_enable_6g_firewall', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_enable_custom_rules', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_place_custom_rules_at_top', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_custom_rules', ''); + + // Upgrade unsafe HTTP calls + $aio_wp_security->configs->add_value('aiowps_upgrade_unsafe_http_calls', ''); // Checkbox + $aio_wp_security->configs->add_value('aiowps_upgrade_unsafe_http_calls_url_exceptions', ''); + + //404 detection + $aio_wp_security->configs->add_value('aiowps_enable_404_logging', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_enable_404_IP_lockout', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_404_lockout_time_length', '60'); + $aio_wp_security->configs->add_value('aiowps_404_lock_redirect_url', 'http://127.0.0.1'); + + //Brute Force features + $aio_wp_security->configs->add_value('aiowps_enable_rename_login_page', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_enable_login_honeypot', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_disable_application_password', ''); // Checkbox + + $aio_wp_security->configs->add_value('aiowps_enable_brute_force_attack_prevention', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_brute_force_secret_word', ''); + $aio_wp_security->configs->add_value('aiowps_cookie_brute_test', ''); + $aio_wp_security->configs->add_value('aiowps_cookie_based_brute_force_redirect_url', 'http://127.0.0.1'); + $aio_wp_security->configs->add_value('aiowps_brute_force_attack_prevention_pw_protected_exception', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_brute_force_attack_prevention_ajax_exception', '');//Checkbox + + //Maintenance menu - Visitor lockout feature + $aio_wp_security->configs->add_value('aiowps_site_lockout', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_site_lockout_msg', '');//Text area/msg box + + // Spam prevention menu + $aio_wp_security->configs->add_value('aiowps_enable_spambot_blocking', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_enable_comment_captcha', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_spam_ip_min_comments_block', ''); + $aio_wp_security->configs->add_value('aiowps_enable_bp_register_captcha', ''); + $aio_wp_security->configs->add_value('aiowps_enable_bbp_new_topic_captcha', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_enable_spambot_detecting', ''); + $aio_wp_security->configs->add_value('aiowps_spambot_detect_usecookies', ''); + $aio_wp_security->configs->add_value('aiowps_spam_comments_should', ''); + $aio_wp_security->configs->add_value('aiowps_enable_trash_spam_comments', ''); + $aio_wp_security->configs->add_value('aiowps_trash_spam_comments_after_days', '14'); + + //Filescan features + //File change detection feature + $aio_wp_security->configs->add_value('aiowps_enable_automated_fcd_scan', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_fcd_scan_frequency', '4'); + $aio_wp_security->configs->add_value('aiowps_fcd_scan_interval', '2'); //Dropdown box where (0,1,2) => (hours,days,weeks) + $aio_wp_security->configs->add_value('aiowps_fcd_exclude_filetypes', ''); + $aio_wp_security->configs->add_value('aiowps_fcd_exclude_files', ''); + $aio_wp_security->configs->add_value('aiowps_send_fcd_scan_email', '');//Checkbox + $aio_wp_security->configs->add_value('aiowps_fcd_scan_email_address', $blog_email_address); + $aio_wp_security->configs->add_value('aiowps_fcds_change_detected', false); //used to display a global alert on site when file change detected + + //Misc Options + //Copy protection feature + $aio_wp_security->configs->add_value('aiowps_copy_protection', '');//Checkbox + //Prevent others from displaying your site in iframe + $aio_wp_security->configs->add_value('aiowps_prevent_site_display_inside_frame', '');//Checkbox + //Prevent users enumeration + $aio_wp_security->configs->add_value('aiowps_prevent_users_enumeration', '');//Checkbox + + //REST API Security + $aio_wp_security->configs->add_value('aiowps_disallow_unauthorized_rest_requests', '');//Checkbox + $aio_wp_security->configs->add_value('aios_roles_disallowed_rest_requests', array()); + $aio_wp_security->configs->add_value('aios_whitelisted_rest_routes', array()); + + // IP retrieval setting + // Commented the below code line because the IP retrieve method will be configured when the AIOS plugin is activated for the first time. + // $aio_wp_security->configs->add_value('aiowps_ip_retrieve_method', '0'); // Default is $_SERVER['REMOTE_ADDR'] + + // Cloudflare Turnstile + $aio_wp_security->configs->add_value('aiowps_turnstile_site_key', ''); + $aio_wp_security->configs->add_value('aiowps_turnstile_secret_key', ''); + + // Google reCAPTCHA + $aio_wp_security->configs->add_value('aiowps_recaptcha_site_key', ''); + $aio_wp_security->configs->add_value('aiowps_recaptcha_secret_key', ''); + $aio_wp_security->configs->add_value('aiowps_default_recaptcha', ''); // Not used since 5.1.2 + + // Deactivation Handler + $aio_wp_security->configs->add_value('aiowps_on_uninstall_delete_db_tables', '1'); //Checkbox + $aio_wp_security->configs->add_value('aiowps_on_uninstall_delete_configs', '1'); //Checkbox + + $aio_wp_security->configs->add_value('installed-at', current_time('timestamp', true)); + + //TODO - keep adding default options for any fields that require it + + //Save it + $aio_wp_security->configs->save_config(); + + // For Cookie based brute force prevention backward compatibility + if (!headers_sent() && '1' == $aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention')) { + $brute_force_secret_word = $aio_wp_security->configs->get_value('aiowps_brute_force_secret_word'); + if (empty($brute_force_secret_word)) { + $brute_force_secret_word = AIOS_DEFAULT_BRUTE_FORCE_FEATURE_SECRET_WORD; + } + AIOWPSecurity_Utility::set_cookie_value(AIOWPSecurity_Utility::get_brute_force_secret_cookie_name(), AIOS_Helper::get_hash($brute_force_secret_word)); + } + + // Login whitelisting started to work on non-apache server from db_version 1.9.5 + if (is_main_site() && version_compare(get_option('aiowpsec_db_version'), '1.9.6', '<') && '1' == $aio_wp_security->configs->get_value('aiowps_enable_whitelisting') && !empty($aio_wp_security->configs->get_value('aiowps_allowed_ip_addresses'))) { + $aio_wp_security->configs->set_value('aiowps_enable_whitelisting', '0'); + $aio_wp_security->configs->set_value('aiowps_is_login_whitelist_disabled_on_upgrade', '1'); + $aio_wp_security->configs->save_config(); + } + + if (is_main_site() && version_compare(get_option('aiowpsec_db_version'), '2.0.0', '<') && '1' == $aio_wp_security->configs->get_value('aiowps_enable_blacklisting') && !empty($aio_wp_security->configs->get_value('aiowps_banned_ip_addresses')) && (false !== strpos($aio_wp_security->configs->get_value('aiowps_banned_ip_addresses'), '*') || false !== strpos($aio_wp_security->configs->get_value('aiowps_banned_ip_addresses'), '/'))) { + $aio_wp_security->configs->set_value('aiowps_enable_blacklisting', '0'); + $aio_wp_security->configs->set_value('aiowps_is_ip_blacklist_settings_notice_on_upgrade', '1'); + $aio_wp_security->configs->save_config(); + self::set_user_agent_firewall_configs(); + self::send_blacklist_manager_disabled_email(); + } + + if (is_main_site() && version_compare(get_option('aiowpsec_db_version'), '2.0.0', '<') && '1' == $aio_wp_security->configs->get_value('aiowps_enable_spambot_blocking')) { + $aio_wp_security->configs->set_value('aiowps_enable_spambot_detecting', '1'); + $aio_wp_security->configs->set_value('aiowps_spambot_detect_usecookies', ''); + $aio_wp_security->configs->set_value('aiowps_spam_comments_should', '0'); + $aio_wp_security->configs->save_config(); + } + + + if (is_main_site() && version_compare(get_option('aiowpsec_db_version'), '2.0.3', '<')) { + $aio_wp_security->configs->set_value('aiowps_enable_pingback_firewall', '0');//Checkbox - blocks all access to XMLRPC + $aio_wp_security->configs->set_value('aiowps_forbid_proxy_comments', '0');//Checkbox + $aio_wp_security->configs->set_value('aiowps_deny_bad_query_strings', '0');//Checkbox + $aio_wp_security->configs->set_value('aiowps_advanced_char_string_filter', '0');//Checkbox + $aio_wp_security->configs->save_config(); + } + + if (is_main_site()) { + AIOWPSecurity_Utility_Htaccess::write_to_htaccess(false); + } + + // Add expiration for antibot keys for previous versions + if (version_compare(get_option('aiowpsec_db_version'), '2.1.1', '<')) { + AIOWPSecurity_Comment::generate_antibot_keys(true); + } + + // Add ContactForm7 related authentication scheme for salt postfix + if (version_compare(get_option('aiowpsec_db_version'), '2.1.4', '<') && '1' == $aio_wp_security->configs->get_value('aiowps_enable_salt_postfix')) { + $salt_postfixes = $aio_wp_security->configs->get_value('aiowps_salt_postfixes'); + $salt_postfixes['wpcf7_submission'] = wp_generate_password(64, true, true); + $aio_wp_security->configs->set_value('aiowps_salt_postfixes', $salt_postfixes, true); + } + } + + /** + * Method to update the plugin db version. + * + * @return void + */ + public static function update_aiowpsec_db_version() { + update_option('aiowpsec_db_version', AIO_WP_SECURITY_DB_VERSION); + } + + /** + * Upgrades from the old config to the firewall's config + * + * @return void + */ + public static function upgrade_basic_firewall_rules_configs() { + global $aio_wp_security; + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + + $settings = array( + 'aiowps_enable_pingback_firewall', + 'aiowps_forbid_proxy_comments', + 'aiowps_deny_bad_query_strings', + 'aiowps_advanced_char_string_filter', + ); + + // The settings that have been activated by the user + $active = array(); + + foreach ($settings as $setting) { + if (('1' === $aio_wp_security->configs->get_value($setting))) { + $active[] = $setting; + $aiowps_firewall_config->set_value($setting, false); + $aio_wp_security->configs->delete_value($setting); + $aio_wp_security->configs->save_config(); + } + + } + + if (!empty($active)) { + $aio_wp_security->configs->set_value('aiowps_firewall_active_upgrade', wp_json_encode($active)); + $aio_wp_security->configs->save_config(); + self::send_basic_firewall_upgrade_email(); + } + } + + /** + * Send an email notifying that the upgraded settings have been disabled + * + * @return void + */ + private static function send_basic_firewall_upgrade_email() { + global $aio_wp_security; + $dashboard_link = 'admin.php?page=aiowpsec'; + $dashboard_link = is_multisite() ? network_admin_url($dashboard_link) : admin_url($dashboard_link); + $subject = __('Basic firewall settings disabled', 'all-in-one-wp-security-and-firewall'); + /* translators: %s: Dashboard link. */ + $email_msg = __('Our basic firewall rules have been upgraded and to prevent any unexpected site issues we have disabled the features.', 'all-in-one-wp-security-and-firewall') . "\n\n" . __('You can enable the features again by logging into your WordPress dashboard.', 'all-in-one-wp-security-and-firewall') . "\n\n" .sprintf(__('Go to dashboard: %s', 'all-in-one-wp-security-and-firewall'), $dashboard_link) . "\n\n" . __('Once logged in you will see a notification where you can decide on which course of action you wish to take.', 'all-in-one-wp-security-and-firewall') . "\n"; + $email = get_bloginfo('admin_email'); + if (false === wp_mail($email, $subject, $email_msg)) { + $aio_wp_security->debug_logger->log_debug("Basic firewall rules notification email failed to send to " . $email, 4); + } + } + + /** + * This function send blacklist ip manager disabled email. + * + * @return void + */ + public static function send_blacklist_manager_disabled_email() { + global $aio_wp_security; + $dashboard_link = 'admin.php?page=aiowpsec'; + $dashboard_link = is_multisite() ? network_admin_url($dashboard_link) : admin_url($dashboard_link); + $subject = '['. get_option('siteurl'). '] '. __('Blacklist manager disabled notification', 'all-in-one-wp-security-and-firewall'); + /* translators: %s: Dashboard link */ + $email_msg = __('The blacklist manager feature has been updated and to prevent any unexpected site lockouts we have disabled the feature.', 'all-in-one-wp-security-and-firewall') . "\n\n" . __('You can enable the feature again by logging into your WordPress dashboard.', 'all-in-one-wp-security-and-firewall') . "\n\n" .sprintf(__('Go to dashboard: %s', 'all-in-one-wp-security-and-firewall'), $dashboard_link) . "\n\n" . __('Once logged in before turning the blacklist manger on please double check your settings to ensure you have not entered your own details.', 'all-in-one-wp-security-and-firewall') . "\n"; + $email = get_bloginfo('admin_email'); + $mail_sent = wp_mail($email, $subject, $email_msg); + if (false === $mail_sent) { + $aio_wp_security->debug_logger->log_debug("Blacklist IP manager disabled notification email failed to send to " . $email, 4); + } + } + + /** + * Firewall configs set based on version. + * + * @return void + */ + public static function set_firewall_configs() { + if (is_main_site()) { + $firewall_version = get_option('aiowpsec_firewall_version'); + if (version_compare($firewall_version, '1.0.1', '<')) { + self::set_cookie_based_bruteforce_firewall_configs(); + } + if (version_compare($firewall_version, '1.0.3', '<')) { + self::set_ip_retrieve_method_configs(); + } + if (version_compare($firewall_version, '1.0.4', '<')) { + self::set_blacklist_ip_firewall_configs(); + } + if (version_compare($firewall_version, '1.0.5', '<')) { + self::upgrade_basic_firewall_rules_configs(); + } + if (version_compare($firewall_version, '1.0.6', '<')) { //1.0.2 set but here making sure the blank user agent is not saved in settings.php which may show a 403 error due to not empty user agent check removed from the rule + self::set_user_agent_firewall_configs(); + } + if (version_compare($firewall_version, '1.0.8', '<')) { + self::port_block_fake_googlebots_config(); + } + } + update_option('aiowpsec_firewall_version', AIO_WP_SECURITY_FIREWALL_VERSION); + } + + /** + * Blacklist IP firewall configs set. + * + * @return void. + */ + public static function set_blacklist_ip_firewall_configs() { + global $aio_wp_security; + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + $aiowps_firewall_config->set_value('aiowps_ip_retrieve_method', $aio_wp_security->configs->get_value('aiowps_ip_retrieve_method')); + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_blacklisting') && !empty($aio_wp_security->configs->get_value('aiowps_banned_ip_addresses'))) { + $aiowps_firewall_config->set_value('aiowps_blacklist_ips', explode("\n", preg_replace("/\r/", "", trim($aio_wp_security->configs->get_value('aiowps_banned_ip_addresses'))))); + } else { + $aiowps_firewall_config->set_value('aiowps_blacklist_ips', array()); + } + } + + /** + * Cookie based bruteforce firewall configs set. + * + * @return void. + */ + public static function set_cookie_based_bruteforce_firewall_configs() { + global $aio_wp_security; + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + + $aiowps_firewall_config->set_value('aios_enable_rename_login_page', $aio_wp_security->configs->get_value('aiowps_enable_rename_login_page')); + + $aiowps_firewall_config->set_value('aios_login_page_slug', $aio_wp_security->configs->get_value('aiowps_login_page_slug')); + + $aios_enable_brute_force_attack_prevention = $aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention'); + $aiowps_firewall_config->set_value('aios_enable_brute_force_attack_prevention', $aios_enable_brute_force_attack_prevention); + + $aiowps_firewall_config->set_value('aios_brute_force_secret_word', $aio_wp_security->configs->get_value('aiowps_brute_force_secret_word')); + + $aiowps_firewall_config->set_value('aios_cookie_based_brute_force_redirect_url', $aio_wp_security->configs->get_value('aiowps_cookie_based_brute_force_redirect_url')); + + $aiowps_firewall_config->set_value('aios_brute_force_attack_prevention_pw_protected_exception', $aio_wp_security->configs->get_value('aiowps_brute_force_attack_prevention_pw_protected_exception')); + + $aiowps_firewall_config->set_value('aios_brute_force_attack_prevention_ajax_exception', $aio_wp_security->configs->get_value('aiowps_brute_force_attack_prevention_ajax_exception')); + + $aiowps_firewall_config->set_value('aios_brute_force_secret_cookie_name', AIOWPSecurity_Utility::get_brute_force_secret_cookie_name()); + } + + /** + * User agent firewall configs set. + * + * @return void. + */ + public static function set_user_agent_firewall_configs() { + global $aio_wp_security; + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_blacklisting') && !empty($aio_wp_security->configs->get_value('aiowps_banned_user_agents'))) { + $aiowps_firewall_config->set_value('aiowps_blacklist_user_agents', explode("\n", preg_replace("/\r/", "", trim($aio_wp_security->configs->get_value('aiowps_banned_user_agents'))))); + } else { + $aiowps_firewall_config->set_value('aiowps_blacklist_user_agents', array()); + } + } + + /** + * Port block fake Googlebots config to firewall config. + * + * @global AIO_WP_Security $aio_wp_security + * @global AIOWPS\Firewall\Config $aiowps_firewall_config + * + * @return void + */ + private static function port_block_fake_googlebots_config() { + global $aio_wp_security; + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + + if ('1' == $aio_wp_security->configs->get_value('aiowps_block_fake_googlebots')) { + $aiowps_firewall_config->set_value('aiowps_block_fake_googlebots', true); + + $validated_ip_list_array = AIOWPSecurity_Utility::get_googlebot_ip_ranges(); + + if (!is_wp_error($validated_ip_list_array)) { + $aiowps_firewall_config->set_value('aiowps_googlebot_ip_ranges', $validated_ip_list_array); + } + } else { + $aiowps_firewall_config->set_value('aiowps_block_fake_googlebots', false); + } + } + + /** + * IP retrieve method configs set. + * + * @return void. + */ + public static function set_ip_retrieve_method_configs() { + global $aio_wp_security; + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + $aiowps_firewall_config->set_value('aios_ip_retrieve_method', $aio_wp_security->configs->get_value('aiowps_ip_retrieve_method')); + } + + /** + * Turn off all security features. + * + * @return void. + */ + public static function turn_off_all_security_features() { + global $aio_wp_security; + AIOWPSecurity_Configure_Settings::set_default_settings(); + + //Refresh the .htaccess file based on the new settings + $serverType = AIOWPSecurity_Utility::get_server_type(); + if (!in_array($serverType, array('-1', 'nginx', 'iis'))) { + $res = AIOWPSecurity_Utility_Htaccess::write_to_htaccess(); + } else { + $res = true; + } + if (!$res) { + $aio_wp_security->debug_logger->log_debug(__METHOD__ . " - Could not write to the .htaccess file. Please check the file permissions.", 4); + } + } + + /** + * Turn off 6g firewall configs. + * + * @return void. + */ + public static function turn_off_all_6g_firewall_configs() { + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + $aiowps_firewall_config->set_value('aiowps_6g_block_request_methods', array()); + $aiowps_firewall_config->set_value('aiowps_6g_block_query', false); + $aiowps_firewall_config->set_value('aiowps_6g_block_request', false); + $aiowps_firewall_config->set_value('aiowps_6g_block_referrers', false); + $aiowps_firewall_config->set_value('aiowps_6g_block_agents', false); + } + + + /** + * Turn off all firewall configs. + * + * @return void. + */ + public static function turn_off_firewall_configs() { + global $aiowps_firewall_config, $aio_wp_security; + $aio_wp_security->configs->set_value('aiowps_disable_xmlrpc_pingback_methods', ''); + $aio_wp_security->configs->set_value('aiowps_disable_rss_and_atom_feeds', ''); + $aio_wp_security->configs->set_value('aiowps_enable_basic_firewall', ''); + $aio_wp_security->configs->set_value('aiowps_max_file_upload_size', AIOS_FIREWALL_MAX_FILE_UPLOAD_LIMIT_MB); //Default + $aio_wp_security->configs->set_value('aiowps_block_debug_log_file_access', ''); + $aio_wp_security->configs->set_value('aiowps_disable_index_views', ''); + $aio_wp_security->configs->set_value('aiowps_disable_trace_and_track', ''); + $aio_wp_security->configs->set_value('aiowps_enable_blacklisting', ''); + $aio_wp_security->configs->set_value('aiowps_enable_5g_firewall', ''); + $aio_wp_security->configs->set_value('aiowps_disallow_unauthorized_rest_requests', ''); + $aio_wp_security->configs->save_config(); + + self::turn_off_all_6g_firewall_configs(); + $aiowps_firewall_config->set_value('aiowps_enable_pingback_firewall', false); + $aiowps_firewall_config->set_value('aiowps_forbid_proxy_comments', false); + $aiowps_firewall_config->set_value('aiowps_deny_bad_query_strings', false); + $aiowps_firewall_config->set_value('aiowps_advanced_char_string_filter', false); + $aiowps_firewall_config->set_value('aiowps_ban_post_blank_headers', false); + $aiowps_firewall_config->set_value('aiowps_block_fake_googlebots', false); + $aiowps_firewall_config->set_value('aiowps_googlebot_ip_ranges', array()); + $aiowps_firewall_config->set_value('aiowps_blacklist_user_agents', array()); + $aiowps_firewall_config->set_value('aiowps_blacklist_ips', array()); + Allow_List::add_ips(array()); // Remove firewall whitelisted IPs + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-cronjob-handler.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-cronjob-handler.php new file mode 100755 index 00000000..fa566e3a --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-cronjob-handler.php @@ -0,0 +1,157 @@ + 900, // 15 * 60 + 'display' => __('Every 15 minutes', 'all-in-one-wp-security-and-firewall') + ); + return $schedules; + } + + /** + * Run cron event every 5 minute. + * + * @return void + */ + public function aios_15_minutes_cron_event() { + global $aio_wp_security; + + if (!class_exists('Updraft_Semaphore_3_0')) { + require_once(AIO_WP_SECURITY_PATH.'/vendor/team-updraft/common-libs/src/updraft-semaphore/class-updraft-semaphore.php'); + } + + $fifteen_minutes_cron_semaphore = new Updraft_Semaphore_3_0('aios_15_minutes_cron_event', 60); + + if ($fifteen_minutes_cron_semaphore->lock(2)) { + try { + $aio_wp_security->user_login_obj->send_login_lockout_emails(); + } catch (Exception $e) { + $log_message = 'Exception ('.get_class($e).') occurred during the 5 minutes cron event action call: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')'; + $aio_wp_security->debug_logger->log_debug($log_message, 4); + // @codingStandardsIgnoreLine + } catch (Error $e) { + $log_message = 'PHP Fatal error ('.get_class($e).') occurred during the the 5 minutes cron event action call. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')'; + $aio_wp_security->debug_logger->log_debug($log_message, 4); + } + + $fifteen_minutes_cron_semaphore->release(); + } else { + $aio_wp_security->debug_logger->log_debug('The 15 minutes cron event lock could not get the lock.'); + } + } + + public function aiowps_hourly_cron_event_handler() { + //Do stuff that needs checking hourly + AIOWPSecurity_Comment::trash_spam_comments(); + do_action('aiowps_perform_fcd_scan_tasks'); + do_action('delete_expired_logged_in_users_event'); + } + + /** + * Run daily cron event + * + * @return void + */ + public function aiowps_daily_cron_event_handler() { + do_action('aiowps_perform_db_cleanup_tasks'); + do_action('aiowps_purge_old_debug_logs'); + do_action('aiowps_send_lockout_email'); + do_action('aios_perform_update_antibot_keys'); + do_action('aios_update_googlebot_ip_ranges'); + } + + /** + * Purges debug logs older than 90 days + * The 90 days can be modified using the constant AIOWPSEC_PURGE_DEBUG_LOGS_AFTER_DAYS + * + * @return void + */ + public function purge_old_debug_logs() { + + global $wpdb, $aio_wp_security; + + $debug_tbl_name = AIOWPSEC_TBL_DEBUG_LOG; + $after_days = 90; + + if (defined('AIOWPSEC_PURGE_DEBUG_LOGS_AFTER_DAYS')) { + $after_days = abs(AIOWPSEC_PURGE_DEBUG_LOGS_AFTER_DAYS); + } + + $after_days = empty($after_days) ? 90 : $after_days; + $older_than_date_time = strtotime('-' . $after_days . ' days', time()); + + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore + $ret = $wpdb->query($wpdb->prepare('DELETE FROM ' . $debug_tbl_name . ' WHERE logtime < %s', $older_than_date_time)); + if (false === $ret) { + $error_msg = empty($wpdb->last_error) ? 'Could not receive the reason for the failure' : $wpdb->last_error; + $aio_wp_security->debug_logger->log_debug_cron("Failed to purge older debug logs : {$error_msg}", 4); + } + } + /** + * Send email notification to an user who has flag is_lockout_email_sent is 0. + * + * @return Void + */ + public function send_lockout_email() { + global $aio_wp_security; + $aio_wp_security->user_login_obj->send_login_lockout_emails(); + } + + /** + * Update Googlebot IP ranges for the firewall configuration. + * + * This function updates the Googlebot IP ranges in the firewall configuration. + * It checks if the 'Block fake Googlebots' feature is enabled and then retrieves + * the validated Googlebot IP ranges. If the IP ranges are retrieved successfully, + * they are saved to the firewall configuration. If there is an error in retrieving + * the IP ranges, a debug message is logged. + * + * @global object $aio_wp_security The main AIO WP Security object. + * @global object $aiowps_firewall_config The AIO WP Security firewall configuration object. + * + * @return void + */ + public function aios_update_googlebot_ip_ranges() { + global $aio_wp_security; + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + + if ($aiowps_firewall_config->get_value('aiowps_block_fake_googlebots')) { + $validated_ip_list_array = AIOWPSecurity_Utility::get_googlebot_ip_ranges(); + + if (is_wp_error($validated_ip_list_array)) { + $aio_wp_security->debug_logger->log_debug('The attempt to save the IP addresses failed, because it was not possible to validate the Googlebot IP addresses: ' . $validated_ip_list_array->get_error_message(), 4); + } + + $aiowps_firewall_config->set_value('aiowps_googlebot_ip_ranges', $validated_ip_list_array); + } + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-deactivation-tasks.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-deactivation-tasks.php new file mode 100755 index 00000000..66e1ba4c --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-deactivation-tasks.php @@ -0,0 +1,47 @@ +configs->load_config(); + + if (is_main_site()) { + // Remove all firewall and other .htaccess rules and remove all settings from .htaccess file that were added by this plugin. + AIOWPSecurity_Utility_Htaccess::delete_from_htaccess(); + + // Remove user meta info so next activation if force logout on it do not logs user out + AIOWPSecurity_User_Login::remove_login_activity(); + + // Deactivate PHP-based firewall. + AIOWPSecurity_Utility_Firewall::remove_firewall(); + } + + self::clear_cron_events(); + } + + /** + * Helper function which clears aiowps cron events + */ + private static function clear_cron_events() { + wp_clear_scheduled_hook('aiowps_hourly_cron_event'); + wp_clear_scheduled_hook('aiowps_daily_cron_event'); + wp_clear_scheduled_hook('aios_15_minutes_cron_event'); + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-debug-logger.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-debug-logger.php new file mode 100755 index 00000000..f844c280 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-debug-logger.php @@ -0,0 +1,100 @@ +debug_logger->log_debug("Log messaged goes here"); + */ +if (!defined('ABSPATH')) { + exit;//Exit if accessed directly +} + +class AIOWPSecurity_Logger { + + private $debug_enabled = false; + + private $debug_readable_level = array('SUCCESS','STATUS','NOTICE','WARNING','FAILURE','CRITICAL'); + + public function __construct($debug_enabled) { + $this->debug_enabled = $debug_enabled; + } + + /** + * Translates the level code to its readable form + * + * @param integer $level_code - The level code to translate (e.g: 2) + * @return string - The level as its readable value (e.g: NOTICE) + */ + private function get_readable_level_from_code($level_code) { + return isset($this->debug_readable_level[$level_code]) ? $this->debug_readable_level[$level_code] : 'UNKNOWN'; + } + + /** + * Clears the debug logs + * + * @return int|WP_Error the amount of records deleted or WP_Error if query failed + */ + public function clear_logs() { + global $wpdb; + + $debug_log_tbl = AIOWPSEC_TBL_DEBUG_LOG; + + if (is_super_admin()) { + $ret = $wpdb->query("DELETE FROM $debug_log_tbl"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- We can't use %i because our plugin supports wordpress < 6.2. + } else { + $ret = $wpdb->query($wpdb->prepare("DELETE FROM $debug_log_tbl WHERE site_id = %d", get_current_blog_id())); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- We can't use %i because our plugin supports wordpress < 6.2. + } + + if (false === $ret) { + $error_msg = empty($wpdb->last_error) ? __('Unable to get the reason why', 'all-in-one-wp-security-and-firewall') : $wpdb->last_error; + $ret = new WP_Error('db_unable_delete', __('Unable to clear the logs', 'all-in-one-wp-security-and-firewall'), $error_msg); + } + + return $ret; + } + + /** + * Logs the debug messages to the database + * + * @param string $message - The main debug message + * @param integer $level_code - The level code which indicates the severity of the message + * @param string $type - The type of debug message. Separates general debug messages from those generated by the cron, for example. + * @return void + */ + public function log_debug($message, $level_code = 0, $type = 'debug') { + + if (!$this->debug_enabled) { + return; + } + + global $wpdb; + $debug_tbl_name = AIOWPSEC_TBL_DEBUG_LOG; + + $data = array( + 'created' => current_time('mysql'), + 'level' => $this->get_readable_level_from_code($level_code), + 'network_id' => get_current_network_id(), + 'site_id' => get_current_blog_id(), + 'message' => $message, + 'type' => $type, + ); + + $ret = $wpdb->query($wpdb->prepare("INSERT INTO ".$debug_tbl_name." (created, logtime, level, network_id, site_id, message, type) VALUES (%s, UNIX_TIMESTAMP(), %s, %d, %d, %s, %s)", $data['created'], $data['level'], $data['network_id'], $data['site_id'], $data['message'], $data['type'])); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared -- We can't use %i because our plugin supports wordpress < 6.2. + if (false === $ret) { + $error_msg = empty($wpdb->last_error) ? 'Could not write to the debug log' : $wpdb->last_error; + error_log("All In One WP Security : {$error_msg}"); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- We can't replace error_log with our debug logger here because the debug logger has failed. + } + } + + /** + * Logs the debug messages that relate to the cron + * + * @param string $message - The main debug message + * @param integer $level_code - The level code which indicates the severity of the message + * @return void + */ + public function log_debug_cron($message, $level_code = 0) { + $this->log_debug($message, $level_code, 'cron_debug'); + } + + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-debug.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-debug.php new file mode 100755 index 00000000..203c7671 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-debug.php @@ -0,0 +1,588 @@ + 'get_aios_info', + 'Server information' => 'get_server_info', + 'WordPress information' => 'get_wordpress_info', + 'PHP information' => 'get_php_info', + 'Database information' => 'get_database_info', + 'Plugin information' => 'get_plugins_list', + 'Must-use plugin information' => 'get_mu_plugins_list', + 'Drop-in information' => 'get_dropin_plugins_list', + 'Theme information' => 'get_themes_list', + 'IP detection methods' => 'get_ip_detection_methods', + 'Cron information' => 'get_cron_jobs_list', + ); + + /** + * Constructor + * + * @return void + */ + public function __construct() { + add_action('aiowp_security_additional_report_actions', array($this, 'add_sender_report_actions')); + } + + /** + * Get AIOS Information + * + * @return array AIOS information + */ + private static function get_aios_info() { + + $aios_info = array( + 'AIOS plugin version' => AIO_WP_SECURITY_VERSION, + 'AIOS DB version' => AIO_WP_SECURITY_DB_VERSION, + 'AIOS firewall version' => AIO_WP_SECURITY_FIREWALL_VERSION, + 'AIOS Premium installed' => AIOWPSecurity_Utility_Permissions::is_premium_installed() ? 'Yes' : 'No', + ); + + if (AIOWPSecurity_Utility_Permissions::is_premium_installed()) { + $aios_info['AIOS Premium version'] = AIOWPS_PREMIUM_VERSION; + } + + return apply_filters('aiowp_security_get_aios_info', $aios_info); + } + + /** + * Get Server Information + * + * @return array Server information + */ + private static function get_server_info() { + + $server_info = array( + 'Operating system' => php_uname('s') . ' ' . php_uname('r'), + 'Server' => $_SERVER['SERVER_SOFTWARE'], + 'Memory usage' => AIOWPSecurity_Utility::convert_numeric_size_to_text(memory_get_peak_usage(true)), + ); + + if (function_exists('disk_total_space')) { + $server_info = array_merge($server_info, array( + 'Total space' => AIOWPSecurity_Utility::convert_numeric_size_to_text(disk_total_space('/')), + 'Used space' => AIOWPSecurity_Utility::convert_numeric_size_to_text(disk_total_space('/') - disk_free_space('/')), + )); + } + return apply_filters('aiowp_security_get_server_info', $server_info); + } + + /** + * Get PHP Information + * + * @return array PHP information + */ + private static function get_php_info() { + + $php_info = array( + 'PHP version' => phpversion(), + 'PHP expose php' => ini_get('expose_php') ? 'Active' : 'Inactive', + 'PHP allow url fopen' => ini_get('allow_url_fopen') ? 'Active' : 'Inactive', + 'PHP memory limit' => ini_get('memory_limit'), + 'PHP upload max filesize' => ini_get('upload_max_filesize'), + 'PHP post max size' => ini_get('post_max_size'), + 'PHP max execution time' => ini_get('max_execution_time'), + 'PHP max input time' => ini_get('max_input_time'), + 'Process owner' => (function_exists('posix_geteuid') && function_exists('posix_getpwuid')) ? posix_getpwuid(posix_geteuid())['name'] : 'Unknown', + 'OpenSSL support' => extension_loaded('openssl') ? 'OK' : 'Not Installed', + 'OpenSSL version' => extension_loaded('openssl') ? OPENSSL_VERSION_TEXT : 'Unknown', + 'cURL support' => function_exists('curl_init') ? 'OK' : 'Not Installed', + 'cURL features code' => function_exists('curl_version') ? curl_version()['features'] : 'Unknown', + 'cURL host' => function_exists('curl_version') ? curl_version()['host'] : 'Unknown', + 'cURL support protocols' => function_exists('curl_version') ? implode(', ', curl_version()['protocols']) : 'Unknown', + 'cURL SSL version' => function_exists('curl_version') ? curl_version()['ssl_version'] : 'Unknown', + 'cURL libz version' => function_exists('curl_version') ? curl_version()['libz_version'] : 'Unknown', + 'Checking display_errors' => ini_get('display_errors') ? 'Enabled' : 'Disabled', + ); + + return apply_filters('aiowp_security_get_php_info', $php_info); + } + + /** + * Retrieves detailed information about the WordPress configuration. + * + * @return array WordPress configuration information + */ + private static function get_wordpress_info() { + + // Include version.php to retrieve the actual WordPress version + require_once ABSPATH . WPINC . '/version.php'; + + global $wp_version; + + $wp_info = array( + 'WordPress version' => $wp_version, + 'Multisite' => is_multisite() ? 'Yes' : 'No', // Checking if the site is multisite + 'ABSPATH' => ABSPATH, + 'WP_DEBUG' => (defined('WP_DEBUG') && WP_DEBUG) ? 'On' : 'Off', + 'WP_DEBUG_LOG' => (defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) ? 'Enabled' : 'Disabled', + 'WP_DEBUG_DISPLAY' => (defined('WP_DEBUG_DISPLAY') && WP_DEBUG_DISPLAY) ? 'Enabled' : 'Disabled', + 'SCRIPT_DEBUG' => (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? 'On' : 'Off', + 'SAVEQUERIES' => (defined('SAVEQUERIES') && SAVEQUERIES) ? 'On' : 'Off', + 'DB_CHARSET' => defined('DB_CHARSET') ? DB_CHARSET : '(not set)', + 'DB_COLLATE' => defined('DB_COLLATE') ? DB_COLLATE : '(not set)', + 'WP_SITEURL' => defined('WP_SITEURL') ? WP_SITEURL : '(not set)', + 'WP_HOME' => defined('WP_HOME') ? WP_HOME : '(not set)', + 'WP_CONTENT_DIR' => defined('WP_CONTENT_DIR') ? WP_CONTENT_DIR : '(not set)', + 'WP_CONTENT_URL' => defined('WP_CONTENT_URL') ? WP_CONTENT_URL : '(not set)', + 'WP_PLUGIN_DIR' => defined('WP_PLUGIN_DIR') ? WP_PLUGIN_DIR : '(not set)', + 'WP_LANG_DIR' => defined('WP_LANG_DIR') ? WP_LANG_DIR : '(not set)', + 'WPLANG' => defined('WPLANG') ? WPLANG : '(not set)', + 'UPLOADS' => defined('UPLOADS') ? UPLOADS : '(not set)', + 'TEMPLATEPATH' => defined('TEMPLATEPATH') ? TEMPLATEPATH : '(not set)', + 'STYLESHEETPATH' => defined('STYLESHEETPATH') ? STYLESHEETPATH : '(not set)', + 'AUTOSAVE_INTERVAL' => defined('AUTOSAVE_INTERVAL') ? AUTOSAVE_INTERVAL : '', + 'WP_POST_REVISIONS' => defined('WP_POST_REVISIONS') ? WP_POST_REVISIONS : 'Unlimited', + 'COOKIE_DOMAIN' => defined('COOKIE_DOMAIN') ? COOKIE_DOMAIN : '(not set)', + 'COOKIEPATH' => defined('COOKIEPATH') ? COOKIEPATH : '/', + 'SITECOOKIEPATH' => defined('SITECOOKIEPATH') ? SITECOOKIEPATH : '/', + 'ADMIN_COOKIE_PATH' => defined('ADMIN_COOKIE_PATH') ? ADMIN_COOKIE_PATH : '/', + 'PLUGINS_COOKIE_PATH' => defined('PLUGINS_COOKIE_PATH') ? PLUGINS_COOKIE_PATH : '/wp-content/plugins', + 'NOBLOGREDIRECT' => defined('NOBLOGREDIRECT') ? NOBLOGREDIRECT : '(not set)', + 'CONCATENATE_SCRIPTS' => defined('CONCATENATE_SCRIPTS') ? (CONCATENATE_SCRIPTS ? 'Yes' : 'No') : 'No', // Checking if CONCATENATE_SCRIPTS is defined + 'WP_MEMORY_LIMIT' => defined('WP_MEMORY_LIMIT') ? WP_MEMORY_LIMIT : '', + 'WP_MAX_MEMORY_LIMIT' => defined('WP_MAX_MEMORY_LIMIT') ? WP_MAX_MEMORY_LIMIT : '', + 'WP_CACHE' => defined('WP_CACHE') ? (WP_CACHE ? 'Enabled' : 'Disabled') : 'Disabled', + 'CUSTOM_USER_TABLE' => defined('CUSTOM_USER_TABLE') ? CUSTOM_USER_TABLE : '(not set)', + 'CUSTOM_USER_META_TABLE' => defined('CUSTOM_USER_META_TABLE') ? CUSTOM_USER_META_TABLE : '(not set)', + 'FS_CHMOD_DIR' => defined('FS_CHMOD_DIR') ? FS_CHMOD_DIR : '(not set)', + 'FS_CHMOD_FILE' => defined('FS_CHMOD_FILE') ? FS_CHMOD_FILE : '(not set)', + 'ALTERNATE_WP_CRON' => defined('ALTERNATE_WP_CRON') ? (ALTERNATE_WP_CRON ? 'Enabled' : 'Disabled') : 'Disabled', + 'DISABLE_WP_CRON' => defined('DISABLE_WP_CRON') ? (DISABLE_WP_CRON ? 'Cron is disabled' : 'Cron is enabled') : 'Cron is enabled', + 'WP_CRON_LOCK_TIMEOUT' => defined('WP_CRON_LOCK_TIMEOUT') ? WP_CRON_LOCK_TIMEOUT : '', + 'EMPTY_TRASH_DAYS' => defined('EMPTY_TRASH_DAYS') ? EMPTY_TRASH_DAYS : '', + 'WP_ALLOW_REPAIR' => defined('WP_ALLOW_REPAIR') ? (WP_ALLOW_REPAIR ? 'Enabled' : 'Disabled') : 'Disabled', + 'DO_NOT_UPGRADE_GLOBAL_TABLES' => defined('DO_NOT_UPGRADE_GLOBAL_TABLES') ? (DO_NOT_UPGRADE_GLOBAL_TABLES ? 'Yes' : 'No') : 'No', // Checking if DO_NOT_UPGRADE_GLOBAL_TABLES is defined + 'DISALLOW_FILE_EDIT' => defined('DISALLOW_FILE_EDIT') ? (DISALLOW_FILE_EDIT ? 'Yes' : 'No') : 'No', // Checking if DISALLOW_FILE_EDIT is defined + 'DISALLOW_FILE_MODS' => defined('DISALLOW_FILE_MODS') ? (DISALLOW_FILE_MODS ? 'Yes' : 'No') : 'No', // Checking if DISALLOW_FILE_MODS is defined + 'IMAGE_EDIT_OVERWRITE' => defined('IMAGE_EDIT_OVERWRITE') ? (IMAGE_EDIT_OVERWRITE ? 'Yes' : 'No') : 'No', // Checking if IMAGE_EDIT_OVERWRITE is defined + 'FORCE_SSL_ADMIN' => defined('FORCE_SSL_ADMIN') ? (FORCE_SSL_ADMIN ? 'Yes' : 'No') : 'No', // Checking if FORCE_SSL_ADMIN is defined + 'WP_HTTP_BLOCK_EXTERNAL' => defined('WP_HTTP_BLOCK_EXTERNAL') ? (WP_HTTP_BLOCK_EXTERNAL ? 'Yes' : 'No') : 'No', // Checking if WP_HTTP_BLOCK_EXTERNAL is defined + 'WP_ACCESSIBLE_HOSTS' => defined('WP_ACCESSIBLE_HOSTS') ? WP_ACCESSIBLE_HOSTS : '(not set)', + 'WP_AUTO_UPDATE_CORE' => defined('WP_AUTO_UPDATE_CORE') ? WP_AUTO_UPDATE_CORE : 'Default', + 'WP_PROXY_HOST' => defined('WP_PROXY_HOST') ? WP_PROXY_HOST : '(not set)', + 'WP_PROXY_PORT' => defined('WP_PROXY_PORT') ? WP_PROXY_PORT : '(not set)', + 'MULTISITE' => defined('MULTISITE') ? (MULTISITE ? 'Yes' : 'No') : 'No', // Checking if MULTISITE is defined + 'WP_ALLOW_MULTISITE' => defined('WP_ALLOW_MULTISITE') ? (WP_ALLOW_MULTISITE ? 'Yes' : 'No') : 'No', // Checking if WP_ALLOW_MULTISITE is defined + 'SUNRISE' => defined('SUNRISE') ? (SUNRISE ? 'Yes' : 'No') : 'No', // Checking if SUNRISE is defined + 'SUBDOMAIN_INSTALL' => defined('SUBDOMAIN_INSTALL') ? (SUBDOMAIN_INSTALL ? 'Yes' : 'No') : 'No', // Checking if SUBDOMAIN_INSTALL is defined + 'VHOST' => defined('VHOST') ? (VHOST ? 'Yes' : 'No') : 'No', // Checking if VHOST is defined + 'DOMAIN_CURRENT_SITE' => defined('DOMAIN_CURRENT_SITE') ? DOMAIN_CURRENT_SITE : '(not set)', + 'PATH_CURRENT_SITE' => defined('PATH_CURRENT_SITE') ? PATH_CURRENT_SITE : '(not set)', + 'BLOG_ID_CURRENT_SITE' => defined('BLOG_ID_CURRENT_SITE') ? BLOG_ID_CURRENT_SITE : '(not set)', + 'WP_DISABLE_FATAL_ERROR_HANDLER' => defined('WP_DISABLE_FATAL_ERROR_HANDLER') ? (WP_DISABLE_FATAL_ERROR_HANDLER ? 'Yes' : 'No') : 'No', // Checking if WP_DISABLE_FATAL_ERROR_HANDLER is defined + 'AUTOMATIC_UPDATER_DISABLED' => defined('AUTOMATIC_UPDATER_DISABLED') ? (AUTOMATIC_UPDATER_DISABLED ? 'Yes' : 'No') : 'No' // Checking if AUTOMATIC_UPDATER_DISABLED is defined + ); + + return apply_filters('aiowp_security_get_wordpress_info', $wp_info); + } + + /** + * Get a list of active and inactive plugins. + * + * @return array List of plugins with their status (active/inactive). + */ + private static function get_plugins_list() { + $plugins = get_plugins(); + $active_plugins = get_option('active_plugins', array()); + + $plugins_list = array(); + + if (empty($plugins)) { + return array('No plugins found' => '-'); + } + + foreach ($plugins as $plugin_path => $plugin_info) { + $plugin_slug = strtolower(basename($plugin_path, '.php')); + $plugin_status = in_array($plugin_path, $active_plugins) ? 'Active' : 'Inactive'; + $plugin_version = $plugin_info['Version']; + $plugin_name = $plugin_info['Name']; + + $plugin_key = "$plugin_name ($plugin_slug) [$plugin_version]"; + + $plugins_list[$plugin_key] = $plugin_status; + } + + return apply_filters('aiowp_security_get_plugins_info', $plugins_list); + } + + /** + * Get a list of themes with their status (active/inactive), version, and slug. + * + * @return array List of themes. + */ + private static function get_themes_list() { + $themes = wp_get_themes(); + $active_theme = wp_get_theme(); + $themes_list = array(); + + if (empty($themes)) { + return array('No themes found' => '-'); + } + + foreach ($themes as $theme_slug => $theme_info) { + $theme_name = $theme_info->get('Name'); + $theme_version = $theme_info->get('Version'); + $theme_status = $theme_info->get_stylesheet() === $active_theme->get_stylesheet() ? 'Active' : 'Inactive'; + + $theme_key = "$theme_name ($theme_slug) [$theme_version]"; + $themes_list[$theme_key] = $theme_status; + } + + return apply_filters('aiowp_security_get_themes_info', $themes_list); + } + + /** + * Get database information + * + * @return array Database information + */ + private static function get_database_info() { + global $wpdb; + + $database_info = array( + 'Database version' => $wpdb->db_version(), + 'DELETE' => self::check_mysql_privilege('DELETE'), + 'INSERT' => self::check_mysql_privilege('INSERT'), + 'UPDATE' => self::check_mysql_privilege('UPDATE'), + 'SELECT' => self::check_mysql_privilege('SELECT'), + 'CREATE TABLE' => self::check_mysql_privilege('CREATE TABLE'), + 'ALTER TABLE' => self::check_mysql_privilege('ALTER TABLE'), + 'DROP' => self::check_mysql_privilege('DROP'), + 'TRUNCATE' => self::check_mysql_privilege('TRUNCATE') + ); + + return apply_filters('aiowp_security_get_database_info', $database_info); + } + + /** + * Get a list of Must Use (MU) plugins. + * + * @return array List of MU plugins. + */ + private static function get_mu_plugins_list() { + $mu_plugins = get_mu_plugins(); + $mu_plugins_list = array(); + + if (empty($mu_plugins)) { + return array('No Must-use plugins found' => '-'); + } + + foreach ($mu_plugins as $mu_plugin_path => $mu_plugin_info) { + $mu_plugin_slug = basename($mu_plugin_path, '.php'); + $mu_plugin_version = $mu_plugin_info['Version']; + $mu_plugin_name = $mu_plugin_info['Name']; + + $mu_plugin_key = "$mu_plugin_name ($mu_plugin_slug) [$mu_plugin_version]"; + + $mu_plugins_list[$mu_plugin_key] = 'Active'; + } + + return apply_filters('aiowp_security_get_mu_plugins_info', $mu_plugins_list); + } + + /** + * Get a list of drop-in plugins. + * + * @return array List of drop-in plugins. + */ + private static function get_dropin_plugins_list() { + $dropins = _get_dropins(); + $dropins_list = array(); + + if ('' === $dropins) { + return array('No drop-in plugins found' => '-'); + } + + foreach ($dropins as $dropin_file => $dropin_info) { + $dropin_status = true === $dropin_info[1] ? 'Active' : 'Inactive'; + $dropin_description = $dropin_info[0]; + + $dropin_key = "$dropin_file [$dropin_description]"; + $dropins_list[$dropin_key] = $dropin_status; + } + + return apply_filters('aiowp_security_get_dropin_plugins_info', $dropins_list); + } + + /** + * Get a list of cron jobs scheduled in WordPress. + * + * @return array List of cron jobs. + */ + public static function get_cron_jobs_list() { + $cron_jobs = _get_cron_array(); + $cron_jobs_list = array(); + + $failed_jobs = 0; + + if (empty($cron_jobs)) { + return array(); // Return an empty array if no cron jobs are found. + } + + $current_timestamp = time(); + $cron_jobs_list['Failed cron jobs'] = $failed_jobs; + foreach ($cron_jobs as $timestamp => $cron_events) { + foreach ($cron_events as $event_hook => $event_data) { + foreach ($event_data as $schedule => $callback) { + if ($timestamp < $current_timestamp) { + $failed_jobs++; + } + $schedule = $callback['schedule']; + $cron_jobs_list[$event_hook] = $schedule; + } + } + } + + return apply_filters('aiowp_security_get_cron_jobs_info', $cron_jobs_list); + } + + /** + * Get debug log + * + * @param bool $html Whether to return the debug log as HTML + * + * @return string Debug log + */ + private static function get_debug_log($html = false) { + global $wpdb, $aio_wp_security; + + if ('1' === $aio_wp_security->configs->get_value('aiowps_enable_debug')) { + + $debug_log_tbl = AIOWPSEC_TBL_DEBUG_LOG; + + $where_sql = is_super_admin() ? '' : 'WHERE site_id = %d'; + $query = "SELECT * FROM {$debug_log_tbl} {$where_sql} ORDER BY id DESC LIMIT 100"; + + $debug_logs = is_super_admin() ? $wpdb->get_results($query, ARRAY_A) : $wpdb->get_results($wpdb->prepare($query, get_current_blog_id()), ARRAY_A); + + if ($html) { + $debug_log = "

Debug log

"; + } else { + $debug_log = "\n --- Debug log --- \n\n"; + } + + foreach ($debug_logs as $log) { + $date_time = esc_html($log['created']); + $level = esc_html($log['level']); + $message = esc_html($log['message']); + $type = esc_html($log['type']); + + if ($html) { + $debug_log .= "Only the most recent 100 logs are displayed
"; + $debug_log .= "Date and time: $date_time
"; + $debug_log .= "Level: $level
"; + $debug_log .= "Message: $message
"; + $debug_log .= "Type: $type

"; + } else { + $debug_log .= "Only the most recent 100 logs are displayed.\n"; + $debug_log .= "Date and time: $date_time\n"; + $debug_log .= "Level: $level\n"; + $debug_log .= "Message: $message\n"; + $debug_log .= "Type: $type\n\n"; + } + } + + return apply_filters('aiowp_security_get_debug_log_info', $debug_log); + } + } + + /** + * Get the IP address detection methods and their status + * + * @return array IP detection methods and their status + */ + private static function get_ip_detection_methods() { + global $aio_wp_security; + $ip_detection_methods = AIOS_Abstracted_Ids::get_ip_retrieve_methods(); + + $active_method = $aio_wp_security->configs->get_site_value('aiowps_ip_retrieve_method'); // In a multisite network, this setting is available for the main site only. + $active_method = empty($active_method) ? 0 : (int) $active_method; + + $ip_detection_list = array(); + + foreach ($ip_detection_methods as $method => $variable) { + $status = ($method === $active_method) ? ' - ' . __('status', 'all-in-one-wp-security-and-firewall') . ': ' . __('On', 'all-in-one-wp-security-and-firewall') : ''; + $ip_address = (!empty($_SERVER[$variable])) ? $_SERVER[$variable] : ''; + $ip_detection_list[$variable] = __('IP', 'all-in-one-wp-security-and-firewall') . ': ' . $ip_address . $status; + } + + return $ip_detection_list; + } + + /** + * Check if the current MySQL user has the specified privilege + * + * @param string $privilege Privilege to check + * + * @return string 'OK' if the user has the privilege, 'Not OK' otherwise + */ + private static function check_mysql_privilege($privilege) { + global $wpdb; + $grants = $wpdb->get_results("SHOW GRANTS FOR CURRENT_USER", ARRAY_N); + foreach ($grants as $grant) { + foreach ($grant as $grant_string) { + if (strpos(strtoupper($grant_string), 'ALL PRIVILEGES') !== false || strpos(strtoupper($grant_string), strtoupper($privilege)) !== false) { + return 'OK'; + } + } + } + return 'Not OK'; + } + + /** + * Generate the debug report + * + * @return string Debug report + */ + public static function generate_report() { + + $data = ''; + $section_content = array(); + + foreach (self::$sections as $title => $method) { + $section_title = esc_html($title); + $section_content = self::$method(); + + // Check if the section content is empty, and handle accordingly. + if (empty($section_content)) { + $section_content = array('No data available'); + } + + $data .= AIOWPSecurity_Reporting::generate_report_sections('table', $section_content, $section_title); + } + + return $data; + } + + /** + * Generate a report for the diagnostics page + * + * @param string $title The title of the report + * + * @return string Report textarea + */ + public static function generate_report_textarea($title) { + $main_content = ''; + + $report_content = $title . "\n\n===================================\n"; + + foreach (self::$sections as $title => $method) { + $section_title = esc_html($title); + $section_content = self::$method(); + $main_content .= AIOWPSecurity_Reporting::generate_report_sections('text', $section_content, $section_title); + } + + $main_content .= self::get_debug_log(); + + $report_content = apply_filters('aiowp_security_generate_report_content', $report_content . $main_content); + + $escaped_content = esc_textarea($report_content); + + return ''; + } + + /** + * Generate sender action button and field + * + * @return string sender action button and email field + */ + public static function add_sender_report_actions() { + $report_sections = ''; + foreach (self::$sections as $title => $method) { + $section_title = esc_html($title); + $section_content = self::$method(); + $report_sections .= AIOWPSecurity_Reporting::generate_report_sections('table', $section_content, $section_title); + } + $encoded_report_sections = htmlentities($report_sections); + + $data = '

'; + $data .= '

'; + $data .= ''; + $data .= ''; + $data .= '
'; + + // Allow only safe HTML in the response + echo wp_kses($data, array( + 'div' => array(), + 'form' => array( + 'action' => true, + 'method' => true, + ), + 'input' => array( + 'type' => true, + 'id' => true, + 'placeholder' => true, + 'value' => true, + 'required' => true, + ), + 'button' => array( + 'class' => true, + 'id' => true, + ), + 'br' => array(), + )); + } + + /** + * Get the current user email if admin or the site admin email + * + * @return string The email address + */ + private static function get_current_user_email() { + $user = wp_get_current_user(); + if ($user && in_array('administrator', (array) $user->roles, true)) { + return $user->user_email; + } else { + return get_option('admin_email'); + } + } + + /** + * Send the report email + * + * @global AIO_WP_Security $aio_wp_security + * + * @param string $email The email address to send the report to. + * @param string $sections The report sections html. + * + * @return boolean True if the email was sent successfully, false otherwise + */ + public static function send_report($email, $sections) { + global $aio_wp_security; + + $report = ''; + $report .= '

' . esc_html('All-In-One Security diagnostics report') . '

'; + + $site_name = esc_html(get_bloginfo('name')); + $report .= '

' . 'Site name' . ': ' . $site_name . "

"; + + $site_url = esc_url(get_bloginfo('url')); + $report .= '

' . 'Site URL' . ': ' . '' . $site_url . '

'; + + $current_datetime = date_i18n(get_option('date_format') . ' ' . get_option('time_format')); + $report .= '

' . 'Date and time' . ': ' . $current_datetime . "

"; + + $report .= $sections; + + $report .= self::get_debug_log(true); + + $report .= '

' . esc_html('This report was generated by the All-In-One Security plugin.') . '

'; + $subject = esc_html('All-In-One Security - diagnostic report'); + + $result = $aio_wp_security->sender_obj->send_email($email, $subject, $report); + + return $result; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-file-scan.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-file-scan.php new file mode 100755 index 00000000..cbc1ec83 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-file-scan.php @@ -0,0 +1,381 @@ +configs->get_value('aiowps_fcd_filename'); + if (empty($fcd_filename)) { + // means that we haven't done a scan before, or, + // the fcd file containing the results doesn't exist + $random_suffix = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(10); + $fcd_filename = 'aiowps_fcd_data_' . $random_suffix; + $aio_wp_security->configs->set_value('aiowps_fcd_filename', $fcd_filename, true); + } + + $fcd_data = self::get_fcd_data(); // get previous scan data if any + + if (false === $fcd_data) { + // an error occurred so return + return false; + } + + $scanned_data = $this->do_file_change_scan(); + + if (empty($fcd_data)) { + $this->save_fcd_data($scanned_data); + $scan_result['initial_scan'] = '1'; + return $scan_result; + } else { + + $scan_result = $this->compare_scan_data($fcd_data['file_scan_data'], $scanned_data); + + $scan_result['initial_scan'] = ''; + $this->save_fcd_data($scanned_data, $scan_result); + if (!empty($scan_result['files_added']) || !empty($scan_result['files_removed']) || !empty($scan_result['files_changed'])) { + //This means there was a change detected + $aio_wp_security->configs->set_value('aiowps_fcds_change_detected', true, true); + $aio_wp_security->debug_logger->log_debug(__METHOD__ . " - change to filesystem detected!"); + + $this->aiowps_send_file_change_alert_email($scan_result); //Send file change scan results via email if applicable + } else { + //Reset the change flag + $aio_wp_security->configs->set_value('aiowps_fcds_change_detected', false, true); + } + return $scan_result; + } + } + + /** + * Send email with notification about file changes detected by last scan. + * + * @global AIO_WP_Security $aio_wp_security + * @param array $scan_result Array with scan result returned by compare_scan_data() method. + */ + public function aiowps_send_file_change_alert_email($scan_result) { + global $aio_wp_security; + if ('1' == $aio_wp_security->configs->get_value('aiowps_send_fcd_scan_email')) { + $subject = __('All In One WP Security - File change detected', 'all-in-one-wp-security-and-firewall') . ' ' . AIOWPSecurity_Utility::convert_timestamp(null, 'l, F jS, Y \a\\t g:i a'); + //$attachment = array(); + $message = __('A file change was detected on your system for site URL', 'all-in-one-wp-security-and-firewall') . ' ' . network_site_url() . __('. Scan was generated on', 'all-in-one-wp-security-and-firewall') . ' ' . AIOWPSecurity_Utility::convert_timestamp(null, 'l, F jS, Y \a\\t g:i a'); + $message .= "\r\n\r\n".__('A summary of the scan results is shown below:', 'all-in-one-wp-security-and-firewall'); + $message .= "\r\n\r\n"; + $message .= self::get_file_change_summary($scan_result); + $message .= "\r\n".__('Login to your site to view the scan details.', 'all-in-one-wp-security-and-firewall'); + + // Get the email address(es). + $addresses = AIOWPSecurity_Utility::get_array_from_textarea_val($aio_wp_security->configs->get_value('aiowps_fcd_scan_email_address')); + // If no explicit email address(es) are given, send email to site admin. + $to = empty($addresses) ? array(get_site_option('admin_email')) : $addresses; + if (!wp_mail($to, $subject, $message)) { + $aio_wp_security->debug_logger->log_debug(__METHOD__ . " - File change notification email failed to send.", 4); + } + + } + } + + /** + * This function is called via the following filter 'aiowps_perform_fcd_scan_tasks' and will start the file scan + * + * @return void + */ + public function aiowps_scheduled_fcd_scan_handler() { + global $aio_wp_security; + + if ('1' != $aio_wp_security->configs->get_value('aiowps_enable_automated_fcd_scan')) return; + + $aio_wp_security->debug_logger->log_debug_cron(__METHOD__ . " - Scheduled fcd_scan is enabled. Checking now to see if scan needs to be done..."); + + $current_time = time(); + + $next_fcd_scan_time = self::get_next_scheduled_scan(); + + if ($next_fcd_scan_time <= $current_time) { + // It's time to do a filescan + $result = $this->execute_file_change_detection_scan(); + if (false === $result) { + $aio_wp_security->debug_logger->log_debug(__METHOD__ . " - Scheduled filescan operation failed.", 4); + } else { + $aio_wp_security->configs->set_value('aiowps_last_fcd_scan_time', $current_time, true); + } + } + + } + + /** + * This function will get the next scheduled scan timestamp and return it + * + * @return int|bool - the next scheduled scan timestamp, or false if the scheduled scan is not setup + */ + public static function get_next_scheduled_scan() { + global $aio_wp_security; + + if ('1' != $aio_wp_security->configs->get_value('aiowps_enable_automated_fcd_scan')) return false; + + $fcd_scan_frequency = $aio_wp_security->configs->get_value('aiowps_fcd_scan_frequency'); // Number of hours or days or months interval + $interval_setting = $aio_wp_security->configs->get_value('aiowps_fcd_scan_interval'); // Hours/Days/Months + switch ($interval_setting) { + case '0': + $interval = 'hours'; + break; + case '1': + $interval = 'days'; + break; + case '2': + $interval = 'weeks'; + break; + } + $last_fcd_scan_time = $aio_wp_security->configs->get_value('aiowps_last_fcd_scan_time'); + if (null == $last_fcd_scan_time) { + // Set the last scan time to now so it can trigger for the next scheduled period + $last_fcd_scan_time = time(); + $aio_wp_security->configs->set_value('aiowps_last_fcd_scan_time', $last_fcd_scan_time, true); + } elseif (is_string($last_fcd_scan_time)) { + $last_fcd_scan_time = strtotime($last_fcd_scan_time); + $aio_wp_security->configs->set_value('aiowps_last_fcd_scan_time', $last_fcd_scan_time, true); + } + $next_fcd_scan_time = strtotime("+".abs($fcd_scan_frequency).$interval, $last_fcd_scan_time); + + return $next_fcd_scan_time; + } + + /** + * Get the last filechange detection data which is stored in the special file. + * + * @global AIO_WP_Security $aio_wp_security + * @return bool|array - false on failure, array on success + */ + public static function get_fcd_data() { + // phpcs:disable WordPress.WP.AlternativeFunctions -- Silence wp_filesystem method suggestion. We cannot use that method. + global $aio_wp_security; + $aiowps_backup_dir = WP_CONTENT_DIR.'/'.AIO_WP_SECURITY_BACKUPS_DIR_NAME; + + $fcd_filename = $aio_wp_security->configs->get_value('aiowps_fcd_filename'); + if (empty($fcd_filename)) { + // means that we haven't done a scan before, or, + // the fcd file containing the results doesn't exist + $random_suffix = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(10); + $fcd_filename = 'aiowps_fcd_data_' . $random_suffix; + $aio_wp_security->configs->set_value('aiowps_fcd_filename', $fcd_filename, true); + } + $results_file = $aiowps_backup_dir. '/'. $fcd_filename; + + if (!is_file($results_file)) { + if (is_dir($results_file)) { + $new_dir_name = $results_file . '_backup'; + rename($results_file, $new_dir_name); //Rename the folder to create backup of the folder. This condition should not really happen, but if it does (user sets some non-sensible value), then it's better to not nuke the existing folder + } + $fp = @fopen($results_file, 'w'); //open for write - will create file if doesn't exist + return array(); + } + + if (empty(filesize($results_file))) { + return array(); // if newly created file return empty array + } + + $fp = @fopen($results_file, 'r'); //open for read and write - will create file if doesn't exist + if (false === $fp) { + // Error + $aio_wp_security->debug_logger->log_debug(__METHOD__ . " - fopen returned false when opening fcd data file"); + return false; + } + + $contents = fread($fp, filesize($results_file)); + fclose($fp); + if (false === $contents) { + // Error + $aio_wp_security->debug_logger->log_debug(__METHOD__ . " - fread returned false when reading fcd data file"); + return false; + } else { + + $fcd_file_contents = json_decode($contents, true); + if (isset($fcd_file_contents['file_scan_data'])) { + return $fcd_file_contents; + } else { + return array(); + } + + } + + // phpcs:enable WordPress.WP.AlternativeFunctions -- Silence wp_filesystem method suggestion. We cannot use that method. + } + + /** + * Recursively scan the entire $start_dir directory and return file size + * and last modified date of every regular file. Ignore files and file + * types specified in file scanner settings. + * + * @global AIO_WP_Security $aio_wp_security + * @param string $start_dir + * @return array + */ + public function do_file_change_scan($start_dir = ABSPATH) { + global $aio_wp_security; + $filescan_data = array(); + // Iterator key is absolute file path, iterator value is SplFileInfo object, + // iteration skips '..' and '.' records, because we're not interested in directories. + $dit = new RecursiveDirectoryIterator($start_dir, FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS); + $rit = new RecursiveIteratorIterator($dit, RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD); + + // Grab files/directories to skip + $files_to_skip = AIOWPSecurity_Utility::explode_trim_filter_empty($aio_wp_security->configs->get_value('aiowps_fcd_exclude_files')); + // Grab (lowercased) file types to skip + $file_types_to_skip = AIOWPSecurity_Utility::explode_trim_filter_empty(strtolower($aio_wp_security->configs->get_value('aiowps_fcd_exclude_filetypes'))); + + $start_dir_length = strlen($start_dir); + + foreach ($rit as $filename => $fileinfo) { + + if (!file_exists($filename) || is_dir($filename)) { + continue; // if file doesn't exist or is a directory move on to next iteration + } + + if ($fileinfo->getFilename() == 'wp-security-log-cron-job.txt' || $fileinfo->getFilename() == 'wp-security-log.txt') { + continue; // Skip AIOS log files + } + + // Let's omit any file types from the scan which were specified in the settings if necessary + if (!empty($file_types_to_skip)) { + //$current_file_ext = strtolower($fileinfo->getExtension()); //getExtension() only available on PHP 5.3.6 or higher + $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); + if (in_array($ext, $file_types_to_skip)) { + continue; + } + } + + // Let's omit specific files or directories from the scan which were specified in the settings + if (!empty($files_to_skip)) { + + $skip_this = false; + foreach ($files_to_skip as $f_or_dir) { + // Expect files/dirs to be specified relatively to $start_dir, + // so start searching at $start_dir_length offset. + if (strpos($filename, $f_or_dir, $start_dir_length) !== false) { + $skip_this = true; + break; // ! + } + } + if ($skip_this) { + continue; + } + } + + $filescan_data[$filename] = array( + 'last_modified' => $fileinfo->getMTime(), + 'filesize' => $fileinfo->getSize(), + ); + + } + return $filescan_data; + } + + public function compare_scan_data($last_scan_data, $new_scanned_data) { + // Identify new files added: get all files which are in the new scan but not present in the old scan + $files_added = @array_diff_key($new_scanned_data, $last_scan_data); + // Identify files deleted: get all files which are in the old scan but not present in the new scan + $files_removed = @array_diff_key($last_scan_data, $new_scanned_data); + // Identify existing files: get all files which are in new scan, but were not added + $files_kept = @array_diff_key($new_scanned_data, $files_added); + + $files_changed = array(); + + // Loop through existing files and determine, if they have been changed + foreach ($files_kept as $filename => $new_scan_meta) { + $last_scan_meta = $last_scan_data[$filename]; + // Check filesize and last_modified values + if (($new_scan_meta['last_modified'] !== $last_scan_meta['last_modified']) || ($new_scan_meta['filesize'] !== $last_scan_meta['filesize'])) { + $files_changed[$filename] = $new_scan_meta; + } + } + + // Create single array of all changes + return array( + 'files_added' => $files_added, + 'files_removed' => $files_removed, + 'files_changed' => $files_changed, + ); + } + + public static function get_file_change_summary($scan_result) { + $scan_summary = ""; + if (!empty($scan_result['files_added'])) { + //Output of files added + $scan_summary .= "\r\n".__('The following files were added to your host', 'all-in-one-wp-security-and-firewall').":\r\n"; + foreach ($scan_result['files_added'] as $key => $value) { + $scan_summary .= "\r\n".$key.' ('.__('modified on:', 'all-in-one-wp-security-and-firewall'). ' ' . AIOWPSecurity_Utility::convert_timestamp($value['last_modified']).')'; + } + $scan_summary .= "\r\n======================================\r\n"; + } + if (!empty($scan_result['files_removed'])) { + //Output of files removed + $scan_summary .= "\r\n".__('The following files were removed from your host', 'all-in-one-wp-security-and-firewall').":\r\n"; + foreach ($scan_result['files_removed'] as $key => $value) { + $scan_summary .= "\r\n".$key.' ('.__('modified on:', 'all-in-one-wp-security-and-firewall'). ' ' . AIOWPSecurity_Utility::convert_timestamp($value['last_modified']).')'; + } + $scan_summary .= "\r\n======================================\r\n"; + } + + if (!empty($scan_result['files_changed'])) { + //Output of files changed + $scan_summary .= "\r\n".__('The following files were changed on your host', 'all-in-one-wp-security-and-firewall').":\r\n"; + foreach ($scan_result['files_changed'] as $key => $value) { + $scan_summary .= "\r\n".$key.' ('.__('modified on:', 'all-in-one-wp-security-and-firewall'). ' ' . AIOWPSecurity_Utility::convert_timestamp($value['last_modified']).')'; + } + $scan_summary .= "\r\n======================================\r\n"; + } + + return $scan_summary; + } + + /** + * Saves file change detection data into a special file + * + * @global AIO_WP_Security $aio_wp_security + * @param type $scanned_data + * @param type $scan_result + * @return boolean + */ + public function save_fcd_data($scanned_data, $scan_result = array()) { + global $aio_wp_security; + + $date_time = current_time('mysql'); + $data = array('date_time' => $date_time, 'file_scan_data' => $scanned_data, 'last_scan_result' => $scan_result); + + $fcd_filename = $aio_wp_security->configs->get_value('aiowps_fcd_filename'); + $aiowps_backup_dir = WP_CONTENT_DIR.'/'.AIO_WP_SECURITY_BACKUPS_DIR_NAME; + + if (!AIOWPSecurity_Utility_File::create_dir($aiowps_backup_dir)) { + $aio_wp_security->debug_logger->log_debug(__METHOD__ . " - Creation of DB backup directory failed!", 4); + return false; + } + + // phpcs:disable WordPress.WP.AlternativeFunctions -- Silence wp_filesystem method suggestion. We cannot use that method. + $results_file = $aiowps_backup_dir. '/'. $fcd_filename; + $fp = fopen($results_file, 'w'); + fwrite($fp, json_encode($data)); + fclose($fp); + // phpcs:enable WordPress.WP.AlternativeFunctions -- Silence wp_filesystem method suggestion. We cannot use that method. + + return true; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-firewall-resource-unavailable.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-firewall-resource-unavailable.php new file mode 100755 index 00000000..923b1ec9 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-firewall-resource-unavailable.php @@ -0,0 +1,74 @@ +resource = $resource; + do_action('aios_firewall_unavailable_resource', $this->resource); + } + + /** + * Handles call operation on an unavailable firewall resource. + * + * @param string $name + * @param array $arguments + * + * @return void + */ + public function __call($name, $arguments) { + do_action('aios_firewall_unavailable_resource_method_call', $this->resource, $name, $arguments); + } + + /** + * Handles call operation on an unavailable static firewall resource. + * + * @param string $name + * @param array $arguments + * + * @return void + */ + public static function __callStatic($name, $arguments) { + do_action('aios_firewall_unavailable_resource_static_method_call', $name, $arguments); + } + + /** + * Handles get operation on an unavailable firewall resource. + * + * @param string $name + * + * @return void + */ + public function __get($name) { + do_action('aios_firewall_unavailable_resource_get_property', $this->resource, $name); + } + + /** + * Handles set operation on an unavailable firewall resource. + * + * @param string $name + * @param mixed $value + * + * @return void + */ + public function __set($name, $value) { + do_action('aios_firewall_unavailable_resource_set_property', $this->resource, $name, $value); + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-firewall-resource.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-firewall-resource.php new file mode 100755 index 00000000..a00df11a --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-firewall-resource.php @@ -0,0 +1,53 @@ +configs->get_value('aiowps_disable_xmlrpc_pingback_methods')) { + add_filter('xmlrpc_methods', array($this, 'aiowps_disable_xmlrpc_pingback_methods')); + add_filter('wp_headers', array($this, 'aiowps_remove_x_pingback_header')); + } + + if ('1' == $aio_wp_security->configs->get_value('aiowps_disable_rss_and_atom_feeds')) { + add_action('do_feed', array($this, 'block_feed'), 1); + add_action('do_feed_rdf', array($this, 'block_feed'), 1); + add_action('do_feed_rss', array($this, 'block_feed'), 1); + add_action('do_feed_rss2', array($this, 'block_feed'), 1); + add_action('do_feed_atom', array($this, 'block_feed'), 1); + add_action('do_feed_rss2_comments', array($this, 'block_feed'), 1); + add_action('do_feed_atom_comments', array($this, 'block_feed'), 1); + + remove_action('wp_head', 'feed_links_extra', 3); + remove_action('wp_head', 'feed_links', 2); + } + + // Check permanent block list and block if applicable (ie, do PHP blocking) + if (!is_user_logged_in()) { + AIOWPSecurity_Blocking::check_visitor_ip_and_perform_blocking(); + } + + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_spambot_detecting') && '0' == $aio_wp_security->configs->get_value('aiowps_spam_comments_should')) { + add_action('pre_comment_on_post', array($this, 'spam_detecting_and_process_comments_discard'), 10, 2); //this hook gets fired before comment is added + } + + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_spambot_detecting') && '1' == $aio_wp_security->configs->get_value('aiowps_spam_comments_should')) { + add_filter('pre_comment_approved', array($this, 'spam_detecting_and_process_comments_mark_spam'), 10, 2); //this hook filters a comments approval status before it is set + } + + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_autoblock_spam_ip')) { + add_action('comment_post', array($this, 'spam_detect_process_comment_post'), 10, 2); //this hook gets fired just after comment is saved to DB + add_action('transition_comment_status', array($this, 'process_transition_comment_status'), 10, 3); //this hook gets fired when a comment's status changes + } + + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_rename_login_page')) { + add_action('widgets_init', array($this, 'remove_standard_wp_meta_widget')); + add_filter('retrieve_password_message', array($this, 'decode_reset_pw_msg'), 10, 4); //Fix for non decoded html entities in password reset link + // Gravity form preview exposed renamed login page when called auth_redirect + add_filter('login_url', array($this, 'login_url_reauth_redirect'), 10, 3); + } + + if (AIOWPSecurity_Utility_Permissions::has_manage_cap() && is_admin()) { + if ('1' == $aio_wp_security->configs->get_value('aios_google_recaptcha_invalid_configuration')) { + add_action('all_admin_notices', array($this, 'google_recaptcha_notice')); + } + + if (is_main_site() && is_super_admin()) { + add_action('all_admin_notices', array($this, 'do_firewall_notice')); + add_action('admin_post_aiowps_firewall_setup', array(AIOWPSecurity_Firewall_Setup_Notice::get_instance(), 'handle_setup_form')); + add_action('admin_post_aiowps_firewall_downgrade', array(AIOWPSecurity_Firewall_Setup_Notice::get_instance(), 'handle_downgrade_protection_form')); + add_action('admin_post_aiowps_firewall_setup_dismiss', array(AIOWPSecurity_Firewall_Setup_Notice::get_instance(), 'handle_dismiss_form')); + } + } + + /** + * Send X-Frame-Options: SAMEORIGIN in HTTP header + */ + if ('1' == $aio_wp_security->configs->get_value('aiowps_prevent_site_display_inside_frame')) { + add_action('template_redirect', 'send_frame_options_header'); + } + + if ('1' == $aio_wp_security->configs->get_value('aiowps_remove_wp_generator_meta_info')) { + add_filter('the_generator', array($this,'remove_wp_generator_meta_info')); + add_filter('style_loader_src', array($this,'remove_wp_css_js_meta_info')); + add_filter('script_loader_src', array($this,'remove_wp_css_js_meta_info')); + } + + // For the cookie based brute force prevention feature + // Already logged in user should not redirected to brute_force_redirect_url in any case so added condition !is_user_logged_in() + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention')) { + $bfcf_secret_word = $aio_wp_security->configs->get_value('aiowps_brute_force_secret_word'); + if (isset($_GET[$bfcf_secret_word])) { + AIOWPSecurity_Utility_IP::check_login_whitelist_and_forbid(); + + // If URL contains secret word in query param then set cookie and then redirect to the login page + AIOWPSecurity_Utility::set_cookie_value(AIOWPSecurity_Utility::get_brute_force_secret_cookie_name(), AIOS_Helper::get_hash($bfcf_secret_word)); + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_rename_login_page') && !is_user_logged_in()) { + $login_url = home_url((get_option('permalink_structure') ? '' : '?') . $aio_wp_security->configs->get_value('aiowps_login_page_slug')); + AIOWPSecurity_Utility::redirect_to_url($login_url); + } elseif (!is_user_logged_in()) { + AIOWPSecurity_Utility::redirect_to_url(AIOWPSEC_WP_URL.'/wp-admin'); + } + } + } + // Stop users enumeration feature + if (1 == $aio_wp_security->configs->get_value('aiowps_prevent_users_enumeration')) { + include_once(AIO_WP_SECURITY_PATH.'/other-includes/wp-security-stop-users-enumeration.php'); + add_filter('rest_request_before_callbacks', array($this, 'rest_request_before_callbacks'), 10, 1); + add_filter('oembed_response_data', array($this, 'oembed_response_data'), 10, 1); + } + + // REST API security + if ($aio_wp_security->configs->get_value('aiowps_disallow_unauthorized_rest_requests') == 1) { + add_action('rest_api_init', array($this, 'check_rest_api_requests'), 10, 1); + } + + // For user unlock request feature + if (isset($_POST['aiowps_unlock_request']) || isset($_POST['aiowps_wp_submit_unlock_request'])) { + nocache_headers(); + remove_action('wp_head', 'head_addons', 7); + include_once(AIO_WP_SECURITY_PATH.'/other-includes/wp-security-unlock-request.php'); + exit(); + } + + if (isset($_GET['aiowps_auth_key'])) { + //If URL contains unlock key in query param then process the request + $unlock_key = sanitize_text_field($_GET['aiowps_auth_key']); + AIOWPSecurity_User_Login::process_unlock_request($unlock_key); + } + + // For honeypot feature + if (isset($_POST['aio_special_field'])) { + $special_field_value = sanitize_text_field($_POST['aio_special_field']); + if (!empty($special_field_value)) { + //This means a robot has submitted the login form! + //Redirect back to its localhost + AIOWPSecurity_Utility::redirect_to_url('http://127.0.0.1'); + } + } + + // For 404 IP lockout feature + if ($aio_wp_security->configs->get_value('aiowps_enable_404_IP_lockout') == '1') { + if (!is_user_logged_in() || !current_user_can('administrator')) { + $this->do_404_lockout_tasks(); + } + } + + + // For login CAPTCHA feature + if ($aio_wp_security->configs->get_value('aiowps_enable_login_captcha') == '1') { + if (!is_user_logged_in()) { + add_action('login_form', array($aio_wp_security->captcha_obj, 'insert_captcha_question_form')); + if (AIOWPSecurity_Utility::is_memberpress_plugin_active()) { + add_action('mepr-login-form-before-submit', array($aio_wp_security->captcha_obj, 'add_captcha_script')); + add_action('mepr-login-form-before-submit', array($aio_wp_security->captcha_obj, 'insert_captcha_question_form')); // for memberpress login form + } + } + } + + // For woo form CAPTCHA features + if ($aio_wp_security->configs->get_value('aiowps_enable_woo_login_captcha') == '1') { + if (!is_user_logged_in()) { + add_action('woocommerce_login_form', array($aio_wp_security->captcha_obj, 'insert_captcha_question_form')); + } + if (isset($_POST['woocommerce-login-nonce'])) { + add_filter('woocommerce_process_login_errors', array($this, 'aiowps_validate_woo_login_or_reg_captcha'), 10, 3); + } + } + + if ($aio_wp_security->configs->get_value('aiowps_enable_woo_register_captcha') == '1') { + if (!is_user_logged_in()) { + add_action('woocommerce_register_form', array($aio_wp_security->captcha_obj, 'insert_captcha_question_form')); + } + + if (isset($_POST['woocommerce-register-nonce'])) { + add_filter('woocommerce_process_registration_errors', array($this, 'aiowps_validate_woo_login_or_reg_captcha'), 10, 3); + } + } + + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_woo_checkout_captcha') && !is_user_logged_in()) { + add_action('woocommerce_after_checkout_billing_form', array($aio_wp_security->captcha_obj, 'insert_captcha_question_form')); + add_action('woocommerce_after_checkout_validation', array($this, 'aiowps_validate_woo_checkout_captcha'), 10, 2); + } + + if ($aio_wp_security->configs->get_value('aiowps_enable_woo_lostpassword_captcha') == '1') { + if (!is_user_logged_in()) { + add_action('woocommerce_lostpassword_form', array($aio_wp_security->captcha_obj, 'insert_captcha_question_form')); + } + if (isset($_POST['woocommerce-lost-password-nonce'])) { + add_action('lostpassword_post', array($this, 'process_woo_lost_password_form_post')); + } + } + + // For bbPress new topic form CAPTCHA + if ($aio_wp_security->configs->get_value('aiowps_enable_bbp_new_topic_captcha') == '1') { + if (!is_user_logged_in()) { + add_action('bbp_theme_before_topic_form_submit_wrapper', array($aio_wp_security->captcha_obj, 'insert_captcha_question_form')); + } + } + + // For custom login form CAPTCHA feature, ie, when wp_login_form() function is used to generate login form + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_custom_login_captcha') && !is_user_logged_in()) { + add_filter('login_form_middle', array($aio_wp_security->captcha_obj, 'insert_captcha_custom_login'), 10, 2); //For cases where the WP wp_login_form() function is used + add_filter('login_form_bottom', array($aio_wp_security->captcha_obj, 'add_captcha_script'), 20); + } + + // For password protected pages CAPTCHA feature + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_password_protected_captcha')) { + add_filter('the_password_form', array($aio_wp_security->captcha_obj, 'insert_captcha_password_protected')); + add_action('login_form_postpass', array($aio_wp_security->captcha_obj, 'validate_password_protected_password_form_with_captcha')); + } + + // For honeypot feature + if ($aio_wp_security->configs->get_value('aiowps_enable_login_honeypot') == '1') { + if (!is_user_logged_in()) { + add_action('login_form', array($this, 'insert_honeypot_hidden_field')); + } + } + + // For registration honeypot feature + if ($aio_wp_security->configs->get_value('aiowps_enable_registration_honeypot') == '1') { + if (!is_user_logged_in()) { + add_action('register_form', array($this, 'insert_honeypot_hidden_field')); + } + } + + // For disable application password feature hide generate password + if ('1' == $aio_wp_security->configs->get_value('aiowps_disable_application_password')) { + add_filter('wp_is_application_passwords_available', '__return_false'); + add_action('edit_user_profile', array($this, 'show_disabled_application_password_message')); + add_action('show_user_profile', array($this, 'show_disabled_application_password_message')); + + // Override the wp_die handler for app passwords were disabled. + if (!empty($_SERVER['SCRIPT_FILENAME']) && ABSPATH . 'wp-admin/authorize-application.php' == $_SERVER['SCRIPT_FILENAME']) { + add_filter('wp_die_handler', function () { + return function ($message, $title, $args) { + if ('Application passwords are not available.' == $message) { + $message = htmlspecialchars(__('Application passwords have been disabled by All-In-One Security plugin.', 'all-in-one-wp-security-and-firewall')); + } + _default_wp_die_handler($message, $title, $args); + }; + }, 10, 1); + } + } + + // For lost password CAPTCHA feature + if ($aio_wp_security->configs->get_value('aiowps_enable_lost_password_captcha') == '1') { + if (!is_user_logged_in()) { + add_action('lostpassword_form', array($aio_wp_security->captcha_obj, 'insert_captcha_question_form')); + add_action('lostpassword_post', array($this, 'process_lost_password_form_post')); + + if (AIOWPSecurity_Utility::is_memberpress_plugin_active()) { + add_action('mepr-forgot-password-form', array($aio_wp_security->captcha_obj, 'add_captcha_script')); + add_action('mepr-forgot-password-form', array($aio_wp_security->captcha_obj, 'insert_captcha_question_form')); // for memberpress forgot password form + add_filter('mepr-validate-forgot-password', array($aio_wp_security->captcha_obj, 'verify_memberpress_form')); // for memberpress forgot password form + } + } + } + + // For registration manual approval feature + if ($aio_wp_security->configs->get_value('aiowps_enable_manual_registration_approval') == '1') { + add_filter('wp_login_errors', array($this, 'modify_registration_page_messages'), 10, 2); + } + + // For registration page CAPTCHA feature + if (is_multisite()) { + $blog_id = get_current_blog_id(); + switch_to_blog($blog_id); + if ($aio_wp_security->configs->get_value('aiowps_enable_registration_page_captcha') == '1') { + if (!is_user_logged_in()) { + add_action('signup_extra_fields', array($this, 'insert_captcha_question_form_multi')); + //add_action('preprocess_signup_form', array($this, 'process_signup_form_multi')); + add_filter('wpmu_validate_user_signup', array($this, 'process_signup_form_multi')); + } + } + restore_current_blog(); + } else { + if ($aio_wp_security->configs->get_value('aiowps_enable_registration_page_captcha') == '1') { + if (!is_user_logged_in()) { + add_action('register_form', array($aio_wp_security->captcha_obj, 'insert_captcha_question_form')); + } + } + } + + if ($aio_wp_security->configs->get_value('aiowps_enable_registration_page_captcha') == '1') { + if (AIOWPSecurity_Utility::is_memberpress_plugin_active()) { + add_action('mepr-checkout-after-password-fields', array($aio_wp_security->captcha_obj, 'add_captcha_script')); + add_action('mepr-checkout-after-password-fields', array($aio_wp_security->captcha_obj, 'insert_captcha_question_form')); // for memberpress register form + add_filter('mepr-validate-signup', array($aio_wp_security->captcha_obj, 'verify_memberpress_form')); // for memberpress register form + } + } + + // For comment CAPTCHA feature or custom login form CAPTCHA + if (is_multisite()) { + $blog_id = get_current_blog_id(); + switch_to_blog($blog_id); + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_comment_captcha') && !is_user_logged_in()) { + add_action('comment_form_after_fields', array($aio_wp_security->captcha_obj, 'insert_captcha_question_form'), 1); + add_action('comment_form_after_fields', array($aio_wp_security->captcha_obj, 'add_captcha_script'), 10); + add_filter('preprocess_comment', array($this, 'process_comment_post')); + } + restore_current_blog(); + } else { + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_comment_captcha') && !is_user_logged_in()) { + add_action('comment_form_after_fields', array($aio_wp_security->captcha_obj, 'insert_captcha_question_form'), 1); + add_action('comment_form_after_fields', array($aio_wp_security->captcha_obj, 'add_captcha_script'), 10); + add_filter('preprocess_comment', array($this, 'process_comment_post')); + } + } + + // For BuddyPress registration CAPTCHA feature + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_bp_register_captcha')) { + add_action('bp_before_registration_submit_buttons', array($aio_wp_security->captcha_obj, 'insert_captcha_question_form')); + add_action('bp_before_registration_submit_buttons', array($aio_wp_security->captcha_obj, 'add_captcha_script'), 10); + add_action('bp_signup_validate', array($this, 'buddy_press_signup_validate_captcha')); + } + + // For 404 event logging + if ($aio_wp_security->configs->get_value('aiowps_enable_404_logging') == '1') { + add_action('template_redirect', array($this, 'check_404_event')); + } + + // For antibot post page set cookies. + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_spambot_detecting') && !is_user_logged_in()) { + if ('1' == $aio_wp_security->configs->get_value('aiowps_spambot_detect_usecookies')) { + add_action('template_redirect', array($this, 'post_antibot_cookie')); + } + add_filter('comment_form_submit_field', array($this, 'comment_form_submit_field'), 10, 1); + } + + // For delete readme.html and wp-config-sample.php. + if ('1' == $aio_wp_security->configs->get_value('aiowps_auto_delete_default_wp_files')) { + add_action('upgrader_process_complete', array($this, 'delete_unneeded_files_after_upgrade'), 10, 2); + } + + // filter php firewall templates array + add_filter('aiowps_modify_php_firewall_rules_template', array($this, 'filter_templates'), 10, 1); + + // For HTTP authentication. + if ('1' == $aio_wp_security->configs->get_value('aiowps_http_authentication_admin') || '1' == $aio_wp_security->configs->get_value('aiowps_http_authentication_frontend')) { + $this->http_authentication(); + } + + // for enforcing strong passwords + if ('1' == $aio_wp_security->configs->get_value('aiowps_enforce_strong_password')) { + wp_register_script('remove-weak-pw', AIO_WP_SECURITY_URL.'/js/remove-weak-pw.js', array('jquery'), AIO_WP_SECURITY_VERSION, true); + wp_enqueue_script('remove-weak-pw'); + } + + // For HIBP. + if ('1' == $aio_wp_security->configs->get_site_value('aiowps_hibp_user_profile_update')) { + add_action('user_profile_update_errors', 'AIOS_HIBP::user_profile_update_check', 1, 3); + } + + if ('1' == $aio_wp_security->configs->get_site_value('aiowps_http_password_reset')) { + add_action('validate_password_reset', 'AIOS_HIBP::password_reset_check', 1, 2); + } + + // For Upgrade unsafe HTTP calls. + if ('1' == $aio_wp_security->configs->get_site_value('aiowps_upgrade_unsafe_http_calls')) { + add_filter('http_request_reject_unsafe_urls', array($this, 'http_request_reject_unsafe_urls'), 10, 2); + } + + // Add more tasks that need to be executed at init time + + add_filter('aiowps_modify_captcha_settings_template', array($this, 'filter_captcha_settings_templates'), 10, 1); + } // end _construct() + + public function aiowps_disable_xmlrpc_pingback_methods($methods) { + unset($methods['pingback.ping']); + unset($methods['pingback.extensions.getPingbacks']); + return $methods; + } + + public function aiowps_remove_x_pingback_header($headers) { + unset($headers['X-Pingback']); + return $headers; + } + + /** + * Blocks feed by redirecting user to home url. + * + * @return Void + */ + public function block_feed() { + wp_redirect(home_url()); + } + + /** + * Spam detection and discard comment. + * + * @param int $comment_post_id + * + * @return void + */ + public function spam_detecting_and_process_comments_discard($comment_post_id) { + $is_comment_should_not_allowed = AIOWPSecurity_Comment::is_comment_spam_detected(); + if ($is_comment_should_not_allowed) { + $this->spam_discard_auto_block_ip(); + $comments = get_comments(array('number' => '1', 'post_id' => $comment_post_id)); + if ($comments) { + $loc = get_comment_link($comments[0]->comment_ID); + } else { + $loc = get_permalink($comment_post_id) . '#spam-comment-msg'; + } + wp_safe_redirect($loc); + exit; + } + } + + /** + * Block IP for spam discard after minimum comments reached. + * + * @return void + */ + public function spam_discard_auto_block_ip() { + global $aio_wp_security, $wpdb; + + if ('1' != $aio_wp_security->configs->get_value('aiowps_enable_autoblock_spam_ip')) return; + + AIOWPSecurity_Utility::event_logger('spam_discard'); + $comment_ip = AIOWPSecurity_Utility_IP::get_user_ip_address(); + $spam_count = $wpdb->get_var($wpdb->prepare("SELECT COUNT(id) FROM ".AIOWPSEC_TBL_EVENTS." WHERE ip_or_host = %s AND event_type=%s", $comment_ip, 'spam_discard')); + $min_comment_before_block = $aio_wp_security->configs->get_value('aiowps_spam_ip_min_comments_block'); + if (!empty($min_comment_before_block) && $spam_count > $min_comment_before_block) { + AIOWPSecurity_Blocking::add_ip_to_block_list($comment_ip, 'spam_discard'); + } + } + + /** + * Spam detection and mark as spam comment. + * + * @param string $approved + * + * @return string status + */ + public function spam_detecting_and_process_comments_mark_spam($approved) { + return AIOWPSecurity_Comment::is_comment_spam_detected() ? 'spam' : $approved; + } + + public function spam_detect_process_comment_post($comment_id, $comment_approved) { + if ("spam" === $comment_approved) { + $this->block_comment_ip($comment_id); + } + + } + + public function process_transition_comment_status($new_status, $old_status, $comment) { + if ('spam' == $new_status) { + $this->block_comment_ip($comment->comment_ID); + } + + } + + /** + * Will check auto-spam blocking settings and will add IP to blocked table accordingly + * + * @param int $comment_id + */ + public function block_comment_ip($comment_id) { + global $aio_wp_security, $wpdb; + $comment_obj = get_comment($comment_id); + $comment_ip = $comment_obj->comment_author_IP; + //Get number of spam comments from this IP + $sql = $wpdb->prepare("SELECT * FROM $wpdb->comments + WHERE comment_approved = 'spam' + AND comment_author_IP = %s + ", $comment_ip); + $comment_data = $wpdb->get_results($sql, ARRAY_A); + $spam_count = count($comment_data); + $min_comment_before_block = $aio_wp_security->configs->get_value('aiowps_spam_ip_min_comments_block'); + if (!empty($min_comment_before_block) && $spam_count >= ($min_comment_before_block - 1)) { + AIOWPSecurity_Blocking::add_ip_to_block_list($comment_ip, 'spam'); + } + } + + public function remove_standard_wp_meta_widget() { + unregister_widget('WP_Widget_Meta'); + } + + public function remove_wp_generator_meta_info() { + return ''; + } + + /** + * This function removes wp meta info from style and script src + * + * @param string|null $src - the src for the style or script + * @return string + */ + public function remove_wp_css_js_meta_info($src) { + global $wp_version; + static $wp_version_hash = null; // Cache hash value for all function calls + + if (empty($src)) return ''; + + // Replace only version number of assets with WP version + if (strpos($src, 'ver=' . $wp_version) !== false) { + if (!$wp_version_hash) { + $wp_version_hash = wp_hash($wp_version); + } + // Replace version number with computed hash + $src = add_query_arg('ver', $wp_version_hash, $src); + } + return $src; + } + + public function do_404_lockout_tasks() { + global $aio_wp_security; + $redirect_url = $aio_wp_security->configs->get_value('aiowps_404_lock_redirect_url'); //This is the redirect URL for blocked users + + $visitor_ip = AIOWPSecurity_Utility_IP::get_user_ip_address(); + + $is_locked = AIOWPSecurity_Utility::check_locked_ip($visitor_ip, '404'); + + if ($is_locked) { + //redirect blocked user to configured URL + AIOWPSecurity_Utility::redirect_to_url($redirect_url); + } else { + //allow through + } + } + + public function insert_captcha_question_form_multi() { + global $aio_wp_security; + $default_captcha = $aio_wp_security->configs->get_value('aiowps_default_captcha'); + $aio_wp_security->captcha_obj->display_captcha_form($default_captcha); + } + + public function process_signup_form_multi($result) { + global $aio_wp_security; + // Check if CAPTCHA enabled + $verify_captcha = $aio_wp_security->captcha_obj->verify_captcha_submit(); + if (false === $verify_captcha) { + // wrong answer was entered + $result['errors']->add('generic', __('ERROR: Your answer was incorrect - please try again.', 'all-in-one-wp-security-and-firewall')); + } + return $result; + } + + /** + * This function echos a honeypot hidden field into login or register form + * + * @return void + */ + public function insert_honeypot_hidden_field() { + $honey_input = '

'; + $honey_input .= '

'; + echo $honey_input; + } + + /** + * Shows application password disabled message on user edit profile page. + * If logged user is admin showing the Change Setting option. + * + * @return void + */ + public function show_disabled_application_password_message() { + if (is_user_logged_in() && is_admin()) { + $disabled_message = '

'.__('Application passwords', 'all-in-one-wp-security-and-firewall').'

'; + $disabled_message .= ''; + $disabled_message .= ''; + $disabled_message .= ''; + $disabled_message .= ''; + $disabled_message .= ''; + $disabled_message .= ''; + $disabled_message .= ''; + $disabled_message .= ''; + echo $disabled_message; + } + } + + public function process_comment_post($comment) { + global $aio_wp_security; + if (is_user_logged_in()) { + return $comment; + } + + // Don't process CAPTCHA for comment replies inside admin menu + if (isset($_REQUEST['action']) && 'replyto-comment' == $_REQUEST['action'] && (check_ajax_referer('replyto-comment', '_ajax_nonce', false) || check_ajax_referer('replyto-comment', '_ajax_nonce-replyto-comment', false))) { + return $comment; + } + + // Don't do CAPTCHA for pingback/trackback + if ('' != $comment['comment_type'] && 'comment' != $comment['comment_type'] && 'review' != $comment['comment_type']) { + return $comment; + } + + $verify_captcha = $aio_wp_security->captcha_obj->verify_captcha_submit(); + if (false === $verify_captcha) { + //Wrong answer + wp_die(__('Error: You entered an incorrect CAPTCHA answer, please go back and try again.', 'all-in-one-wp-security-and-firewall')); + } else { + return($comment); + } + } + + /** + * Process the main Wordpress account lost password login form post + * Called by wp hook "lostpassword_post" + */ + public function process_lost_password_form_post() { + global $aio_wp_security; + + // Workaround - the WooCommerce lost password form also uses the same "lostpassword_post" hook. + // We don't want to process woo forms here so ignore if this is a woo lost password $_POST + if (!array_key_exists('woocommerce-lost-password-nonce', $_POST)) { + $verify_captcha = $aio_wp_security->captcha_obj->verify_captcha_submit(); + if (false === $verify_captcha) { + add_filter('allow_password_reset', array($this, 'add_lostpassword_captcha_error_msg')); + } + } + } + + public function add_lostpassword_captcha_error_msg() { + //Insert an error just before the password reset process kicks in + return new WP_Error('aiowps_captcha_error', __('ERROR: Your answer was incorrect - please try again.', 'all-in-one-wp-security-and-firewall')); + } + + public function check_404_event() { + if (is_404()) { + //This means a 404 event has occurred - let's log it! + AIOWPSecurity_Utility::event_logger('404'); + } + + } + + /** + * Deletes unneeded default WP files if they're regenerated after core upgrade. + * + * @param WP_Upgrader $upgrader + * @param array $hook_extra + * + * @return void + */ + public function delete_unneeded_files_after_upgrade($upgrader, $hook_extra) { + if (empty($hook_extra)) { + return; + } + + if (isset($hook_extra['action']) && 'update' == $hook_extra['action'] && isset($hook_extra['type']) && 'core' == $hook_extra['type']) { + AIOWPSecurity_Utility::delete_unneeded_default_files(); + } + } + + /** + * Sends WWW-Authenticate header for frontend or admin protection according to user configuration. + * + * @global AIO_WP_Security $aio_wp_security + * + * @return void + */ + private function http_authentication() { + global $aio_wp_security; + + if (defined('AIOS_DISABLE_HTTP_AUTHENTICATION') && AIOS_DISABLE_HTTP_AUTHENTICATION) return; + + $request_uri = isset($_SERVER['REQUEST_URI']) ? wp_parse_url(urldecode($_SERVER['REQUEST_URI'])) : ''; + + $request_path = isset($request_uri['path']) ? $request_uri['path'] : ''; + $request_query = isset($request_uri['query']) ? $request_uri['query'] : ''; + + $non_logged_in_admin_ajax_request = !is_user_logged_in() && defined('DOING_AJAX') && DOING_AJAX; + + // Can't use defined('REST_REQUEST') && REST_REQUEST because REST_REQUEST isn't defined until after init. + $logged_in_rest_request = is_user_logged_in() && (1 === preg_match('/^\/'.rest_get_url_prefix().'(?:\/.*)?$/', $request_path) || 1 === preg_match('/^rest_route=.+$/', $request_query)); + + $is_login_page = 'wp-login.php' == $GLOBALS['pagenow']; + + if ('cli' == PHP_SAPI || (defined('WP_CLI') && WP_CLI)) { + // CLI + return; + } elseif ((is_admin() && !$non_logged_in_admin_ajax_request) || $logged_in_rest_request || $is_login_page) { + // Admin + if ('1' != $aio_wp_security->configs->get_value('aiowps_http_authentication_admin')) { + return; + } + } else { + // Frontend + if ('1' != $aio_wp_security->configs->get_value('aiowps_http_authentication_frontend')) { + return; + } + } + + $username = $aio_wp_security->configs->get_value('aiowps_http_authentication_username'); + $password = $aio_wp_security->configs->get_value('aiowps_http_authentication_password'); + + // Check that the user hasn't already logged in with credentials. + if (!(isset($_SERVER['PHP_AUTH_USER']) && $_SERVER['PHP_AUTH_USER'] == $username && isset($_SERVER['PHP_AUTH_PW']) && $_SERVER['PHP_AUTH_PW'] == $password)) { + header('WWW-Authenticate: Basic charset="UTF-8"'); + header('HTTP/1.0 401 Unauthorized'); + + // Show failure message when the user clicks on the cancel button of the login prompt. + $aiowps_failure_message = $aio_wp_security->configs->get_value('aiowps_http_authentication_failure_message'); + $aiowps_failure_message_raw = html_entity_decode($aiowps_failure_message, ENT_COMPAT, 'UTF-8'); + echo $aiowps_failure_message_raw; + exit; + } + } + + /** + * Filters whether to pass URLs through wp_http_validate_url() in an HTTP request based on whether the url is in the url exceptions config. + * + * @global AIO_WP_Security $aio_wp_security + * + * @param bool $pass_url Whether to pass URLs through wp_http_validate_url(). Default false. + * @param string $url The request URL. + * + * @return bool + */ + public function http_request_reject_unsafe_urls($pass_url, $url) { + global $aio_wp_security; + + if ($pass_url) { + return true; + } + + $parsed_url = parse_url($url); // phpcs:ignore WordPress.WP.AlternativeFunctions.parse_url_parse_url -- Using the same function as WordPress in order to not preclude URLs that would be allowed by WordPress. + + if (empty($parsed_url['scheme'])) { // The same weak sanity check used by the WordPress wp_remote_* functions. + return false; + } + + if (empty($parsed_url['host']) || in_array($parsed_url['host'], array('localhost', '127.0.0.1', '[::1]'))) { + return false; + } + + $upgrade_unsafe_http_calls_url_exceptions = $aio_wp_security->configs->get_site_value('aiowps_upgrade_unsafe_http_calls_url_exceptions'); + + if (!empty($upgrade_unsafe_http_calls_url_exceptions)) { + foreach (preg_split('/\R/', $upgrade_unsafe_http_calls_url_exceptions) as $exempt_url) { + $exempt_url = sanitize_url($exempt_url); + + if (empty($exempt_url)) { + continue; + } + + if (0 === strpos($exempt_url, '#')) { + continue; + } + + if ($url === $exempt_url) { + return false; + } + } + } + + return true; + } + + public function buddy_press_signup_validate_captcha() { + global $bp, $aio_wp_security; + // Check CAPTCHA if required + $verify_captcha = $aio_wp_security->captcha_obj->verify_captcha_submit(); + if (false === $verify_captcha) { + // wrong answer was entered + $bp->signup->errors['aiowps-captcha-answer'] = __('Your CAPTCHA answer was incorrect - please try again.', 'all-in-one-wp-security-and-firewall'); + } + return; + } + + public function aiowps_validate_woo_login_or_reg_captcha($errors) { + global $aio_wp_security; + $locked = $aio_wp_security->user_login_obj->check_locked_user(); + if (!empty($locked)) { + $errors->add('authentication_failed', __('ERROR: Your IP address is currently locked please contact the administrator!', 'all-in-one-wp-security-and-firewall')); + return $errors; + } + + $verify_captcha = $aio_wp_security->captcha_obj->verify_captcha_submit(); + if (false === $verify_captcha) { + // wrong answer was entered + $errors->add('authentication_failed', __('ERROR: Your answer was incorrect - please try again.', 'all-in-one-wp-security-and-firewall')); + } + return $errors; + + } + + /** + * Process the WooCommerce checkout validation + * Called by WooCommerce hook "woocommerce_after_checkout_validation" + * + * @param array $data An array of posted data + * @param WP_ERROR $errors Validation errors + */ + public function aiowps_validate_woo_checkout_captcha($data, $errors) { + global $aio_wp_security; + $locked = $aio_wp_security->user_login_obj->check_locked_user(); + if (!empty($locked)) { + /* translators: %s: Error notification with strong HTML tag. */ + $errors->add('authentication_failed', sprintf(__('%s: Your IP address is currently locked.', 'all-in-one-wp-security-and-firewall') . ' ' . __('Please contact the administrator.', 'all-in-one-wp-security-and-firewall'), '' . __('ERROR', 'all-in-one-wp-security-and-firewall') . '')); + return $errors; + } + + $verify_captcha = $aio_wp_security->captcha_obj->verify_captcha_submit(); + if (false === $verify_captcha) { + // wrong answer was entered + /* translators: %s: Error notification with strong HTML tag. */ + $errors->add('authentication_failed', sprintf(__('%s: Your answer was incorrect - please try again.', 'all-in-one-wp-security-and-firewall'), '' . __('ERROR', 'all-in-one-wp-security-and-firewall') . '')); + } + return $errors; + + } + + /** + * Process the WooCommerce lost password login form post + * Called by wp hook "lostpassword_post" + */ + public function process_woo_lost_password_form_post() { + global $aio_wp_security; + + if (isset($_POST['woocommerce-lost-password-nonce'])) { + $verify_captcha = $aio_wp_security->captcha_obj->verify_captcha_submit(); + if (false === $verify_captcha) { + add_filter('allow_password_reset', array($this, 'add_lostpassword_captcha_error_msg')); + } + } + } + + /** + * Displays a notice message if the entered recatcha site key is wrong. + */ + public function google_recaptcha_notice() { + global $aio_wp_security; + + if (($aio_wp_security->is_admin_dashboard_page() || $aio_wp_security->is_plugin_admin_page() || $aio_wp_security->is_aiowps_admin_page()) && !$aio_wp_security->is_aiowps_google_recaptcha_tab_page()) { + $recaptcha_tab_url = 'admin.php?page='.AIOWPSEC_BRUTE_FORCE_MENU_SLUG.'&tab=login-captcha'; + echo '

'; + /* translators: %s: Admin Dashboard > WP Security > Brute Force > Login CAPTCHA Tab Link */ + printf(__('Your Google reCAPTCHA configuration is invalid.', 'all-in-one-wp-security-and-firewall').' '.__('Please enter the correct reCAPTCHA keys %s to use the Google reCAPTCHA feature.', 'all-in-one-wp-security-and-firewall'), ''.__('here', 'all-in-one-wp-security-and-firewall').''); + echo '

'; + } + } + + /** + * This is a fix for cases when the password reset URL in the email was not decoding all html entities properly + * + * @param string $message + * @return string + */ + public function decode_reset_pw_msg($message) { + $message = html_entity_decode($message); + return $message; + } + + public function modify_registration_page_messages($errors) { + if (isset($_GET['checkemail']) && 'registered' == $_GET['checkemail']) { + if (is_wp_error($errors)) { + $errors->remove('registered'); + $pending_approval_msg = __('Your registration is pending approval.', 'all-in-one-wp-security-and-firewall'); + $pending_approval_msg = apply_filters('aiowps_pending_registration_message', $pending_approval_msg); + $errors->add('registered', $pending_approval_msg, array('registered' => 'message')); + } + } + return $errors; + } + + /** + * Checks for REST API requests + * Below uses the "rest_api_init" action hook to check for REST requests. + * It will block "unauthorized" requests whilst allowing genuine requests. + * REST route will not be blocked if route is whitelisted or user is logged in and user role is allowed. + * + * @return void + */ + public function check_rest_api_requests() { + global $aio_wp_security; + + $is_whitelisted_route = false; + $rest_route = AIOWPSecurity_Utility::get_rest_route(); + + if (empty($rest_route)) return; //rest_api_init is called getting rest server for non rest endpoint. example /wp-admin/post-new.php. WordPress 6.5.0 has wp_is_serving_rest_request we can not use. + + $aios_whitelisted_rest_routes = apply_filters('aios_whitelisted_rest_routes', $aio_wp_security->configs->get_value('aios_whitelisted_rest_routes')); + foreach ($aios_whitelisted_rest_routes as $whitelisted_rest_route) { + $whitelisted_rest_route = preg_quote($whitelisted_rest_route, '/'); + // The 'wc/' rest route to match for white listed 'wc' not the 'wc-admin/' or other having wc + if (preg_match('/^'.$whitelisted_rest_route.'\//i', $rest_route)) { + $is_whitelisted_route = true; + } + } + + $rest_user = wp_get_current_user(); + $is_disallowed_role = !empty($rest_user->roles) && !empty(array_intersect($rest_user->roles, $aio_wp_security->configs->get_value('aios_roles_disallowed_rest_requests'))) ? true : false; + + if (!$is_whitelisted_route && (empty($rest_user->ID) || $is_disallowed_role)) { + $error_message = apply_filters('aiowps_rest_api_error_message', __('You are not authorized to perform this action.', 'all-in-one-wp-security-and-firewall')); + $aio_wp_security->debug_logger->log_debug('REST API request '.$rest_route.' was blocked, If this was unintentional whitelist "' . explode('/', $rest_route)[0] . '" the REST route.', 4); + wp_die($error_message, '', 403); + } + } + + /** + * Shows the firewall notice + * + * @return void + */ + public function do_firewall_notice() { + + $firewall_setup = AIOWPSecurity_Firewall_Setup_Notice::get_instance(); + $firewall_setup->start_firewall_setup(); + + } + + /** + * Called by the WP filter rest_request_before_callbacks + * + * @param WP_REST_Response $response + * + * @return WP_REST_Response|WP_Error $response + */ + public function rest_request_before_callbacks($response) { + $rest_route = !empty($_GET['rest_route']) ? $_GET['rest_route'] : (empty($_SERVER['REQUEST_URI']) ? '' : (string) parse_url(urldecode($_SERVER['REQUEST_URI']), PHP_URL_PATH)); + $rest_route = trim($rest_route, '/'); + if ('' != $rest_route && !current_user_can('edit_others_posts')) { + if (preg_match('/wp\/v2\/users$/i', $rest_route)) { + $error = new WP_Error('aios_user_lists_forbidden', __('Listing users is forbidden.', 'all-in-one-wp-security-and-firewall'), array('status' => 403)); + $response = rest_ensure_response($error); + } elseif (preg_match('/wp\/v2\/users\/+(\d+)$/i', $rest_route, $matches)) { + $id = empty($matches) ? 0 : (int) $matches[1]; + if (get_current_user_id() !== $id) { + $error = new WP_Error('aios_user_details_forbidden', __('Accessing user details is forbidden.', 'all-in-one-wp-security-and-firewall'), array('status' => 403)); + $response = rest_ensure_response($error); + } + } + } + return $response; + } + + /** + * Called by the WP filter oembed_response_data + * + * @param Array $data + * + * @return Array $data + */ + public function oembed_response_data($data) { + unset($data['author_name']); + unset($data['author_url']); + return $data; + } + + /** + * Sets the antibot cookie for post page comment form + * + * @return void + */ + public function post_antibot_cookie() { + if (is_single()) { + AIOWPSecurity_Comment::insert_antibot_keys_in_cookie(); + } + } + + /** + * Sets the hidden fields html code for post page comment form + * + * @param string $submit_field HTML markup for the submit field + * + * @return string + */ + public function comment_form_submit_field($submit_field) { + return $submit_field . " " . AIOWPSecurity_Comment::insert_antibot_keys_in_comment_form(); + } + + /** + * Filters the captcha settings templates based on specific conditions. + * + * This function checks if certain conditions (like login lockdown) are active, and filters the templates accordingly. + * If a template contains a display condition callback, it ensures the callback is callable and invokes it to determine + * whether the template should be included in the result. + * + * @param array $templates An array of captcha setting templates to filter. + * + * @return array The filtered array of captcha setting templates. + */ + public function filter_captcha_settings_templates($templates) { + global $aio_wp_security; + + if (empty($templates) || $aio_wp_security->is_login_lockdown_by_const()) return array(); + + return $this->filter_templates($templates); + } + + + /** + * Filters the provided templates array based on a specified callback condition. + * + * This function applies a filter to the input templates array, checking for each template + * if a 'display_condition_callback' is set and callable. If the condition passes, the template is retained. + * + * @param array $templates An array of templates to filter. Each template should have a 'display_condition_callback' key. + * + * @return array Filtered array of templates where the 'display_condition_callback' is valid. + */ + public function filter_templates($templates) { + if (empty($templates)) return array(); + + return array_filter($templates, function ($template) { + return AIOWPSecurity_Utility::apply_callback_filter($template, 'display_condition_callback'); + }); + } + + /** + * This filter stops exposed renamed login URL using auth_redirect + * + * @param string|null $login_url The login URL. Not HTML-encoded. + * @param string $redirect The path to redirect to on login, if supplied. + * @param bool $force_reauth Whether to force reauthorization, even if a cookie is present. + * + * @return string The filtered login URL. + */ + public function login_url_reauth_redirect($login_url, $redirect, $force_reauth) { + // Ensure $login_url is a string to avoid deprecation warnings. + $login_url = isset($login_url) ? $login_url : ''; + + if (true === $force_reauth && !empty($redirect)) { + wp_die( + esc_html__('You do not have permission to access this page.', 'all-in-one-wp-security-and-firewall') . ' ' . + esc_html__('Please log in and try again.', 'all-in-one-wp-security-and-firewall'), + 403 + ); + } + + return $login_url; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-helper.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-helper.php new file mode 100755 index 00000000..767875f1 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-helper.php @@ -0,0 +1,345 @@ +::' + * @return string + */ + public static function get_firewall_rule_location($rule) { + //normalise key + $rule = strtolower($rule); + + $basic_firewall = array( + 'completely block xmlrpc::general' => 'page=aiowpsec_firewall', + ); + $additional_firewall = array( + 'advanced character filter::general' => 'page=aiowpsec_firewall&tab=additional-firewall', + 'bad query strings::general' => 'page=aiowpsec_firewall&tab=additional-firewall', + 'proxy comment posting::general' => 'page=aiowpsec_firewall&tab=additional-firewall', + ); + $bruteforce = array( + 'cookie based prevent bruteforce::bruteforce' => 'page=aiowpsec_brute_force&tab=cookie-based-brute-force-prevention', + ); + $blacklist = array( + 'blocked ips::blacklist' => 'page=aiowpsec_blacklist', + 'blocked user agents::blacklist' => 'page=aiowpsec_blacklist', + ); + $firewall_6g = array( + 'block request methods::6g' => 'page=aiowpsec_firewall&tab=6g-firewall', + 'block query strings::6g' => 'page=aiowpsec_firewall&tab=6g-firewall', + 'block referrer strings::6g' => 'page=aiowpsec_firewall&tab=6g-firewall', + 'block request strings::6g' => 'page=aiowpsec_firewall&tab=6g-firewall', + 'block user-agents::6g' => 'page=aiowpsec_firewall&tab=6g-firewall', + ); + + // merge all the locations to one + $locations = array_merge($firewall_6g, $blacklist, $bruteforce, $basic_firewall, $additional_firewall); + return isset($locations[$rule]) ? $locations[$rule] : ''; + } + + /** + * Get server detected visitor IP Address. + * + * @return String visitor IP Address. + */ + public static function get_server_detected_user_ip_address() { + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + + // check if user configured custom IP retrieval method + $ip_method_id = empty($aiowps_firewall_config) ? '' : $aiowps_firewall_config->get_value('aios_ip_retrieve_method'); + + $visitor_ip = ''; + $ip_retrieve_methods = AIOS_Abstracted_Ids::get_ip_retrieve_methods(); + + if (empty($ip_method_id) || !isset($ip_retrieve_methods[$ip_method_id])) { + $ip_method_id = 0; + } + + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- WordPress API cannot be used here as it's loaded independently of WordPress + $visitor_ip = isset($_SERVER[$ip_retrieve_methods[$ip_method_id]]) ? $_SERVER[$ip_retrieve_methods[$ip_method_id]] : ''; + + // Check if multiple IPs were given - these will be present as comma-separated list + if (preg_match('/^([^,]+),/', $visitor_ip, $matches)) $visitor_ip = $matches[1]; + + // Now remove port portion if ipv4 address with port, for ipv6 it was making issue so using fiter_var valid ip checked first. + if (!filter_var($visitor_ip, FILTER_VALIDATE_IP) && preg_match('/(.+):\d+$/', $visitor_ip, $matches)) $visitor_ip = $matches[1]; + + if (!filter_var($visitor_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && !filter_var($visitor_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- WordPress API cannot be used here as it's loaded independently of WordPress + $visitor_ip = empty($_SERVER['REMOTE_ADDR']) ? '' : $_SERVER['REMOTE_ADDR']; + } + + return $visitor_ip; + } + + /** + * Get user IP Address. + * + * @return string User IP Address. + */ + public static function get_user_ip_address() { + static $visitor_ip; + if (isset($visitor_ip)) { + //already set in the page request + return $visitor_ip; + } + + $visitor_ip = self::get_server_detected_user_ip_address(); + + if (in_array($visitor_ip, array('', '127.0.0.1', '::1'))) { + $external_ip_address = self::get_external_ip_address(); + if (false != $external_ip_address) { + $visitor_ip = $external_ip_address; + } + } + + return $visitor_ip; + } + + /** + * Check user IP Address is with in list. + * + * @param array $ip_address_list + * + * @return boolean. + */ + public static function is_user_ip_address_within_list($ip_address_list) { + + if (!(include_once AIOWPS_FIREWALL_DIR.'/../../vendor/mlocati/ip-lib/ip-lib.php')) { + throw new \Exception("AIOS_Helper::is_user_ip_address_within_list failed to load ip-lib.php"); + } + + if (empty($ip_address_list)) return false; + + $user_ip = self::get_user_ip_address(); + $user_ip_address = \IPLib\Factory::parseAddressString($user_ip); + if (null != $user_ip_address) { + $user_ip_address_type = $user_ip_address->getAddressType(); + $user_ipv4_address_parsed = (6 == $user_ip_address_type) ? $user_ip_address->toIPv4() : $user_ip_address; + // linear search used to compare ips list. + foreach ($ip_address_list as $ip_address) { + if (preg_match("/\/|\*/", $ip_address)) { // checks user ipadress with in range of ip range. + $range = \IPLib\Factory::parseRangeString($ip_address); + if (null != $range && $range->contains($user_ip_address)) return true; + } elseif ($ip_address == $user_ip) { + return true; + } elseif (null != $user_ipv4_address_parsed) { // check for ip matches if ipv6 to ipv4 or vice versa + $ip_address_parsed = \IPLib\Factory::parseAddressString($ip_address); + if (null != $ip_address_parsed) { + $ip_address_parsed_type = $ip_address_parsed->getAddressType(); + $ipv4_address_parsed = (6 == $ip_address_parsed_type) ? $ip_address_parsed->toIPv4() : $ip_address_parsed; + if ((string) $user_ipv4_address_parsed == (string) $ipv4_address_parsed) return true; + } + } + } + } + return false; + } + + /** + * Get user IP Address using an external service. + * This can be used as a fallback for users on localhost where + * get_ip_address() will be a local IP and non-geolocatable. + * + * @return string|boolean external ip address if from one of lookup service gets response otherwise false. + */ + public static function get_external_ip_address() { + $aiowps_firewall_constants = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONSTANTS); + $external_ip_address = false; + + //Running from cronjob REQUEST_URI is empty or DOING_CRON, if from command line cli is PHP_SAPI, constant set by user + if (empty($_SERVER['REQUEST_URI']) || (defined('DOING_CRON') && DOING_CRON) || 'cli' == PHP_SAPI || $aiowps_firewall_constants->AIOS_DISABLE_EXTERNAL_IP_ADDR) return $external_ip_address; + + $ip_lookup_services = AIOS_Abstracted_Ids::get_ip_lookup_services(); + $ip_lookup_services_keys = array_keys($ip_lookup_services); + shuffle($ip_lookup_services_keys); + + foreach ($ip_lookup_services_keys as $service_name) { + $service_endpoint = $ip_lookup_services[$service_name]; + $response = self::request_remote($service_endpoint); + if (!empty($response) && filter_var($response, FILTER_VALIDATE_IP)) { + $external_ip_address = $response; + break; + } + } + return $external_ip_address; + } + + /** + * Remote url request. + * + * @global \AIOWPS\Firewall\Constants $aiowps_firewall_constants + * + * @param string $url url to be requested. + * @param array $args request args array. + * + * @return string response. + */ + public static function request_remote($url, $args = array()) { + $aiowps_firewall_constants = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONSTANTS); + $response = ''; + $aiowps_firewall_utility = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::UTILITY); + $root = $aiowps_firewall_utility::get_root_dir(); + $includes = isset($aiowps_firewall_constants->WPINC) ? $aiowps_firewall_constants->WPINC : 'wp-includes'; + + //WP 6.2+ the request library updated to 2.0.5, class and interface files/directory moved and namespaced name used. + if (!class_exists('WpOrg\Requests\Autoload')) { + if (file_exists($root . $includes . '/Requests/src/Autoload.php')) { + require_once($root . $includes . '/Requests/src/Autoload.php'); + WpOrg\Requests\Autoload::register(); + WpOrg\Requests\Requests::set_certificate_path($root . $includes . '/certificates/ca-bundle.crt'); + } elseif (!class_exists('Requests') && file_exists($root . $includes . '/class-requests.php')) { + require_once($root . $includes . '/class-requests.php'); + Requests::register_autoloader(); + Requests::set_certificate_path($root . $includes . '/certificates/ca-bundle.crt'); + } + } + $timeout = isset($aiowps_firewall_constants->AIOS_REQUEST_TIMEOUT) ? $aiowps_firewall_constants->AIOS_REQUEST_TIMEOUT : 4; + + try { + $headers = isset($args['headers']) ? $args['headers'] : array(); + $data = isset($args['body']) ? $args['body'] : array(); + $method = isset($args['method']) ? $args['method'] : 'GET'; + $options = array('timeout' => $timeout); + //WP 6.2+ the request library 2.0.5 namespaced name WpOrg\Requests\Requests instead just Requests + if (class_exists('WpOrg\Requests\Requests')) { + $request_response = WpOrg\Requests\Requests::request($url, $headers, $data, $method, $options); + } elseif (class_exists('Requests')) { + $request_response = Requests::request($url, $headers, $data, $method, $options); + } + $response = $request_response->body; + } catch (\Exception $e) { + $error_message = $e->getMessage(); + // timed out exception ignore it. + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- PCP warning. Part of AIOS error reporting. + if (!preg_match('/timed out/i', $error_message)) error_log('AIOS_Helper::request_remote exception - ' . $error_message); + } catch (\Error $e) { // phpcs:ignore PHPCompatibility.Classes.NewClasses.errorFound -- this won't run on PHP 5.6 so we still want to catch it on other versions + error_log('AIOS_Helper::request_remote error - ' . $e->getMessage()); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- PCP warning. Part of AIOS error reporting. + } + + if (empty($response) && ini_get('allow_url_fopen')) { + // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- Cannot use WP API since Firewall is loaded outside WordPress. + $response = @file_get_contents($url, false, stream_context_create(array('http' => array("timeout" => $timeout)))); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore this to silence request failed warning for IP lookup services + } + return $response; + } + + /** + * Performs reverse IP lookup for the given IP address + * + * @param string $ip_address - IP address to perform reverse lookup + * + * @return array - Reverse lookup data + */ + public static function get_ip_reverse_lookup($ip_address) { + global $aio_wp_security; + $reverse_lookup_data = array(); + $ip_reverse_lookup_services = AIOS_Abstracted_Ids::get_reverse_ip_lookup_services(); + $ip_reverse_lookup_services_keys = array_keys($ip_reverse_lookup_services); + shuffle($ip_reverse_lookup_services_keys); + + foreach ($ip_reverse_lookup_services_keys as $service_name) { + $endpoint = $ip_reverse_lookup_services[$service_name]; + $url = sprintf($endpoint, $ip_address); + $response = wp_safe_remote_get($url, array( 'timeout' => 2 )); + + if (!is_wp_error($response) && $response['body']) { + $data = json_decode($response['body'], true); + if (!$data) { + $aio_wp_security->debug_logger->log_debug("Error decoding IP lookup result", 4); + return $reverse_lookup_data; + } + switch ($service_name) { + case 'ip-api': + $fields_to_copy = array('org', 'as'); + foreach ($fields_to_copy as $field) { + $reverse_lookup_data[$field] = empty($data[$field]) ? null : $data[$field]; + } + break; + case 'ipinfo': + $reverse_lookup_data['org'] = empty($data['org']) ? null : $data['org']; + $reverse_lookup_data['as'] = $reverse_lookup_data['org']; + break; + default: + break; + } + + $reverse_lookup_data = apply_filters('aiowps_login_lockdown_lookup_result', $reverse_lookup_data, $data, $service_name); + break; + } + } + + return $reverse_lookup_data; + } + + /** + * Gets hash of given string using auth Authentication scheme + * + * @param string $data - Plain text to hash. + * + * @return string - Hash of $data + */ + public static function get_hash($data) { + $aiowps_firewall_constants = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONSTANTS); + $salt = $aiowps_firewall_constants->AUTH_KEY.$aiowps_firewall_constants->AUTH_SALT; + return hash_hmac('md5', $data, $salt); + } + + /** + * Set a message for a specific context. + * + * @param string $context The unique context identifier for the message. + * @param string $message The message to store for the given context. + * @param string $type The message type to store for the given context. + * + * @return void + */ + public static function set_message($context, $message, $type = 'info') { + self::$messages[$context] = array('message' => $message, 'type' => $type); + } + + /** + * Get a message for a specific context. + * + * @param string $context The unique context identifier for the message. + * + * @return array|null The message for the given context, or null if not found. + */ + public static function get_message($context) { + return isset(self::$messages[$context]) ? self::$messages[$context] : null; + } + + /** + * Clear messages (optional, for cleanup purposes). + * + * @return void + */ + public static function clear_messages() { + self::$messages = array(); + } + + /** + * This function checks if the current request is an UpdraftCentral request by looking for a specific constant. + * + * @return boolean - True if the request is from UpdraftCentral, false otherwise. + */ + public static function is_updraft_central_request() { + return defined('UPDRAFTCENTRAL_COMMAND') && UPDRAFTCENTRAL_COMMAND; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-hibp.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-hibp.php new file mode 100755 index 00000000..06c34bfe --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-hibp.php @@ -0,0 +1,83 @@ +debug_logger->log_debug('Failed to query the HIBP api: ' . $response_body->get_error_message(), 4); + return false; + } + + $response_body_array = explode("\n", $response_body); + + foreach ($response_body_array as $suffix_and_count) { + $suffix = explode(':', $suffix_and_count)[0]; + + if (strtolower($suffix) == $password_hash_suffix) { + return true; + } + } + + return false; + } + + /** + * Checks if a password has been pwned when updating a user profile. + * + * @param WP_Error $errors + * @param bool $update + * @param stdClass $user + * + * @return void + */ + public static function user_profile_update_check(&$errors, $update, &$user) { + // Use get_error_code() instead of has_errors() for backward compatibility with WP 5.0. + if ($errors->get_error_code() || empty($user->user_pass)) { + return; + } + + if (self::password_is_pwned($user->user_pass)) { + $errors->add('pass', __('Error: This password has been exposed in a data breach, according to Have I Been Pwned (HIBP).')); + } + } + + /** + * Checks if a password has been pwned when resetting a password. + * + * @param WP_Error $errors + * + * @return void + */ + public static function password_reset_check($errors) { + // Use get_error_code() instead of has_errors() for backward compatibility with WP 5.0. + if ($errors->get_error_code() || !isset($_POST['pass1']) || empty($_POST['pass1'])) { + return; + } + + if (self::password_is_pwned($_POST['pass1'])) { + $errors->add('pass', __('Error: This password has been exposed in a data breach, according to Have I Been Pwned (HIBP).')); + } + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-installer.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-installer.php new file mode 100755 index 00000000..4dc6d8c9 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-installer.php @@ -0,0 +1,498 @@ + array( + 'clean_audit_log_stacktraces', + ), + '2.0.9' => array( + 'update_table_column_to_timestamp', + ), + '2.0.10' => array( + 'delete_aiowps_temp_configs_option', + ), + '2.1.4' => array( + 'update_tables_to_innodb', + ) + ); + + /** + * Run installer function. + * + * @return void + */ + public static function run_installer() { + global $wpdb; + if (function_exists('is_multisite') && is_multisite() && is_main_site()) { + // check if it is a network activation - if so, run the activation function for each blog id + $blogids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- There doesn't seem to be a documented alternative. Possible alternative get_sites(array('fields' => 'ids', 'number' => 0) but 'number' => 0 is not documented. + foreach ($blogids as $blog_id) { + switch_to_blog($blog_id); + AIOWPSecurity_Installer::create_db_tables(); + AIOWPSecurity_Installer::migrate_db_tables(); + AIOWPSecurity_Installer::check_tasks(); + AIOWPSecurity_Configure_Settings::add_option_values(); + AIOWPSecurity_Configure_Settings::update_aiowpsec_db_version(); + restore_current_blog(); + } + } else { + AIOWPSecurity_Installer::create_db_tables(); + AIOWPSecurity_Installer::migrate_db_tables(); + AIOWPSecurity_Installer::check_tasks(); + AIOWPSecurity_Configure_Settings::add_option_values(); + AIOWPSecurity_Configure_Settings::update_aiowpsec_db_version(); + } + + AIOWPSecurity_Installer::create_db_backup_dir(); // Create a backup dir in the WP uploads directory. + } + + /** + * See if any database tasks need to be run, and perform them if so. + * + * @return void + */ + public static function check_tasks() { + $our_version = AIO_WP_SECURITY_DB_VERSION; + $db_version = get_option('aiowpsec_db_version'); + // database tasks not need to be run if first time install - false check added + if (false != $db_version && version_compare($our_version, $db_version, '>')) { + foreach (self::$db_tasks as $version => $updates) { + if (version_compare($version, $db_version, '>')) { + foreach ($updates as $update) { + call_user_func(array(__CLASS__, $update)); + } + } + } + } + } + + public static function create_db_tables() { + global $wpdb; + + if (!function_exists('dbDelta')) { + require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); + } + + if (function_exists('is_multisite') && is_multisite()) { + /* + * FIX for multisite table creation case: + * Although each table name is defined in a constant inside the wp-security-core.php, + * we need to do this step for multisite case because we need to refresh the $wpdb->prefix value + * otherwise it will contain the original blog id and not the current id we need. + * + */ + $lockout_tbl_name = $wpdb->prefix.'aiowps_login_lockdown'; + $aiowps_global_meta_tbl_name = $wpdb->prefix.'aiowps_global_meta'; + $aiowps_event_tbl_name = $wpdb->prefix.'aiowps_events'; + $perm_block_tbl_name = $wpdb->prefix.'aiowps_permanent_block'; + } else { + $lockout_tbl_name = AIOWPSEC_TBL_LOGIN_LOCKOUT; + $aiowps_global_meta_tbl_name = AIOWPSEC_TBL_GLOBAL_META_DATA; + $aiowps_event_tbl_name = AIOWPSEC_TBL_EVENTS; + $perm_block_tbl_name = AIOWPSEC_TBL_PERM_BLOCK; + } + + $message_store_log_tbl_name = AIOWPSEC_TBL_MESSAGE_STORE; + $audit_log_tbl_name = AIOWPSEC_TBL_AUDIT_LOG; + $debug_log_tbl_name = AIOWPSEC_TBL_DEBUG_LOG; + $logged_in_users_tbl_name = AIOWPSEC_TBL_LOGGED_IN_USERS; + + $charset_collate = ''; + if (!empty($wpdb->charset)) { + $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset"; + } else { + $charset_collate = "DEFAULT CHARSET=utf8"; + } + if (!empty($wpdb->collate)) { + $charset_collate .= " COLLATE $wpdb->collate"; + } + + $ld_tbl_sql = "CREATE TABLE " . $lockout_tbl_name . " ( + id bigint(20) NOT NULL AUTO_INCREMENT, + user_id bigint(20) NOT NULL, + user_login VARCHAR(150) NOT NULL, + lockdown_date datetime NOT NULL DEFAULT '1000-10-10 10:00:00', + created INTEGER UNSIGNED, + release_date datetime NOT NULL DEFAULT '1000-10-10 10:00:00', + released INTEGER UNSIGNED, + failed_login_ip varchar(100) NOT NULL DEFAULT '', + lock_reason varchar(128) NOT NULL DEFAULT '', + unlock_key varchar(128) NOT NULL DEFAULT '', + is_lockout_email_sent tinyint(1) NOT NULL DEFAULT '1', + backtrace_log text NOT NULL, + ip_lookup_result LONGTEXT DEFAULT NULL, + PRIMARY KEY (id), + KEY failed_login_ip (failed_login_ip), + KEY is_lockout_email_sent (is_lockout_email_sent), + KEY unlock_key (unlock_key) + ) ENGINE=InnoDB " . $charset_collate . ";"; + dbDelta($ld_tbl_sql); + + $gm_tbl_sql = "CREATE TABLE " . $aiowps_global_meta_tbl_name . " ( + meta_id bigint(20) NOT NULL auto_increment, + date_time datetime NOT NULL default '1000-10-10 10:00:00', + created INTEGER UNSIGNED, + meta_key1 varchar(255) NOT NULL, + meta_key2 varchar(255) NOT NULL, + meta_key3 varchar(255) NOT NULL, + meta_key4 varchar(255) NOT NULL, + meta_key5 varchar(255) NOT NULL, + meta_value1 varchar(255) NOT NULL, + meta_value2 text NOT NULL, + meta_value3 text NOT NULL, + meta_value4 longtext NOT NULL, + meta_value5 longtext NOT NULL, + PRIMARY KEY (meta_id) + ) ENGINE=InnoDB " . $charset_collate . ";"; + dbDelta($gm_tbl_sql); + + $evt_tbl_sql = "CREATE TABLE " . $aiowps_event_tbl_name . " ( + id bigint(20) NOT NULL AUTO_INCREMENT, + event_type VARCHAR(150) NOT NULL DEFAULT '', + username VARCHAR(150), + user_id bigint(20), + event_date datetime NOT NULL DEFAULT '1000-10-10 10:00:00', + created INTEGER UNSIGNED, + ip_or_host varchar(100), + referer_info varchar(255), + url varchar(255), + country_code varchar(50), + event_data longtext, + PRIMARY KEY (id) + ) ENGINE=InnoDB " . $charset_collate . ";"; + dbDelta($evt_tbl_sql); + + $pb_tbl_sql = "CREATE TABLE " . $perm_block_tbl_name . " ( + id bigint(20) NOT NULL AUTO_INCREMENT, + blocked_ip varchar(100) NOT NULL DEFAULT '', + block_reason varchar(128) NOT NULL DEFAULT '', + country_origin varchar(50) NOT NULL DEFAULT '', + blocked_date datetime NOT NULL DEFAULT '1000-10-10 10:00:00', + created INTEGER UNSIGNED, + unblock tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (id), + KEY blocked_ip (blocked_ip) + ) ENGINE=InnoDB " . $charset_collate . ";"; + dbDelta($pb_tbl_sql); + + $audit_log_tbl_sql = "CREATE TABLE " . $audit_log_tbl_name . " ( + id bigint(20) NOT NULL AUTO_INCREMENT, + network_id bigint(20) NOT NULL DEFAULT '0', + site_id bigint(20) NOT NULL DEFAULT '0', + username varchar(60) NOT NULL DEFAULT '', + ip VARCHAR(45) NOT NULL DEFAULT '', + level varchar(25) NOT NULL DEFAULT '', + event_type varchar(25) NOT NULL DEFAULT '', + details text NOT NULL, + stacktrace text NOT NULL, + created INTEGER UNSIGNED, + country_code varchar(50), + PRIMARY KEY (id), + INDEX username (username), + INDEX ip (ip), + INDEX level (level), + INDEX event_type (event_type) + ) ENGINE=InnoDB " . $charset_collate . ";"; + dbDelta($audit_log_tbl_sql); + + $debug_log_tbl_sql = "CREATE TABLE " . $debug_log_tbl_name . " ( + id bigint(20) NOT NULL AUTO_INCREMENT, + created datetime NOT NULL DEFAULT '1000-10-10 10:00:00', + logtime INTEGER UNSIGNED, + level varchar(25) NOT NULL DEFAULT '', + network_id bigint(20) NOT NULL DEFAULT '0', + site_id bigint(20) NOT NULL DEFAULT '0', + message text NOT NULL, + type varchar(25) NOT NULL DEFAULT '', + PRIMARY KEY (id) + ) ENGINE=InnoDB " . $charset_collate . ";"; + dbDelta($debug_log_tbl_sql); + + $liu_tbl_sql = "CREATE TABLE " . $logged_in_users_tbl_name . " ( + id bigint(20) NOT NULL AUTO_INCREMENT, + user_id bigint(20) NOT NULL, + username varchar(60) NOT NULL DEFAULT '', + ip_address varchar(45) NOT NULL DEFAULT '', + site_id bigint(20) NOT NULL, + created integer UNSIGNED, + expires integer UNSIGNED, + PRIMARY KEY (id), + UNIQUE KEY unique_user_id (user_id), + INDEX created (created), + INDEX expires (expires), + INDEX user_id (user_id), + INDEX site_id (site_id) + ) ENGINE=InnoDB " . $charset_collate . ";"; + dbDelta($liu_tbl_sql); + + $message_store_log_tbl_sql = "CREATE TABLE " . $message_store_log_tbl_name . " ( + id bigint(20) NOT NULL AUTO_INCREMENT, + message_key text NOT NULL, + message_value text NOT NULL, + created INTEGER UNSIGNED, + PRIMARY KEY (id) + ) ENGINE=InnoDB " . $charset_collate . ";"; + dbDelta($message_store_log_tbl_sql); + } + + /** + * This function will handle any database table migrations + * + * @return void + */ + public static function migrate_db_tables() { + global $wpdb; + + if (function_exists('is_multisite') && is_multisite()) { + /* + * FIX for multisite table creation case: + * Although each table name is defined in a constant inside the wp-security-core.php, + * we need to do this step for multisite case because we need to refresh the $wpdb->prefix value + * otherwise it will contain the original blog id and not the current id we need. + * + */ + $failed_login_tbl_name = $wpdb->prefix.'aiowps_failed_logins'; + $login_activity_tbl_name = $wpdb->prefix.'aiowps_login_activity'; + + } else { + $failed_login_tbl_name = AIOWPSEC_TBL_FAILED_LOGINS; + $login_activity_tbl_name = AIOWPSEC_TBL_USER_LOGIN_ACTIVITY; + } + + $audit_log_tbl_name = AIOWPSEC_TBL_AUDIT_LOG; + $network_id = get_current_network_id(); + $site_id = get_current_blog_id(); + + $table_exists = $wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $wpdb->esc_like($failed_login_tbl_name))); // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- There doesn't seem to be an alternative. + if ($table_exists) { + $import_details = array( + 'failed_login' => array( + 'imported' => true, + ) + ); + $import_details = wp_json_encode($import_details, true); + $table_migration_details = array( + 'table_migration' => array( + 'success' => true, + 'from_table' => $failed_login_tbl_name, + 'to_table' => $audit_log_tbl_name + ) + ); + + if (false === $wpdb->query($wpdb->prepare("INSERT INTO $audit_log_tbl_name (network_id, site_id, username, ip, level, event_type, details, stacktrace, created) SELECT %d AS network_id, %d AS site_id, fl.user_login AS username, fl.login_attempt_ip AS ip, 'warning' AS level, 'Failed login' AS event_type, %s AS details, '' AS stacktrace, UNIX_TIMESTAMP(fl.failed_login_date) AS created FROM $failed_login_tbl_name fl", $network_id, $site_id, $import_details))) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- We can't use %i because our plugin supports wordpress < 6.2. + $table_migration_details['table_migration']['success'] = false; + do_action('aiowps_record_event', 'table_migration', $table_migration_details, 'error'); + } else { + do_action('aiowps_record_event', 'table_migration', $table_migration_details, 'info'); + $wpdb->query("DROP TABLE IF EXISTS `$failed_login_tbl_name`"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- We can't use %i because our plugin supports wordpress < 6.2. + } + } + + $table_exists = $wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $wpdb->esc_like($login_activity_tbl_name))); // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- There doesn't seem to be an alternative. + if ($table_exists) { + $wpdb->query("DROP TABLE IF EXISTS `$login_activity_tbl_name`"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- We can't use %i because our plugin supports wordpress < 6.2. + } + } + + /** + * This function will run SQL to clean sensitive information from the audit log table stacktrace + * + * @return void + */ + public static function clean_audit_log_stacktraces() { + global $wpdb; + $wpdb->query("UPDATE ".AIOWPSEC_TBL_AUDIT_LOG." SET stacktrace = '' WHERE event_type = 'failed_login' OR event_type = 'successful_login' OR event_type = 'user_registration'"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared -- We can't use %i because our plugin supports wordpress < 6.2. + } + + /** + * This function will update the table datetime column to timestamp with backward compability + * + * @return void + */ + public static function update_table_column_to_timestamp() { + $db_version = get_option('aiowpsec_db_version', '1.0'); + if (version_compare('2.0.8', $db_version, '>')) { + self::update_column_to_timestamp(AIOWPSEC_TBL_EVENTS, 'event_date', 'created'); + self::update_column_to_timestamp(AIOWPSEC_TBL_LOGIN_LOCKOUT, 'lockdown_date', 'created'); + self::update_column_to_timestamp(AIOWPSEC_TBL_LOGIN_LOCKOUT, 'release_date', 'released'); + } + + if (version_compare('2.0.9', $db_version, '>')) { + self::update_column_to_timestamp(AIOWPSEC_TBL_PERM_BLOCK, 'blocked_date', 'created'); + self::update_column_to_timestamp(AIOWPSEC_TBL_GLOBAL_META_DATA, 'date_time', 'created'); + self::update_column_to_timestamp(AIOWPSEC_TBL_DEBUG_LOG, 'created', 'logtime'); + } + } + + /** + * Update the table column to UTC timestamp not depending on the timezone of the user or server settings + * + * @global wpdb $wpdb + * + * @param string $table_name + * @param string $field_datetime + * @param string $field_timestamp + * + * @return boolean - returns the rows updated or not + */ + public static function update_column_to_timestamp($table_name, $field_datetime, $field_timestamp) { + global $wpdb; + //MySQL UNIX_TIMESTAMP will convert datetime based on local timezone not UTC + $offset = $wpdb->get_var("SELECT TIMESTAMPDIFF(SECOND, NOW(), UTC_TIMESTAMP())"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- There doesn't seem to be an alternative. + if (AIOWPSEC_TBL_PERM_BLOCK == $table_name || AIOWPSEC_TBL_GLOBAL_META_DATA == $table_name || AIOWPSEC_TBL_DEBUG_LOG == $table_name) { + //User local settings date time saved offset timezone needs to removed for UTC correct value + $offset += AIOWPSecurity_Utility::get_wp_timezone()->getOffset(new DateTime('now', new DateTimeZone('UTC'))); + } + if (function_exists('is_multisite') && is_multisite() && AIOWPSEC_TBL_EVENTS == $table_name) { + $table_name = $wpdb->prefix.'aiowps_events'; + } elseif (function_exists('is_multisite') && is_multisite() && AIOWPSEC_TBL_LOGIN_LOCKOUT == $table_name) { + $table_name = $wpdb->prefix.'aiowps_login_lockdown'; + } elseif (function_exists('is_multisite') && is_multisite() && AIOWPSEC_TBL_PERM_BLOCK == $table_name) { + $table_name = $wpdb->prefix.'aiowps_permanent_block'; + } elseif (function_exists('is_multisite') && is_multisite() && AIOWPSEC_TBL_GLOBAL_META_DATA == $table_name) { + $table_name = $wpdb->prefix.'aiowps_global_meta'; + } elseif (function_exists('is_multisite') && is_multisite() && AIOWPSEC_TBL_DEBUG_LOG == $table_name) { + $table_name = $wpdb->prefix.'aiowps_debug_log'; + } + //offset to make sure UTC timestamp updated + $wpdb->query($wpdb->prepare("UPDATE $table_name SET $field_timestamp = (UNIX_TIMESTAMP($field_datetime) - %d)", $offset)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- We can't use %i because our plugin supports wordpress < 6.2. + } + + /** + * Deletes the aiowps_temp_configs option if present. + * + * @return void + */ + public static function delete_aiowps_temp_configs_option() { + delete_option('aiowps_temp_configs'); + } + + /** + * Alters all of the AIOS tables to use InnoDB. + * + * @global wpdb $wpdb + * + * @return void + */ + public static function update_tables_to_innodb() { + global $wpdb; + + if (function_exists('is_multisite') && is_multisite()) { + /* + * FIX for multisite table creation case: + * Although each table name is defined in a constant inside the wp-security-core.php, + * we need to do this step for multisite case because we need to refresh the $wpdb->prefix value + * otherwise it will contain the original blog id and not the current id we need. + * + */ + $lockout_tbl_name = $wpdb->prefix.'aiowps_login_lockdown'; + $aiowps_global_meta_tbl_name = $wpdb->prefix.'aiowps_global_meta'; + $aiowps_event_tbl_name = $wpdb->prefix.'aiowps_events'; + $perm_block_tbl_name = $wpdb->prefix.'aiowps_permanent_block'; + } else { + $lockout_tbl_name = AIOWPSEC_TBL_LOGIN_LOCKOUT; + $aiowps_global_meta_tbl_name = AIOWPSEC_TBL_GLOBAL_META_DATA; + $aiowps_event_tbl_name = AIOWPSEC_TBL_EVENTS; + $perm_block_tbl_name = AIOWPSEC_TBL_PERM_BLOCK; + } + + $message_store_log_tbl_name = AIOWPSEC_TBL_MESSAGE_STORE; + $audit_log_tbl_name = AIOWPSEC_TBL_AUDIT_LOG; + $debug_log_tbl_name = AIOWPSEC_TBL_DEBUG_LOG; + $logged_in_users_tbl_name = AIOWPSEC_TBL_LOGGED_IN_USERS; + + // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- No alternative. + $wpdb->query('ALTER TABLE ' . $lockout_tbl_name . ' ENGINE=InnoDB'); + $wpdb->query('ALTER TABLE ' . $aiowps_global_meta_tbl_name . ' ENGINE=InnoDB'); + $wpdb->query('ALTER TABLE ' . $aiowps_event_tbl_name . ' ENGINE=InnoDB'); + $wpdb->query('ALTER TABLE ' . $perm_block_tbl_name . ' ENGINE=InnoDB'); + $wpdb->query('ALTER TABLE ' . $audit_log_tbl_name . ' ENGINE=InnoDB'); + $wpdb->query('ALTER TABLE ' . $debug_log_tbl_name . ' ENGINE=InnoDB'); + $wpdb->query('ALTER TABLE ' . $logged_in_users_tbl_name . ' ENGINE=InnoDB'); + $wpdb->query('ALTER TABLE ' . $message_store_log_tbl_name . ' ENGINE=InnoDB'); + // phpcs:enable WordPress.DB.DirectDatabaseQuery + } + + public static function create_db_backup_dir() { + global $aio_wp_security; + // phpcs:disable WordPress.WP.AlternativeFunctions -- WP_Filesystem is not appropriate here. + //Create our folder in the "wp-content" directory + $aiowps_dir = WP_CONTENT_DIR . '/' . AIO_WP_SECURITY_BACKUPS_DIR_NAME; + if (!is_dir($aiowps_dir) && is_writable(WP_CONTENT_DIR)) { + mkdir($aiowps_dir, 0755, true); + //Let's also create an empty index.html file in this folder + $index_file = $aiowps_dir . '/index.html'; + $handle = fopen($index_file, 'w'); //or die('Cannot open file: '.$index_file); + fclose($handle); + } + $server_type = AIOWPSecurity_Utility::get_server_type(); + //Only create .htaccess if server is the right type + if ('apache' == $server_type || 'litespeed' == $server_type) { + $file = $aiowps_dir . '/.htaccess'; + if (!file_exists($file)) { + //Create an .htacces file + //Write some rules which will only allow people originating from wp admin page to download the DB backup + $rules = ''; + $rules .= 'order deny,allow' . PHP_EOL; + $rules .= 'deny from all' . PHP_EOL; + $write_result = file_put_contents($file, $rules); + if (false === $write_result) { + $aio_wp_security->debug_logger->log_debug("Creation of .htaccess file in " . AIO_WP_SECURITY_BACKUPS_DIR_NAME . " directory failed!", 4); + } + } + } + // phpcs:enable WordPress.WP.AlternativeFunctions -- WP_Filesystem is not appropriate here. + } + + /** + * Setup AIOS cron tasks. + * Handles both single and multi-site (NW activation) cases. + * + * @global type $wpdb + * + * @return Void + */ + public static function set_cron_tasks_upon_activation() { + require_once(__DIR__.'/wp-security-cronjob-handler.php'); + // It is required because we are going to schedule a 15-minute cron event upon activation. + add_filter('cron_schedules', array('AIOWPSecurity_Cronjob_Handler', 'cron_schedules')); + if (is_multisite() && is_main_site()) { + global $wpdb; + // check if it is a network activation + $blogids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- There doesn't seem to be a documented alternative. Possible alternative get_sites(array('fields' => 'ids', 'number' => 0) but 'number' => 0 is not documented. + foreach ($blogids as $blog_id) { + switch_to_blog($blog_id); + AIOWPSecurity_Installer::schedule_cron_events(); + do_action('aiowps_activation_complete'); + restore_current_blog(); + } + } else { + AIOWPSecurity_Installer::schedule_cron_events(); + do_action('aiowps_activation_complete'); + } + } + + /** + * Helper function for scheduling AIOS cron events. + * + * @return Void + */ + public static function schedule_cron_events() { + if (!wp_next_scheduled('aios_15_minutes_cron_event')) { + wp_schedule_event(time(), 'aios-every-15-minutes', 'aios_15_minutes_cron_event'); //schedule a 15 minutes cron event + } + if (!wp_next_scheduled('aiowps_hourly_cron_event')) { + wp_schedule_event(time(), 'hourly', 'aiowps_hourly_cron_event'); //schedule an hourly cron event + } + if (!wp_next_scheduled('aiowps_daily_cron_event')) { + wp_schedule_event(time(), 'daily', 'aiowps_daily_cron_event'); //schedule an daily cron event + } + if (!wp_next_scheduled('aiowps_weekly_cron_event')) { + wp_schedule_event(time(), 'weekly', 'aiowps_weekly_cron_event'); //schedule an daily cron event + } + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-notices.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-notices.php new file mode 100755 index 00000000..d8f36244 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-notices.php @@ -0,0 +1,739 @@ +debug_logger->log_debug('Notice rendering error: ' . $e->getMessage(), 4); + return esc_html__('An error occurred while rendering this notice, please enable and check your debug log.', 'all-in-one-wp-security-and-firewall'); + } + } + + + /** + * Returns array_merge of notices from parent and notices in $child_notice_content. + * + * @return Array + */ + protected function populate_notices_content() { + global $aio_wp_security; + $parent_notice_content = parent::populate_notices_content(); + + /* translators: 1. HTML text. 2. HTML text, 3. HTML text. */ + $sale_description = $this->safe_sprintf(__('Get %1$s with %2$s. %3$s, downtime, and response time issues.', 'all-in-one-wp-security-and-firewall'), '' . __('added protection', 'all-in-one-wp-security-and-firewall') . '', '' . __('Premium', 'all-in-one-wp-security-and-firewall') . '', '' . __('Scan your site for malware', 'all-in-one-wp-security-and-firewall') . ''); + + /* translators: %s: HTML text. */ + $sale_description .= ' ' . $this->safe_sprintf(__('Block traffic by country of origin, get advanced two-factor authentication, %s, and more.', 'all-in-one-wp-security-and-firewall'), '' . __('added protection', 'all-in-one-wp-security-and-firewall') . '', '' . __('Premium', 'all-in-one-wp-security-and-firewall') . '', '' . __('Scan your site for malware', 'all-in-one-wp-security-and-firewall') . ''); + + // Build text for firewall rules that have been upgraded + $firewall_upgrade_text = '

' . + esc_html__('The All in One Security plugin has deactivated some of the firewall settings that you had activated.', 'all-in-one-wp-security-and-firewall') . + '

'; + $firewall_upgrade_text .= '

' . + esc_html__('We have upgraded the following settings so that they are now part of the PHP firewall instead of .htaccess directives:', 'all-in-one-wp-security-and-firewall') . + '

'; + $firewall_upgrade_text .= '
    '; + + $active_settings = $aio_wp_security->configs->get_value('aiowps_firewall_active_upgrade'); + + if (!empty($active_settings)) { + $active_settings = json_decode($active_settings); + if (!empty($active_settings)) { + + foreach ($active_settings as $setting) { + switch ($setting) { + case 'aiowps_enable_pingback_firewall': + $firewall_upgrade_text .= '
  • ' . esc_html__('Completely block xmlrpc.php', 'all-in-one-wp-security-and-firewall').'
  • '; + break; + case 'aiowps_forbid_proxy_comments': + $firewall_upgrade_text .= '
  • ' . esc_html__('Forbid proxy comment posting', 'all-in-one-wp-security-and-firewall').'
  • '; + break; + case 'aiowps_deny_bad_query_strings': + $firewall_upgrade_text .= '
  • ' . esc_html__('Deny bad query strings', 'all-in-one-wp-security-and-firewall').'
  • '; + break; + case 'aiowps_advanced_char_string_filter': + $firewall_upgrade_text .= '
  • ' . esc_html__('Advanced character filter', 'all-in-one-wp-security-and-firewall').'
  • '; + break; + default: + continue 2; + } + } + } + } else { + $firewall_upgrade_text .= '

    ' . esc_html__('None of the settings that have been upgraded were active.', 'all-in-one-wp-security-and-firewall').'

    '; + } + + $firewall_upgrade_text .= '
'; + $firewall_upgrade_text .= '

' . esc_html__('What would you like to do?', 'all-in-one-wp-security-and-firewall') .'

'; + + $login_whitelist_notice_text = '

' . + esc_html__('The All in One Security plugin has disabled the login whitelist setting that you have enabled in the past.', 'all-in-one-wp-security-and-firewall') . + '

' . + '

'; + if (AIOWPSecurity_Utility::is_apache_server()) { + $login_whitelist_notice_text .= esc_html__('Your website is running on an Apache webserver, the login whitelisting might not be functional until the recent update of AIOS (because it relied upon Apache-specific module features).', 'all-in-one-wp-security-and-firewall'); + } else { + $login_whitelist_notice_text .= esc_html__('Your website is running on a non-Apache webserver, so the login whitelisting was not functional until the recent update of AIOS (because it relied upon Apache-specific features).', 'all-in-one-wp-security-and-firewall'); + } + $login_whitelist_notice_text .= ' ' . esc_html__('It began working with AIOS version 5.0.8.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('We have disabled it so that your login page will not be blocked unexpectedly.', 'all-in-one-wp-security-and-firewall') . + '

'; + + $allowed_ip_addresses = explode("\n", $aio_wp_security->configs->get_value('aiowps_allowed_ip_addresses')); + $allowed_ip_addresses = array_map('trim', $allowed_ip_addresses); + $login_whitelist_notice_text .= '

' . + esc_html__('Whitelisted login IP address(es):', 'all-in-one-wp-security-and-firewall') . ' ' . htmlspecialchars(implode(', ', $allowed_ip_addresses)) . + '

' . + '

' . + esc_html__('Would you like to re-enable login whitelisting?', 'all-in-one-wp-security-and-firewall') . + '

'; + + $child_notice_content = array( + // Upgrade AIOS backup to UDP backup in the 5.0.0 version + 'automated-database-backup' => array( + 'title' => esc_html__('Removed database backup feature from the All-In-One Security plugin', 'all-in-one-wp-security-and-firewall'), + 'text' => '

' . + esc_html__('Beginning with version 5.0.0, AIOS has replaced the AIOS backup method with the superior UpdraftPlus method.', 'all-in-one-wp-security-and-firewall') . ' '. + esc_html__('It remains free and is fully supported by the UpdraftPlus team.', 'all-in-one-wp-security-and-firewall') . + '

' . + '

' . + esc_html__('You are seeing this notice because you have previously set up automated database backups in AIOS.', 'all-in-one-wp-security-and-firewall') . ' ' . + esc_html__('Would you like to set up scheduled backups with UpdraftPlus?', 'all-in-one-wp-security-and-firewall') . + '

', + 'button_link' => add_query_arg(array( + 'page' => 'aiowpsec_database', + 'tab' => 'database-backup', + ), admin_url('admin.php')) . '#automated-scheduled-backups-heading', + 'button_meta' => esc_html__('Setup UpdraftPlus backup plugin', 'all-in-one-wp-security-and-firewall'), + 'dismiss_time' => 'dismiss_automated_database_backup_notice', + 'supported_positions' => array('automated-database-backup'), + 'validity_function' => 'should_show_automated_database_backup_notice', + ), + 'ip-retrieval-settings' => array( + 'title' => esc_html__('Important: set up your IP address detection settings', 'all-in-one-wp-security-and-firewall'), + 'text' => '

' . + esc_html__("The All in One Security plugin couldn't be certain about the correct method to detect the IP address for your site visitors with your currently-configured IP address detection settings.", 'all-in-one-wp-security-and-firewall') . ' '. + esc_html__('It is important for your security to set the IP address detection settings properly.', 'all-in-one-wp-security-and-firewall') . + '

' . + '

' . + esc_html__('Please go to the settings and set them now.', 'all-in-one-wp-security-and-firewall') . + '

', + 'button_link' => add_query_arg(array( + 'page' => 'aiowpsec_settings', + 'tab' => 'advanced-settings', + ), admin_url('admin.php')) . '#automated-scheduled-backups-heading', + 'button_meta' => esc_html__('Setup IP address detection settings', 'all-in-one-wp-security-and-firewall'), + 'dismiss_time' => 'dismiss_ip_retrieval_settings_notice', + 'supported_positions' => array('ip-retrieval-settings'), + 'validity_function' => 'should_show_ip_retrieval_settings_notice', + ), + 'load-firewall-resources-failed' => array( + 'title' => '', + 'text' => '

' . + esc_html__('Failed to load the firewall resources.', 'all-in-one-wp-security-and-firewall') . ' ' . + esc_html__('The firewall won\'t operate correctly.', 'all-in-one-wp-security-and-firewall') . + '

', + 'dismiss_time' => '', + 'supported_positions' => array('load-firewall-resources-failed'), + 'validity_function' => 'should_show_load_firewall_resources_failed_notice', + ), + 'end-of-support-php-56' => array( + 'title' => esc_html__('AIOS PHP 5.6 support will end soon', 'all-in-one-wp-security-and-firewall'), + 'text' => $this->get_end_of_support_php_56_text(), + 'dismiss_time' => 'php_56_eol_dismiss_forever', + 'supported_positions' => array('end-of-support-php-56'), + 'validity_function' => 'should_show_end_of_support_php_56', + ), + 'upgrade-firewall-tab-rules' => array( + 'title' => esc_html__('Important: Disabled firewall settings', 'all-in-one-wp-security-and-firewall'), + 'text' => $firewall_upgrade_text, + 'button_link' => add_query_arg(array( + 'page' => esc_html(AIOWPSEC_FIREWALL_MENU_SLUG), + 'tab' => 'basic-firewall', + ), admin_url('admin.php')), + 'action_button_text' => esc_html__('Reactivate', 'all-in-one-wp-security-and-firewall'), + 'button_meta' => esc_html__('Configure manually', 'all-in-one-wp-security-and-firewall'), + 'dismiss_time' => 'dismiss_firewall_settings_disabled_on_upgrade_notice', + 'supported_positions' => array('upgrade-firewall-tab-rules'), + 'dismiss_text' => esc_html__('Keep deactivated', 'all-in-one-wp-security-and-firewall'), + 'validity_function' => 'should_show_upgrade_firewall_settings_notice', + ), + 'ip-blacklist-settings-on-upgrade' => array( + 'title' => esc_html__('Important: Blacklist manager disabled', 'all-in-one-wp-security-and-firewall'), + 'text' => '

' . + esc_html__("The blacklist manager feature has been disabled to prevent any unexpected site lockouts.", 'all-in-one-wp-security-and-firewall') . + '

' . + '

' . + esc_html__("This feature will block any IP address or range listed in its settings, please double check your own details are not included before turning it back on.", 'all-in-one-wp-security-and-firewall') . + '

' , + 'button_link' => add_query_arg(array( + 'page' => esc_html(AIOWPSEC_FIREWALL_MENU_SLUG), + 'tab' => 'blacklist' + ), admin_url('admin.php')) . '#poststuff', + 'action_button_text' => 'Turn it on', + 'button_meta' => esc_html__('Edit the settings', 'all-in-one-wp-security-and-firewall'), + 'dismiss_time' => 'dismiss_ip_blacklist_notice', + 'dismiss_text' => 'Keep it off', + 'supported_positions' => array('ip-blacklist-settings-on-upgrade'), + 'validity_function' => 'should_show_ip_blacklist_settings_on_upgrade', + ), + 'login-whitelist-disabled-on-upgrade' => array( + 'title' => esc_html__('Important: Disabled login whitelist setting', 'all-in-one-wp-security-and-firewall'), + 'text' => $login_whitelist_notice_text, + 'button_link' => add_query_arg(array( + 'page' => esc_html(AIOWPSEC_BRUTE_FORCE_MENU_SLUG), + 'tab' => 'login-whitelist', + ), admin_url('admin.php')) . '#poststuff', + 'action_button_text' => esc_html__('Turn it back on', 'all-in-one-wp-security-and-firewall'), + 'button_meta' => esc_html__('Edit the settings', 'all-in-one-wp-security-and-firewall'), + 'dismiss_time' => 'dismiss_login_whitelist_disabled_on_upgrade_notice', + 'supported_positions' => array('login-whitelist-disabled-on-upgrade'), + 'dismiss_text' => esc_html__('Keep it off', 'all-in-one-wp-security-and-firewall'), + 'validity_function' => 'should_show_login_whitelist_disabled_on_upgrade_notice', + ), + 'rate_plugin' => array( + 'text' => $this->safe_sprintf(esc_html__('We noticed AIOS has kept your site safe for a while.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('If you like us, please consider leaving a positive review.', 'all-in-one-wp-security-and-firewall'). ' ' . esc_html__('If you have any issues or questions, please contact %s.', 'all-in-one-wp-security-and-firewall'), '' . esc_html__('support', 'all-in-one-wp-security-and-firewall').'') . '
' . esc_html__('Thank you so much!', 'all-in-one-wp-security-and-firewall') . '

- ' . esc_html__('All-In-One Security (AIOS)', 'all-in-one-wp-security-and-firewall').'', + 'image' => 'plugin-logos/aios-icon.png', + 'button_link' => 'https://wordpress.org/support/plugin/all-in-one-wp-security-and-firewall/reviews/?rate=5#new-post', + 'button_meta' => 'review', + 'dismiss_time' => 'dismiss_review_notice', + 'supported_positions' => $this->dashboard_top, + 'validity_function' => 'show_rate_notice' + ), + 'updraftplus' => array( + 'prefix' => '', + 'title' => esc_html__('Enhance your security even more by backing up your site', 'all-in-one-wp-security-and-firewall'), + 'text' => esc_html__('UpdraftPlus is the world\'s most trusted backup plugin.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('From the owners of All-In-One Security (AIOS).', 'all-in-one-wp-security-and-firewall'), + 'image' => 'plugin-logos/updraftplus-icon.png', + 'button_link' => 'https://wordpress.org/plugins/updraftplus/', + 'button_meta' => 'updraftplus', + 'dismiss_time' => 'dismiss_page_notice_until', + 'supported_positions' => $this->dashboard_top_or_report, + 'validity_function' => 'updraftplus_not_installed', + ), + 'wp-optimize' => array( + 'prefix' => '', + 'title' => esc_html__('Speed up your site', 'all-in-one-wp-security-and-firewall'), + 'text' => esc_html__("After you've secured your site, we recommend you install our WP-Optimize plugin to streamline it for better website performance.", 'all-in-one-wp-security-and-firewall'), + 'image' => 'plugin-logos/wp-optimize-icon.png', + 'button_link' => 'https://wordpress.org/plugins/wp-optimize/', + 'button_meta' => 'wp-optimize', + 'dismiss_time' => 'dismiss_notice', + 'supported_positions' => $this->anywhere, + 'validity_function' => 'wp_optimize_not_installed', + ), + + // The sale adverts content starts here + 'blackfriday' => array( + 'prefix' => '', + 'title' => esc_html__('20% off - Black Friday Sale', 'all-in-one-wp-security-and-firewall'), + 'text' => $sale_description, + 'text2' => esc_html__('at checkout.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('Hurry, offer ends 2 December.', 'all-in-one-wp-security-and-firewall') . '', + 'image' => 'notices/sale_20.png', + 'button_text' => sprintf(__('Save 20%% with code %s', 'all-in-one-wp-security-and-firewall'), 'blackfridaysale2025'), + 'button_link' => add_query_arg( + array( + 'utm_source' => 'aios-plugin', + 'utm_medium' => 'referral', + 'utm_campaign' => 'bf25-aios-plugin-banner', + 'utm_content' => 'bf-sale', + 'utm_creative_format' => 'advert', + ), + 'https://teamupdraft.com/plugin-black-friday/?utm_source=aios-plugin&utm_medium=referral&utm_campaign=bf25-aios-plugin-banner&utm_content=bf-sale&utm_creative_format=advert'), + 'campaign' => 'blackfriday', + 'button_meta' => 'inline', + 'dismiss_time' => 'dismiss_season', + // 'discount_code' => '‘bf22aiosupgrade’', + 'valid_from' => '2025-11-14 00:00:00', + 'valid_to' => '2025-12-02 23:59:59', + 'supported_positions' => $this->dashboard_top_or_report, + ) + ); + + return array_merge($parent_notice_content, $child_notice_content); + } + + /** + * Decides whether to show the automated database backup notice. + * + * @return Boolean True if the automated database notice should be shown, otherwise false. + */ + protected function should_show_automated_database_backup_notice() { + if ($this->is_database_backup_admin_page_tab()) { + return false; + } + + if (defined('AIOS_FORCE_AUTOMATED_DATABASE_BACKUP_NOTICE') && AIOS_FORCE_AUTOMATED_DATABASE_BACKUP_NOTICE) { + return true; + } + + if ($this->is_updraftplus_plugin_active() && $this->is_schedule_database_backup_set_in_updraftplus()) { + return false; + } + + global $aio_wp_security; + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_automated_backups')) { + return true; + } + + return false; + } + + /** + * Determines whether to show the PHP 5.6 end of support notice + * + * @return boolean + */ + protected function should_show_end_of_support_php_56() { + return version_compare(PHP_VERSION, '7.0.0', '<'); + } + + /** + * Gets the text to display with the PHP 5.6 end of support notice + * + * @return string + */ + protected function get_end_of_support_php_56_text() { + $text = '

' . esc_html__('AIOS will end support for PHP 5.6 on the 1st September 2025.', 'all-in-one-wp-security-and-firewall') . '

'; + + $text .= '

' . esc_html__('PHP 5.6 is outdated and no longer receives security updates.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('To keep things secure and compatible with modern WordPress standards, AIOS will move to a minimum requirement of PHP 7.0.', 'all-in-one-wp-security-and-firewall') . '

'; + + $text .= '

' . esc_html__('After the 1st September 2025, AIOS may not operate correctly on PHP versions below 7.0.', 'all-in-one-wp-security-and-firewall') . '

'; + + $text .= '

' . esc_html__('If you require help upgrading your PHP version, please contact your hosting provider.', 'all-in-one-wp-security-and-firewall') . '

'; + + return $text; + } + + /** + * Decides whether to show the load firewall resources failed notice. + * + * @return boolean + */ + protected function should_show_load_firewall_resources_failed_notice() { + return !AIOS_Firewall_Resource::all_loaded(); + } + + /** + * Determines whether to show the notice which handles the firewall settings notice + * + * @return boolean + */ + protected function should_show_upgrade_firewall_settings_notice() { + if (!is_main_site()) { + return false; + } + + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No nonce to check. + $is_firewall_page = ('admin.php' == $GLOBALS['pagenow'] && isset($_GET['page']) && AIOWPSEC_FIREWALL_MENU_SLUG == $_GET['page']); + if ($is_firewall_page) return false; + + global $aio_wp_security; + + $active_settings = $aio_wp_security->configs->get_value('aiowps_firewall_active_upgrade'); + + if (empty($active_settings)) return false; + + $active_settings = json_decode($active_settings); + + if (empty($active_settings)) return false; + + return true; + } + + /** + * Whether the current page is the AIOS database backup admin page + * + * @return Boolean True if the current page is the AIOS database backup admin page, otherwise false. + */ + private function is_database_backup_admin_page_tab() { + return $this->is_database_security_admin_page() && $this->is_database_backup_tab(); + } + + /** + * Whether the current page is the database security admin page. + * + * @return Boolean True if the current page is the database security admin page, otherwise false. + */ + private function is_database_security_admin_page() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No nonce to check. + return ('admin.php' == $GLOBALS['pagenow'] && isset($_GET['page']) && 'aiowpsec_database' == $_GET['page']); + } + + /** + * Whether the current tab is the database backup tab. + * + * @return Boolean True if the current tab is the database backup tab, otherwise false. + */ + private function is_database_backup_tab() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No nonce to check. + return (isset($_GET['tab']) && 'database-backup' == $_GET['tab']); + } + + /** + * Decides whether to show the IP address detection settings notice. + * + * @return Boolean True if the IP address detection settings notice should be shown, otherwise false. + */ + protected function should_show_ip_retrieval_settings_notice() { + if (!is_main_site()) { + return false; + } + + if ($this->is_ip_settings_admin_page_tab()) { + return false; + } + + if (defined('AIOS_FORCE_IP_RETRIEVAL_SETTINGS_NOTICE') && AIOS_FORCE_IP_RETRIEVAL_SETTINGS_NOTICE) { + return true; + } + + global $aio_wp_security; + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + + // Is notice dismissed. + if ('1' == $aio_wp_security->configs->get_value('dismiss_ip_retrieval_settings_notice')) { + return false; + } + + $configured_ip_method_id = $aio_wp_security->configs->get_value('aiowps_ip_retrieve_method'); + + if (AIOWPSecurity_Utility_IP::is_server_suitable_ip_methods_give_same_ip_address()) { + if ('' === $configured_ip_method_id) { + $server_suitable_ip_methods = AIOWPSecurity_Utility_IP::get_server_suitable_ip_methods(); + $most_suitable_ip_method = reset($server_suitable_ip_methods); + if (!empty($most_suitable_ip_method)) { + $most_suitable_ip_method_id = array_search($most_suitable_ip_method, AIOS_Abstracted_Ids::get_ip_retrieve_methods()); + $aio_wp_security->configs->set_value('aiowps_ip_retrieve_method', $most_suitable_ip_method_id); + $aiowps_firewall_config->set_value('aios_ip_retrieve_method', $most_suitable_ip_method_id, true); + } + } + + return false; + } + + // If the IP retrieval method is not set. + $configured_ip_method_id = $aio_wp_security->configs->get_value('aiowps_ip_retrieve_method'); + if ('' === $configured_ip_method_id) { + return true; + } + + $server_user_ip_address = AIOS_Helper::get_server_detected_user_ip_address(); + return empty($server_user_ip_address); + } + + /** + * Whether the current page is the AIOS IP retrieval admin page + * + * @return Boolean True if the current page is the AIOS database backup admin page, otherwise false. + */ + private function is_ip_settings_admin_page_tab() { + return $this->is_settings_admin_page() && $this->is_advanced_settings_tab(); + } + + /** + * Whether the current page is the AIOS settings admin page + * + * @return Boolean True if the current page is the AIOS settings admin page, otherwise false. + */ + private function is_settings_admin_page() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No nonce to check. + return ('admin.php' == $GLOBALS['pagenow'] && isset($_GET['page']) && 'aiowpsec_settings' == $_GET['page']); + } + + /** + * Whether the current tab is the advanced settings tab. + * + * @return Boolean True if the current tab is the advanced settings tab, otherwise false. + */ + private function is_advanced_settings_tab() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No nonce to check. + return (isset($_GET['tab']) && 'advanced-settings' == $_GET['tab']); + } + + /** + * Check whether the UpdraftPlus plugin is active or not. + * + * @return bool True if the UpdraftPlus plugin is active, otherwise false. + */ + private function is_updraftplus_plugin_active() { + return class_exists('UpdraftPlus'); + } + + /** + * Check whether the database backup scheduled in the UpdraftPlus plugin. + * + * @return bool + */ + private function is_schedule_database_backup_set_in_updraftplus() { + $updraft_interval_database_option_val = get_option('updraft_interval_database', ''); + if (empty($updraft_interval_database_option_val) || 'manual' == $updraft_interval_database_option_val) { + return false; + } + + return true; + } + + /** + * Decides whether to show the IP Blacklist settings notice. + * + * @return Boolean True if the IP Blacklist settings notice should be shown, otherwise false. + */ + protected function should_show_ip_blacklist_settings_on_upgrade() { + if (!is_main_site()) { + return false; + } + + if ($this->is_blacklist_admin_page()) { + return false; + } + + global $aio_wp_security; + + if ('1' == $aio_wp_security->configs->get_value('aiowps_is_ip_blacklist_settings_notice_on_upgrade')) { + return true; + } + + return false; + } + + /** + * Whether the current page is the AIOS blacklist admin page + * + * @return Boolean True if the current page is the AIOS blacklist admin page, otherwise false. + */ + private function is_blacklist_admin_page() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No nonce to check. + return ('admin.php' == $GLOBALS['pagenow'] && isset($_GET['page']) && AIOWPSEC_FIREWALL_MENU_SLUG == $_GET['page'] && isset($_GET['tab']) && 'blacklist' == $_GET['tab']); + } + + /** + * Decides whether to show the IP address detection settings notice. + * + * @return Boolean True if the IP address detection settings notice should be shown, otherwise false. + */ + protected function should_show_login_whitelist_disabled_on_upgrade_notice() { + if (!is_main_site()) { + return false; + } + + if ($this->is_login_whitelist_admin_page_tab()) { + return false; + } + + if (defined('AIOS_FORCE_LOGIN_WHITELIST_DISABLED_ON_UPGRADE_NOTICE') && AIOS_FORCE_LOGIN_WHITELIST_DISABLED_ON_UPGRADE_NOTICE) { + return true; + } + + global $aio_wp_security; + + if ('1' == $aio_wp_security->configs->get_value('aiowps_is_login_whitelist_disabled_on_upgrade') && '1' != $aio_wp_security->configs->get_value('aiowps_enable_whitelisting')) { + return true; + } + + return false; + } + + /** + * Whether the current page is the AIOS IP retrieval admin page + * + * @return Boolean True if the current page is the AIOS database backup admin page, otherwise false. + */ + private function is_login_whitelist_admin_page_tab() { + return $this->is_brute_force_admin_page() && $this->is_login_whitelist_tab(); + } + + /** + * Whether the current page is the AIOS settings admin page + * + * @return Boolean True if the current page is the AIOS settings admin page, otherwise false. + */ + private function is_brute_force_admin_page() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No nonce to check. + return ('admin.php' == $GLOBALS['pagenow'] && isset($_GET['page']) && AIOWPSEC_BRUTE_FORCE_MENU_SLUG == $_GET['page']); + } + + /** + * Whether the current tab is the advanced settings tab. + * + * @return Boolean True if the current tab is the advanced settings tab, otherwise false. + */ + private function is_login_whitelist_tab() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No nonce to check. + return (isset($_GET['tab']) && 'login-whitelist' == $_GET['tab']); + } + + /** + * Call this method to setup the notices + */ + public function notices_init() { + if ($this->initialized) return; + $this->initialized = true; + $this->notices_content = $this->populate_notices_content(); + + $enqueue_version = (defined('WP_DEBUG') && WP_DEBUG) ? AIO_WP_SECURITY_VERSION.'.'.time() : AIO_WP_SECURITY_VERSION; + wp_enqueue_style('aiowpsec-admin-notices-css', AIO_WP_SECURITY_URL.'/css/wp-security-notices.css', array(), $enqueue_version); + } + + /** + * Get AIOS Plugin installation timestamp. + * + * @return integer AIOS Plugin installation timestamp. + */ + public function get_aiowps_plugin_installed_timestamp() { + $installed_at = @filemtime(AIO_WP_SECURITY_PATH.'/index.html'); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore warning as we handle it below + if (false === $installed_at) { + global $aio_wp_security; + $installed_at = (int) $aio_wp_security->configs->get_value('installed-at'); + } + $installed_at = apply_filters('aiowps_plugin_installed_timestamp', $installed_at); + return $installed_at; + } + + /** + * This function will check if we should display the rate notice or not + * + * @return boolean - to indicate if we should show the notice or not + */ + protected function show_rate_notice() { + $installed_at = $this->get_aiowps_plugin_installed_timestamp(); + $time_now = $this->get_time_now(); + $installed_for = $time_now - $installed_at; + + if ($installed_at && $installed_for > 28*86400) { + return true; + } + + return false; + } + + /** + * Checks if UpdraftPlus is installed(returns false) or not(returns true). + * + * @return Boolean + */ + protected function updraftplus_not_installed() { + if (!function_exists('get_plugins')) include_once(ABSPATH.'wp-admin/includes/plugin.php'); + $plugins = get_plugins(); + + foreach ($plugins as $value) { + if ('updraftplus' == $value['TextDomain']) { + return false; + } + } + return true; + } + + /** + * Checks if WP-Optimize is installed(returns false) or not(returns true). + * + * @return Boolean + */ + protected function wp_optimize_not_installed() { + if (!function_exists('get_plugins')) include_once(ABSPATH.'wp-admin/includes/plugin.php'); + $plugins = get_plugins(); + + foreach ($plugins as $value) { + if ('wp-optimize' == $value['TextDomain']) { + return false; + } + } + return true; + } + + /** + * Determines whether to prepare a seasonal notice(returns true) or not(returns false). + * + * @param Array $notice_data - all data for the notice + * + * @return Boolean + */ + protected function skip_seasonal_notices($notice_data) { + $time_now = $this->get_time_now(); + $valid_from = strtotime($notice_data['valid_from']); + $valid_to = strtotime($notice_data['valid_to']); + $dismiss = $this->check_notice_dismissed($notice_data['dismiss_time']); + if (($time_now >= $valid_from && $time_now <= $valid_to) && !$dismiss) { + // return true so that we return this notice to be displayed + return true; + } + + return false; + } + + /** + * Get timestamp that is considered as current timestamp for notice. + * + * @return integer timestamp that should be consider as a current time. + */ + public function get_time_now() { + $time_now = defined('AIOWPSECURITY_NOTICES_FORCE_TIME') ? AIOWPSECURITY_NOTICES_FORCE_TIME : time(); + return $time_now; + } + + /** + * Checks whether a notice is dismissed(returns true) or not(returns false). + * + * @param String $dismiss_time - dismiss time id for the notice + * + * @return boolean + */ + protected function check_notice_dismissed($dismiss_time) { + $time_now = $this->get_time_now(); + + global $aio_wp_security; + $dismiss = ($time_now < (int) $aio_wp_security->configs->get_value($dismiss_time)); + + return $dismiss; + } + + /** + * Renders or returns a notice. + * + * @param Boolean|String $advert_information - all data for the notice + * @param Boolean $return_instead_of_echo - whether to return the notice(true) or render it to the page(false) + * @param String $position - notice position + * + * @return Void|String + */ + protected function render_specified_notice($advert_information, $return_instead_of_echo = false, $position = 'top') { + + if ('bottom' == $position) { + $template_file = 'bottom-notice.php'; + } elseif ('report' == $position) { + $template_file = 'report.php'; + } elseif ('report-plain' == $position) { + $template_file = 'report-plain.php'; + } elseif (in_array($position, AIOS_Abstracted_Ids::custom_admin_notice_ids())) { + $template_file = 'custom-notice.php'; + } elseif (in_array($position, AIOS_Abstracted_Ids::htaccess_to_php_feature_notice_ids())) { + $template_file = 'htaccess-to-php-feature-notice.php'; + } else { + $template_file = 'horizontal-notice.php'; + } + + global $aio_wp_security; + return $aio_wp_security->include_template('notices/'.$template_file, $return_instead_of_echo, $advert_information); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-process-renamed-login-page.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-process-renamed-login-page.php new file mode 100755 index 00000000..5a28ef4e --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-process-renamed-login-page.php @@ -0,0 +1,293 @@ +aiowps_filter_wp_login_file($url); + } + + public function aiowps_wp_redirect($location) { + return $this->aiowps_filter_wp_login_file($location); + } + + /** + * Filter register link on the login page + * + * @param string $registration_url + * @return string + */ + public function register_link($registration_url) { + return $this->aiowps_filter_wp_login_file($registration_url); + } + + /** + * Filter confirm link so we hide the secret login slug in the export_personal_data email + * + * @param string $email_text + * @param string $email_data + * @return string + */ + public function aiowps_user_request_email_content($email_text, $email_data) { + global $aio_wp_security; + if (isset($email_data['request']) && isset($email_data['request']->action_name)) { + if ('export_personal_data' == $email_data['request']->action_name) { + $confirm_url = $email_data['confirm_url']; + $login_slug = $aio_wp_security->configs->get_value('aiowps_login_page_slug'); + if (get_option('permalink_structure')) { + $new_confirm_url = str_replace($login_slug, 'wp-login.php', $confirm_url); + } else { + $search_pattern = '?'.$login_slug.'&action'; + $new_confirm_url = str_replace($search_pattern, '/wp-login.php/?action', $confirm_url); + } + + $email_text_modified = str_replace('###CONFIRM_URL###', esc_url_raw($new_confirm_url), $email_text); + return $email_text_modified; + } + } + return $email_text; + } + + /** + * Filter all login url strings on the login page + * + * @param string $url + * @return string + */ + public function aiowps_filter_wp_login_file($url) { + if (strpos($url, 'wp-login.php') !== false) { + $args = explode('?', $url); + if (isset($args[1])) { + if (strpos($args[1], 'action=postpass') !== false) { + return $url; //Don't reveal the secret URL in the post password action url + } + parse_str($args[1], $args); + $url = esc_url(add_query_arg($args, AIOWPSecurity_Process_Renamed_Login_Page::new_login_url())); + $url = html_entity_decode($url); + } elseif (isset($_SERVER['REQUEST_URI']) && stripos(urldecode(sanitize_url(wp_unslash($_SERVER['REQUEST_URI']))), 'wp-admin/install.php')) { + return $url; + } else { + $url = AIOWPSecurity_Process_Renamed_Login_Page::new_login_url(); + } + } + return $url; + } + + /** + * Login page renamed related tasks, do not allow access if not logged with rename login page. + * + * @return void + */ + public static function renamed_login_init_tasks() { + // Bail if the host cron job is running by running the command "php wp-cron.php" + // The $_SERVER['REQUEST_URI'] is undefined when running a PHP file from the command line. + // for `wp plugin list` it will be empty so showing Not available instead plugin list. + if (empty($_SERVER['REQUEST_URI']) || defined('WP_CLI') || 'cli' == PHP_SAPI || wp_doing_cron() || wp_doing_ajax()) { + return; + } + + global $aio_wp_security; + + //The following will process the native wordpress post password protection form + //Normally this is done by wp-login.php file but we cannot use that since the login page has been renamed + + // Bots with URLs like: /index.php?action[]=aaaa will return an array here. It needs to be a string. + $action = (isset($_GET['action']) && is_string($_GET['action'])) ? sanitize_text_field(wp_unslash($_GET['action'])) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No nonce available. + // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing -- No nonce available. + if (isset($_POST['post_password']) && 'postpass' == $action) { + + // Check if the captcha is enabled for the password protected pages and process validation if the login page was renamed + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_password_protected_captcha')) { + $aio_wp_security->captcha_obj->validate_password_protected_password_form_with_captcha(); + } + + require_once ABSPATH . 'wp-includes/class-phpass.php'; + $hasher = new PasswordHash(8, true); + + /** + * Filter the life span of the post password cookie. + * + * By default, the cookie expires 10 days from creation. To turn this + * into a session cookie, return 0. + * + * @since 3.7.0 + * + * @param int $expires The expiry time, as passed to setcookie(). + */ + $expire = apply_filters('post_password_expires', time() + 10 * DAY_IN_SECONDS); + // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- No nonce available, not recommended to sanitize passwords. + setcookie('wp-postpass_' . COOKIEHASH, $hasher->HashPassword(wp_unslash($_POST['post_password'])), $expire, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true); + + wp_safe_redirect(wp_get_referer()); + exit(); + } + + //case where someone attempting to reach wp-admin + if (is_admin() && !is_user_logged_in() && (isset($_SERVER["SCRIPT_FILENAME"]) ? basename(sanitize_text_field(wp_unslash($_SERVER["SCRIPT_FILENAME"]))) : '') !== 'admin-post.php') { + //Fix to prevent fatal error caused by some themes and Yoast SEO + do_action('aiowps_before_wp_die_renamed_login'); + wp_die(esc_html__('You do not have permission to access this page.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('Please log in and try again.', 'all-in-one-wp-security-and-firewall'), 403); + } + + //case where someone attempting to reach wp-login + if (isset($_SERVER['REQUEST_URI']) && stripos(urldecode(sanitize_url(wp_unslash($_SERVER['REQUEST_URI']))), 'wp-login.php') && !is_user_logged_in()) { + + // Handle export personal data request for rename login case + if (isset($_GET['request_id'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce available. + $request_id = (int) sanitize_text_field(wp_unslash($_GET['request_id'])); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce available. + $result = ''; + if (isset($_GET['confirm_key'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce available. + $key = sanitize_text_field(wp_unslash($_GET['confirm_key'])); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce available. + $result = wp_validate_user_request_key($request_id, $key); + } else { + $result = new WP_Error('invalid_key', esc_html__('Invalid key', 'all-in-one-wp-security-and-firewall')); + } + + if (is_wp_error($result)) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. $result is WPError object with sanitized strings. + wp_die($result); + } elseif (!empty($result)) { + _wp_privacy_account_request_confirmed($request_id); + $message = _wp_privacy_account_request_confirmed_message($request_id); + login_header(__('User action confirmed.', 'all-in-one-wp-security-and-firewall'), $message); + login_footer(); + exit; + } + } + + //Check if the maintenance (lockout) mode is active - if so prevent access to site by not displaying 404 page! + if ($aio_wp_security->configs->get_value('aiowps_site_lockout') == '1') { + AIOWPSecurity_WP_Loaded_Tasks::site_lockout_tasks(); + } else { + AIOWPSecurity_Process_Renamed_Login_Page::aiowps_set_404(); + } + } + + //case where someone attempting to reach the standard register or signup pages + $request_uri = urldecode(sanitize_url(wp_unslash($_SERVER['REQUEST_URI']))); + if ('' !== $request_uri && stripos($request_uri, 'wp-register.php') || '' !== $request_uri && stripos($request_uri, 'wp-signup.php')) { + //Check if the maintenance (lockout) mode is active - if so prevent access to site by not displaying 404 page! + if ('1' == $aio_wp_security->configs->get_value('aiowps_site_lockout')) { + AIOWPSecurity_WP_Loaded_Tasks::site_lockout_tasks(); + } else { + AIOWPSecurity_Process_Renamed_Login_Page::aiowps_set_404(); + } + } + + $login_slug = $aio_wp_security->configs->get_value('aiowps_login_page_slug'); + + if (self::is_renamed_login_page_requested($login_slug)) { + if (empty($action) && is_user_logged_in()) { + //if user is already logged in but tries to access the renamed login page, send them to the dashboard + // or to requested redirect-page, filtered in 'login_redirect'. + if (isset($_REQUEST['redirect_to'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce available. + $redirect_to = wp_sanitize_redirect(wp_unslash($_REQUEST['redirect_to'])); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce available. + $redirect_to = wp_validate_redirect($redirect_to, apply_filters('wp_safe_redirect_fallback', admin_url(), 302)); + $requested_redirect_to = $redirect_to; + } else { + $redirect_to = admin_url(); + $requested_redirect_to = ''; + } + $redirect_to = apply_filters('login_redirect', $redirect_to, $requested_redirect_to, wp_get_current_user()); + AIOWPSecurity_Utility::redirect_to_url($redirect_to); + } else { + global $wp_version; + do_action('aiowps_rename_login_load'); + // logout action called by WooCommerce does not apply the login whitelist which shows a 403 error for the customer + if (!(isset($_GET['action']) && 'logout' == $_GET['action'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce available. + AIOWPSecurity_Utility_IP::check_login_whitelist_and_forbid(); + } + + status_header(200); + if (version_compare($wp_version, '6.6', '>=')) { + require_once(AIO_WP_SECURITY_PATH . '/other-includes/wp-security-rename-login-feature.php'); + } elseif (version_compare($wp_version, '5.7', '>=')) { + require_once(AIO_WP_SECURITY_PATH . '/other-includes/wp-security-rename-login-feature-pre-6-6.php'); + } elseif (version_compare($wp_version, '5.2', '>=')) { + require_once(AIO_WP_SECURITY_PATH . '/other-includes/wp-security-rename-login-feature-pre-5-7.php'); + } else { + require_once(AIO_WP_SECURITY_PATH . '/other-includes/wp-security-rename-login-feature-pre-5-2.php'); + } + + die; + } + } + } + + public static function new_login_url() { + global $aio_wp_security; + $login_slug = $aio_wp_security->configs->get_value('aiowps_login_page_slug'); + if (get_option('permalink_structure')) { + return trailingslashit(trailingslashit(home_url()) . $login_slug); + } else { + return trailingslashit(site_url()) . '?' . $login_slug; + } + } + + public static function aiowps_set_404() { + global $wp_query; + do_action('aiowps_before_set_404'); // This hook is for themes which produce a fatal error when the rename login feature is enabled and someone visits "wp-admin" slug directly + + status_header(404); + $wp_query->set_404(); + do_action('template_redirect'); // Trigger 'template_redirect' to allow third-party plugins to intercept and inject custom logic before rendering the fallback template. + + $template = get_404_template(); + if (empty($template)) $template = get_index_template(); + $template = apply_filters('template_include', $template); + if ($template) include($template); + die; + } + + /** + * Check renamed login page is requested + * + * @param string $login_slug Renamed loginpage slug + * + * @return boolean + */ + public static function is_renamed_login_page_requested($login_slug) { + + if (empty($_SERVER['REQUEST_URI'])) return false; + + $parsed_url_path = isset($_SERVER['REQUEST_URI']) ? wp_parse_url(sanitize_url(wp_unslash($_SERVER['REQUEST_URI'])), PHP_URL_PATH) : ''; + $home_url_with_slug = home_url($login_slug, 'relative'); + + /* + * Compatibility fix for WPML, TranslatePress plugin + */ + if (function_exists('wpml_object_id') || function_exists('trp_enable_translatepress')) { + $home_url_with_slug = home_url($login_slug); + $parsed_home_url_with_slug = wp_parse_url($home_url_with_slug); + $home_url_with_slug = $parsed_home_url_with_slug['path']; //this will return just the path minus the protocol and host + } + + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce available. + if (untrailingslashit($parsed_url_path) === $home_url_with_slug || (!get_option('permalink_structure') && isset($_GET[$login_slug]))) { + return true; + } + + return false; + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-reporting.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-reporting.php new file mode 100755 index 00000000..b5bf996d --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-reporting.php @@ -0,0 +1,60 @@ + $value) { + $sanitized_key = esc_html($key); + $sanitized_value = esc_html($value); + $sanitized_section_content[$sanitized_key] = $sanitized_value; + } + + if ('text' === $output_format) { + $data .= "\n --- $section_title --- \n\n"; + $data .= self::output_section_data($sanitized_section_content); + $data .= "\n===================================\n"; + } elseif ('table' === $output_format) { + $data .= '
'; + $data .= '

'; + $data .= '
'; + $data .= apply_filters('aiowp_security_report_section_content', AIOWPSecurity_Utility_UI::format_data_as_table($sanitized_section_content)); + $data .= '
'; + $data .= '
'; + } + + $data = apply_filters('aiowp_security_generate_report_section_below', $data); + + return $data; + } + + /** + * Output the section data + * + * @param array $section_data Section data to output + * + * @return string Section data + */ + private static function output_section_data($section_data = array()) { + $output = ''; + foreach ($section_data as $key => $value) { + $output .= "$key - $value\n"; + } + return $output; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-sender-service.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-sender-service.php new file mode 100755 index 00000000..794a7600 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-sender-service.php @@ -0,0 +1,29 @@ +configs->set_value('aiowps_enable_basic_firewall', '1', true); + + //Now let's write the applicable rules to the .htaccess file + if (AIOWPSecurity_Utility::allow_to_write_to_htaccess()) { + $res = AIOWPSecurity_Utility_Htaccess::write_to_htaccess(); + } else { + $res = true; + } + + if ($res) { + $msg['updated'] = __('Settings were successfully saved.', 'all-in-one-wp-security-and-firewall'); + } else { + /* translators: %s: .htaccess path */ + $msg['error'] = sprintf(__('Could not write to the %s file.', 'all-in-one-wp-security-and-firewall'), AIOWPSecurity_Utility_File::get_home_path().'.htaccess') . ' ' . __('Please check the file permissions.', 'all-in-one-wp-security-and-firewall'); + } + return $msg; + } + + /** + * Disable all security features. + * + * @return array messages + */ + public static function disable_all_security_features() { + $msg = array(); + AIOWPSecurity_Configure_Settings::turn_off_all_security_features(); + + //Now let's clear the applicable rules from the .htaccess file + if (AIOWPSecurity_Utility::allow_to_write_to_htaccess()) { + $res = AIOWPSecurity_Utility_Htaccess::write_to_htaccess(); + } else { + $res = true; + } + + //Now let's revert the disable editing setting in the wp-config.php file if necessary + $res2 = AIOWPSecurity_Utility::enable_file_edits(); + + if ($res) { + $msg['updated'] = __('All the security features have been disabled successfully.', 'all-in-one-wp-security-and-firewall'); + } else { + /* translators: %s: .htaccess path */ + $msg['error'][] = sprintf(__('Could not write to the %s file.', 'all-in-one-wp-security-and-firewall'), AIOWPSecurity_Utility_File::get_home_path().'.htaccess') . ' ' . sprintf(__('Please restore it manually using the restore functionality in the "%s" tab.', 'all-in-one-wp-security-and-firewall'), '.htaccess ' . __('file', 'all-in-one-wp-security-and-firewall')); + } + + if (!$res2) { + /* translators: %s: wp-config.php path */ + $msg['error'][] = sprintf(__('Could not write to the %s file.', 'all-in-one-wp-security-and-firewall'), AIOWPSecurity_Utility_File::get_home_path().'wp-config.php') . ' ' . sprintf(__('Please restore it manually using the restore functionality in the "%s" tab.', 'all-in-one-wp-security-and-firewall'), 'wp-config.php ' . __('file', 'all-in-one-wp-security-and-firewall')); + } + return $msg; + } + + /** + * Disable all firewall rules. + * + * @return array messages + */ + public static function disable_all_firewall_rules() { + $msg = array(); + AIOWPSecurity_Configure_Settings::turn_off_firewall_configs(); + + //Now let's clear the applicable rules from the .htaccess file + if (AIOWPSecurity_Utility::allow_to_write_to_htaccess()) { + $res = AIOWPSecurity_Utility_Htaccess::write_to_htaccess(); + } else { + $res = true; + } + + if ($res) { + $msg['updated'] = __('All firewall rules have been disabled successfully.', 'all-in-one-wp-security-and-firewall'); + } else { + /* translators: %s: .htaccess path, %s file tab name. */ + $msg['error'] = sprintf(__('Could not write to the %s file.', 'all-in-one-wp-security-and-firewall'), AIOWPSecurity_Utility_File::get_home_path().'.htaccess') . ' ' . sprintf(__('Please restore it manually using the restore functionality in the "%s" tab.', 'all-in-one-wp-security-and-firewall'), '.htaccess ' . __('file', 'all-in-one-wp-security-and-firewall')); + } + return $msg; + } + + /** + * Reset all settings. + * + * @return array messages + */ + public static function reset_all_settings() { + $msg = array(); + if (!class_exists('AIOWPSecurity_Reset_Settings')) { + include(AIO_WP_SECURITY_PATH . '/admin/wp-security-reset-settings.php'); + } + $reset_option_res = AIOWPSecurity_Reset_Settings::reset_options(); + if (AIOWPSecurity_Utility::allow_to_write_to_htaccess()) { + $delete_htaccess = AIOWPSecurity_Reset_Settings::delete_htaccess(); + } else { + $delete_htaccess = true; + } + AIOWPSecurity_Reset_Settings::reset_db_tables(); + // AIOS premium and other plugin related config settings are reset by adding below action. + do_action('aios_reset_all_settings'); + + if (false === $reset_option_res && false === $delete_htaccess) { + $msg['error'] = __('Deletion of aio_wp_security_configs option and .htaccess directives failed.', 'all-in-one-wp-security-and-firewall'); + } elseif (false === $reset_option_res) { + $msg['error'] = __('Reset of aio_wp_security_configs option failed.', 'all-in-one-wp-security-and-firewall'); + } elseif (false === $delete_htaccess) { + $msg['error'] = __('Deletion of .htaccess directives failed.', 'all-in-one-wp-security-and-firewall'); + } else { + $msg['updated'] = __('All settings have been successfully reset.', 'all-in-one-wp-security-and-firewall'); + } + return $msg; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-two-factor-login.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-two-factor-login.php new file mode 100755 index 00000000..91729b0b --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-two-factor-login.php @@ -0,0 +1,201 @@ +is_incompatible_plugin_active()) return; + + if (!function_exists('mcrypt_get_iv_size') && !function_exists('openssl_cipher_iv_length')) { + add_action('all_admin_notices', array($this, 'admin_notice_missing_mcrypt_and_openssl')); + return; + } + + $this->is_tfa_integrated = true; + + // Run at a priority ensuring that this will be after AIOS has registered its translation domain + add_action('init', array($this, 'plugin_text_domain_loaded'), 11); + + add_action('admin_menu', array($this, 'menu_entry_for_user'), 30); + $this->version = AIO_WP_SECURITY_VERSION; + $this->set_user_settings_page_slug(AIOWPSEC_TWO_FACTOR_AUTH_MENU_SLUG); + + $this->set_plugin_translate_url('https://translate.wordpress.org/projects/wp-plugins/all-in-one-wp-security-and-firewall/'); + $this->set_site_wide_administration_url(admin_url('admin.php?page=aiowpsec_settings&tab=two-factor-authentication')); + $this->set_premium_version_url('https://teamupdraft.com/all-in-one-security/pricing/?utm_source=aios-plugin&utm_medium=referral&utm_campaign=paac&utm_content=emergency-codes-feature&utm_creative_format=text'); + $this->set_faq_url('https://wordpress.org/plugins/all-in-one-wp-security-and-firewall/#faq'); + parent::__construct(); + } + + /** + * Runs upon the WP action init (once the text domain has been loaded) + */ + public function plugin_text_domain_loaded() { + $this->set_settings_page_heading(__('Two factor authentication - Admin settings', 'all-in-one-wp-security-and-firewall')); + } + + /** + * Detect plugins that cause us to self-deactivate + * + * @return Boolean|String + */ + private function is_incompatible_plugin_active() { + + if (defined('WORDFENCE_LS_VERSION')) return 'Wordfence Login Security'; + + $active_plugins = $this->get_active_plugins(); + foreach ($active_plugins as $plugin_file_rel_to_plugins_dir) { + $temp_plugin_file_name = substr($plugin_file_rel_to_plugins_dir, strpos($plugin_file_rel_to_plugins_dir, '/') + 1); + if ('wordfence-login-security.php' == $temp_plugin_file_name) { + return 'Wordfence Login Security'; + } + if ('wordfence.php' == $temp_plugin_file_name) { + return 'Wordfence'; + } + } + return false; + } + + /** + * Gets an array of plugins active on either the current site, or site-wide + * + * @return Array - a list of plugin paths (relative to the plugin directory) + */ + private function get_active_plugins() { + + // Gets all active plugins on the current site + $active_plugins = get_option('active_plugins'); + + if (is_multisite()) { + $network_active_plugins = get_site_option('active_sitewide_plugins'); + if (!empty($network_active_plugins)) { + $network_active_plugins = array_keys($network_active_plugins); + $active_plugins = array_merge($active_plugins, $network_active_plugins); + } + } + + return $active_plugins; + } + + /** + * Runs upon the WP actions admin_menu and network_admin_menu + */ + public function menu_entry_for_user() { + + global $current_user; + if ($this->is_activated_for_user($current_user->ID)) { + if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) { + $menu_icon_url = AIO_WP_SECURITY_URL . '/images/aios-plugin-icon.svg'; + add_menu_page(__('AIOS', 'all-in-one-wp-security-and-firewall'), __('AIOS', 'all-in-one-wp-security-and-firewall'), apply_filters('aios_management_permission', 'manage_options'), AIOWPSEC_MAIN_MENU_SLUG, '', $menu_icon_url); + } + add_submenu_page(AIOWPSEC_MAIN_MENU_SLUG, __('Two Factor Auth', 'all-in-one-wp-security-and-firewall'), __('Two Factor Auth', 'all-in-one-wp-security-and-firewall'), 'read', AIOWPSEC_TWO_FACTOR_AUTH_MENU_SLUG, array($this, 'show_dashboard_user_settings_page')); + } + } + + /** + * AIOS settings based user IP address + * + * @return string IP address + */ + public function aios_set_user_ip_address() { + return AIOS_Helper::get_user_ip_address(); + } + + /** + * Builds Two Factor Authentication tab + * + * @param array $tabs array that contain tab name and call back function + * @return array Returns all tabs with callback function name + */ + public function add_two_factor_setting_tab($tabs = array()) { + if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) return; + + $tabs['two-factor-authentication'] = array( + 'title' => __('Two factor authentication', 'all-in-one-wp-security-and-firewall'), + 'render_callback' => array($this, 'render_two_factor_authentication'), + 'display_condition_callback' => 'is_main_site', + ); + return $tabs; + } + + /** + * Display the Two Factor Authentication tab & handle the operations + */ + public function render_two_factor_authentication() { + $plugin = $this->is_incompatible_plugin_active(); + if (false !== $plugin) { + global $aio_wp_security; + $aio_wp_security->include_template('admin/incompatible-plugin.php', false, array( + 'incompatible_plugin' => $plugin, + )); + return; + } + + $this->show_admin_settings_page(); + } + + /** + * Include the admin settings page code. + */ + public function show_admin_settings_page() { + + if (!is_admin() || !AIOWPSecurity_Utility_Permissions::has_manage_cap()) return; + + // Check if there are any settings errors and display them (this is needed because the forms from this template submit to the TFA options page not AIOS, so we need to grab them and output them manually). + $settings_errors = get_settings_errors(); + foreach ($settings_errors as $error) { + $type = 'success' == $error['type'] ? 'updated' : 'error'; + $this->show_admin_warning($error['message'], $type); + } + + // The value for totp_controller is already set by versions of the TFA plugin after 3 Oct 2022 + $this->include_template('admin-settings.php', array( + 'totp_controller' => $this->get_controller('totp'), + 'settings_page_heading' => $this->get_settings_page_heading(), + 'admin_settings_links' => array(), + )); + } + + /** + * Runs conditionally on the WP action all_admin_notices. + */ + public function admin_notice_missing_mcrypt_and_openssl() { + $this->show_admin_warning(''.__('PHP OpenSSL or mcrypt module required', 'all-in-one-wp-security-and-firewall').'
'.__('The All-In-One Security plugin\'s Two Factor Authentication module requires either the PHP openssl (preferred) or mcrypt module to be installed.', 'all-in-one-wp-security-and-firewall') . ' ' . __('Please ask your web hosting company to install one of them.', 'all-in-one-wp-security-and-firewall'), 'error'); + } +} + +if (false === AIOWPSecurity_Utility::is_incompatible_tfa_premium_version_active() && false === AIOWPSecurity_Utility::is_tfa_or_self_plugin_activating()) { + $GLOBALS['simba_two_factor_authentication'] = new AIO_WP_Security_Simba_Two_Factor_Authentication_Plugin(); +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-uninstallation-tasks.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-uninstallation-tasks.php new file mode 100755 index 00000000..8c70157b --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-uninstallation-tasks.php @@ -0,0 +1,83 @@ +prefix.'aiowps_login_lockdown', + $wpdb->prefix.'aiowps_failed_logins', + $wpdb->prefix.'aiowps_login_activity', + $wpdb->prefix.'aiowps_global_meta', + $wpdb->prefix.'aiowps_events', + $wpdb->prefix.'aiowps_permanent_block', + $wpdb->prefix.'aiowps_debug_log', + $wpdb->prefix.'aiowps_audit_log', + $wpdb->prefix.'aiowps_logged_in_users', + $wpdb->prefix.'aiowps_message_store', + ); + + $aio_wp_security->configs->load_config(); + + // check and drop database tables + if ('1' == $aio_wp_security->configs->get_value('aiowps_on_uninstall_delete_db_tables')) { + foreach ($database_tables as $table_name) { + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $wpdb->query("DROP TABLE IF EXISTS `$table_name`"); + } + } + + // check and delete configurations + if ('1' == $aio_wp_security->configs->get_value('aiowps_on_uninstall_delete_configs')) { + if (is_main_site()) { + $firewall_rules_path = AIOWPSecurity_Utility_Firewall::get_firewall_rules_path(); + AIOWPSecurity_Utility_File::remove_local_directory($firewall_rules_path); + + delete_metadata('user', '0', 'aiowps_account_status', '', true); + delete_metadata('user', '0', 'aiowps_registrant_ip', '', true); + } + + delete_option('aio_wp_security_configs'); + delete_option('aiowpsec_db_version'); + delete_option('aiowpsec_firewall_version'); + delete_option('aios_antibot_key_map_info'); + } + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-user-login.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-user-login.php new file mode 100755 index 00000000..a809416d --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-user-login.php @@ -0,0 +1,1022 @@ +key_login_msg = 'aiowps_login_msg_id'; + // As a first authentication step, check if user's IP is locked. + add_filter('authenticate', array($this, 'block_ip_if_locked'), 1, 1); + // Check whether user needs to be manually approved after default WordPress authenticate hooks (with priority 20). + add_filter('authenticate', array($this, 'check_manual_registration_approval'), 30, 1); + // Check login CAPTCHA + if ($aio_wp_security->configs->get_value('aiowps_enable_login_captcha')) { + add_filter('authenticate', array($this, 'check_captcha'), 20, 1); + } + // As a last authentication step, perform post authentication steps + add_filter('authenticate', array($this, 'post_authenticate'), 100, 3); + add_action('aiowps_force_logout_check', array($this, 'aiowps_force_logout_action_handler')); + add_action('wp_logout', array($this, 'wp_logout_action_handler'), 10, 1); + add_filter('login_message', array($this, 'aiowps_login_message')); //WP filter to add or modify messages on the login page + + // Display disable lockdown message + if (is_admin() && AIOWPSecurity_Utility_Permissions::has_manage_cap() && $aio_wp_security->is_login_lockdown_by_const() && $this->is_admin_page_to_display_disable_login_lockdown_by_const_notice()) { + add_action('all_admin_notices', array($this, 'disable_login_lockdown_by_const_notice')); + } + + add_action('set_auth_cookie', array($this, 'handle_logged_in_user'), 10, 4); + + //cron job to remove expired users from logged_in table + add_action('delete_expired_logged_in_users_event', array($this, 'delete_expired_logged_in_users')); + + add_filter('retrieve_password_message', array($this, 'aiowps_retrieve_password_message'), 10, 1); + } + + /** + * Check whether the admin page is to display disable login lockdown by const notice. + * + * @return boolean True if the notice will be displayed, Otherwise false. + */ + private function is_admin_page_to_display_disable_login_lockdown_by_const_notice() { + global $pagenow; + if (in_array($pagenow, array('index.php', 'plugins.php'))) { + return true; + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. Ignore. + } elseif (('admin.php' == $pagenow && isset($_GET['page']) && false !== strpos(sanitize_title(wp_unslash($_GET['page'])), AIOWPSEC_MENU_SLUG_PREFIX)) && !$this->is_locked_ip_addresses_tab_admin_page()) { + return true; + } + return false; + } + + /** + * Check whether the admin page is Locked IP Addresses Tab page. + * + * @return boolean True if is Locked IP Addresses Tab page, Otherwise false. + */ + private function is_locked_ip_addresses_tab_admin_page() { + global $pagenow; + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce. + return ('admin.php' == $pagenow && isset($_GET['page']) && 'aiowpsec' == $_GET['page'] && isset($_GET['tab']) && 'locked-ip' == $_GET['tab']); + } + + /** + * Displays admin to disable lockdown message. + * + * @return Void + */ + public function disable_login_lockdown_by_const_notice() { + + if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) { + return; + } + + echo '
+

'. + esc_html__('You have disabled login lockout by defining the AIOS_DISABLE_LOGIN_LOCKOUT constant value as true, and the login lockout setting has enabled it.', 'all-in-one-wp-security-and-firewall') . ' ' . + /* translators: 1: Locked IP Addresses admin page link */ + sprintf(esc_html__('Delete your login lockout IP from %s and define the AIOS_DISABLE_LOGIN_LOCKOUT constant value as false.', 'all-in-one-wp-security-and-firewall'), + '' . esc_html__('Locked IP addresses', 'all-in-one-wp-security-and-firewall') . '' + ). + '

+
'; + } + + /** + * Terminate the execution via wp_die with 503 status code, if current + * user's IP is currently locked. + * + * @global AIO_WP_Security $aio_wp_security + * @param WP_Error|WP_User $user + * @return WP_User + */ + public function block_ip_if_locked($user) { + global $aio_wp_security; + + // Allow users to login when disable AIOWPS_DISABLE_LOCK_DOWN defined true + if ($aio_wp_security->is_login_lockdown_by_const()) { + return $user; + } + + $user_locked = $this->check_locked_user(); + if (null != $user_locked) { + $aio_wp_security->debug_logger->log_debug("Login attempt from blocked IP range - ".$user_locked['failed_login_ip'], 2); + // Allow the error message to be filtered. + /* translators: %s: Error notification with strong HTML tag. */ + $error_msg = apply_filters('aiowps_ip_blocked_error_msg', sprintf(__('%s: Access from your IP address has been blocked for security reasons.', 'all-in-one-wp-security-and-firewall'), '' . __('ERROR', 'all-in-one-wp-security-and-firewall') . '') . ' ' . __('Please contact the administrator.', 'all-in-one-wp-security-and-firewall')); + // If unlock requests are allowed, add the "Request Unlock" button to the message. + $unlock_form = ''; + if ($aio_wp_security->configs->get_value('aiowps_allow_unlock_requests') == '1') { + $unlock_form = $this->get_unlock_request_form(); + $error_msg .= $unlock_form; + } + $error_msg = apply_filters('aiowps_ip_blocked_output_page', $error_msg, $unlock_form); //filter the complete output of the locked page + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP Error. Can not escape form html inside $error_msg. + wp_die($error_msg, esc_html__('Service temporarily unavailable', 'all-in-one-wp-security-and-firewall'), 503); + } else { + return $user; + } + } + + /** + * Check login CAPTCHA (if enabled). + * + * @global AIO_WP_Security $aio_wp_security + * @param WP_Error|WP_User $user + * @return WP_Error|WP_User + */ + public function check_captcha($user) { + global $aio_wp_security; + if (is_wp_error($user) || $aio_wp_security->is_login_lockdown_by_const()) { + // Authentication has failed already at some earlier step. + return $user; + } + + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- PCP warning. No nonce. + if (! (isset($_POST['log']) && isset($_POST['pwd']))) { + // XML-RPC authentication (not via wp-login.php), nothing to do here. + return $user; + } + + if ($aio_wp_security->configs->get_value('aiowps_enable_login_captcha') != '1') { + // CAPTCHA not enabled, nothing to do here. + return $user; + } + + /* translators: %s: Error notification with strong HTML tag. */ + $captcha_error = new WP_Error('authentication_failed', sprintf(__('%s: Your answer was incorrect - please try again.', 'all-in-one-wp-security-and-firewall'), '' . __('ERROR', 'all-in-one-wp-security-and-firewall') . '')); + $verify_captcha = $aio_wp_security->captcha_obj->verify_captcha_submit(); + if (false === $verify_captcha) { + return $captcha_error; + } + return $user; + } + + /** + * Check, whether $user needs to be manually approved by site admin yet. + * + * @global AIO_WP_Security $aio_wp_security + * @param WP_Error|WP_User $user + * @return WP_Error|WP_User + */ + public function check_manual_registration_approval($user) { + global $aio_wp_security; + if (!($user instanceof WP_User)) { + // Not a WP_User - nothing to do here. + return $user; + } + //Check if auto pending new account status feature is enabled + if ($aio_wp_security->configs->get_value('aiowps_enable_manual_registration_approval') == '1') { + $aiowps_account_status = get_user_meta($user->ID, 'aiowps_account_status', true); + if ('pending' == $aiowps_account_status) { + // Account needs to be activated yet + /* translators: %s: Notification with strong HTML tag. */ + return new WP_Error('account_pending', sprintf(__('%s: Your account is currently not active.', 'all-in-one-wp-security-and-firewall'), '' . __('ACCOUNT PENDING', 'all-in-one-wp-security-and-firewall') . '') . ' '. __('An administrator needs to activate your account before you can login.', 'all-in-one-wp-security-and-firewall')); + } + } + return $user; + } + + /** + * Handle post authentication steps (in case of failed login): + * - increment number of failed logins for $username + * - (optionally) lock the user + * - (optionally) display a generic error message + * + * @global AIO_WP_Security $aio_wp_security + * @param WP_Error|WP_User $user + * @param string $username + * @param string $password + * @return WP_Error|WP_User + */ + public function post_authenticate($user, $username, $password) { + global $aio_wp_security; + if (!is_wp_error($user)) { + // Authentication has been successful, there's nothing to do here. + return $user; + } + if (empty($username) || empty($password)) { + // Neither log nor block login attempts with empty username or password. + return $user; + } + if ($user->get_error_code() === 'account_pending') { + // Neither log nor block users attempting to log in before their registration is approved. + return $user; + } + // Login failed for non-trivial reason + AIOWPSecurity_Audit_Events::event_failed_login($username); + if ($aio_wp_security->configs->get_value('aiowps_enable_login_lockdown') == '1') { + $is_whitelisted = false; + //check if lockout whitelist enabled + if ($aio_wp_security->configs->get_value('aiowps_lockdown_enable_whitelisting') == '1') { + $whitelisted_ips = $aio_wp_security->configs->get_value('aiowps_lockdown_allowed_ip_addresses'); + $is_whitelisted = AIOWPSecurity_Utility_IP::is_userip_whitelisted($whitelisted_ips); + } + + if (false === $is_whitelisted) { + // Too many failed logins from user's IP? + $login_attempts_permitted = absint($aio_wp_security->configs->get_value('aiowps_max_login_attempts')); + $too_many_failed_logins = $login_attempts_permitted <= $this->get_login_fail_count(); + + // Is an invalid username or email the reason for login error? + $invalid_username = ($user->get_error_code() === 'invalid_username' || $user->get_error_code() == 'invalid_email'); + // Should an invalid username be immediately locked? + $invalid_username_lockdown = $aio_wp_security->configs->get_value('aiowps_enable_invalid_username_lockdown') == '1'; + $lock_invalid_username = $invalid_username && $invalid_username_lockdown; + + // Should an invalid username be blocked as per blacklist? + $instant_lockout_users_list = $aio_wp_security->configs->get_value('aiowps_instantly_lockout_specific_usernames'); + if (!is_array($instant_lockout_users_list)) { + $instant_lockout_users_list = array(); + } + $username_blacklisted = $invalid_username && in_array($username, $instant_lockout_users_list); + + $lock_reasons = array(); + if ($too_many_failed_logins) { + $lock_reasons[] = 'too_many_failed_logins'; + } + if ($lock_invalid_username) { + $lock_reasons[] = 'invalid_username'; + } + if ($username_blacklisted) { + $lock_reasons[] = 'username_blacklisted'; + } + if ($lock_reasons) { + $this->lock_the_user($username, implode(',', $lock_reasons)); + } + } + } + + if ($aio_wp_security->configs->get_value('aiowps_set_generic_login_msg') == '1') { + // Return generic error message if configured + return new WP_Error('authentication_failed', __('ERROR: Invalid login credentials.', 'all-in-one-wp-security-and-firewall')); + } + return $user; + } + /** + * This function queries the aiowps_login_lockdown table. + * If the release_date has not expired AND the current visitor IP addr matches + * it will return a record + */ + public function check_locked_user() { + global $wpdb; + $login_lockdown_table = AIOWPSEC_TBL_LOGIN_LOCKOUT; + $ip = AIOWPSecurity_Utility_IP::get_user_ip_address(); //Get the IP address of user + if (empty($ip)) return false; + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $locked_user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $login_lockdown_table WHERE `released` > UNIX_TIMESTAMP() AND `failed_login_ip` = %s", $ip), ARRAY_A); + return $locked_user; + } + /** + * This function queries the aiowps_audit_log table and returns the number of failures for current IP range within allowed failure period + */ + public function get_login_fail_count() { + + global $wpdb, $aio_wp_security; + + $audit_log_table = AIOWPSEC_TBL_AUDIT_LOG; + $login_retry_interval = $aio_wp_security->configs->get_value('aiowps_retry_time_period') * 60; + $now = time(); + $ip = AIOWPSecurity_Utility_IP::get_user_ip_address(); // Get the users IP address + + if (empty($ip)) return false; + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $login_failures = $wpdb->get_var("SELECT COUNT(ID) FROM $audit_log_table " . "WHERE created + " . esc_sql($login_retry_interval) . " > '" . esc_sql($now) . "' AND " . "ip = '" . esc_sql($ip) . "' AND event_type = 'failed_login'"); + return $login_failures; + } + + /** + * Get lockout time dynamically multiplied with default lockout time + * + * @return Integer get lockout time length. + */ + public function get_dynamic_lockout_time_length() { + global $aio_wp_security; + + $login_fail_count = $this->get_login_fail_count(); + $lockout_time_default = $aio_wp_security->configs->get_value('aiowps_lockout_time_length'); + if (!is_numeric($lockout_time_default)) { + $lockout_time_default = 5; + } + $lockout_time_max = $aio_wp_security->configs->get_value('aiowps_max_lockout_time_length'); + if (!is_numeric($lockout_time_max)) { + $lockout_time_max = 60; + } + $lockout_time_length = (int) ($login_fail_count > 0 ? (3 * $lockout_time_default * ($login_fail_count + 1)) : $lockout_time_default); + + return $lockout_time_length >= $lockout_time_max ? $lockout_time_max : $lockout_time_length; + } + + /** + * Adds an entry to the `aiowps_login_lockdown` table. + * + * @param string $username User's username or email + * @param string $lock_reason + * @param bool $is_lockout_email_sent flag for lockout email send + */ + public function lock_the_user($username, $lock_reason = 'login_fail', $is_lockout_email_sent = 0) { + global $aio_wp_security; + $login_lockdown_table = AIOWPSEC_TBL_LOGIN_LOCKOUT; + $lock_minutes = $this->get_dynamic_lockout_time_length(); + $ip = AIOWPSecurity_Utility_IP::get_user_ip_address(); //Get the IP address of user + if (empty($ip)) return; + $ip_range = AIOWPSecurity_Utility_IP::get_sanitized_ip_range($ip); //Get the IP range of the current user + $user = is_email($username) ? get_user_by('email', $username) : get_user_by('login', $username); //Returns WP_User object if exists + $ip_range = apply_filters('aiowps_before_lockdown', $ip_range); + if ($user) { + //If the login attempt was made using a valid user set variables for DB storage later on + $user_id = $user->ID; + } else { + //If the login attempt was made using a non-existent user then let's set user_id to blank and record the attempted user login name for DB storage later on + $user_id = 0; + } + + $lock_time = current_time('mysql', true); + $date = new DateTime($lock_time); + $add_interval = 'PT'.absint($lock_minutes).'M'; + $date->add(new DateInterval($add_interval)); + $release_time = $date->format('Y-m-d H:i:s'); + $backtrace_log = ''; + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_php_backtrace_in_email')) { + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace, PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection -- PCP and compatibility warnings. Safe to ignore. + $backtrace_log = AIOWPSecurity_Utility::normalise_call_stack_args(debug_backtrace()); + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r -- PCP warning. Ignore. + $backtrace_log = print_r($backtrace_log, true); + } + $is_lockout_email_sent = (1 == $aio_wp_security->configs->get_value('aiowps_enable_email_notify') ? 0 : -1); + $ip_lookup_result = AIOS_Helper::get_ip_reverse_lookup($ip); + $ip_lookup_result = wp_json_encode($ip_lookup_result); + if (false === $ip_lookup_result) $ip_lookup_result = null; + + $lock_seconds = $lock_minutes * MINUTE_IN_SECONDS; + + $data = array( + 'user_id' => $user_id, + 'user_login' => $username, + 'lockdown_date' => $lock_time, + 'release_date' => $release_time, + 'failed_login_IP' => $ip, + 'lock_reason' => $lock_reason, + 'is_lockout_email_sent' => $is_lockout_email_sent, + 'backtrace_log' => $backtrace_log, + 'ip_lookup_result' => $ip_lookup_result, + 'lock_seconds' => $lock_seconds + ); + + $result = AIOWPSecurity_Utility::add_lockout($data); + + if (false === $result) { + $aio_wp_security->debug_logger->log_debug("Error inserting record into ".$login_lockdown_table, 4); + } else { + do_action('aiowps_lockdown_event', $ip_range, $username); + $aio_wp_security->debug_logger->log_debug("The following IP address range has been locked out for exceeding the maximum login attempts: ".$ip_range, 2); + } + } + + /** + * Send IP Lock notification. + * + * @param Array $lockout_ips_list have username, ip_range, ip + * @param String $backtrace_filepath + * + * @return Boolean True if mail sent otherwise false. + */ + private function send_ip_lock_notification_email($lockout_ips_list = array(), $backtrace_filepath = '') { + global $aio_wp_security; + $send_mail = false; + if (0 != count($lockout_ips_list)) { + $email_notification_enabled = $aio_wp_security->configs->get_value('aiowps_enable_email_notify'); + if (1 == $email_notification_enabled) { + $to_email_address = AIOWPSecurity_Utility::get_array_from_textarea_val($aio_wp_security->configs->get_value('aiowps_email_address')); + if (empty($to_email_address)) { + $to_email_address = array(get_site_option('admin_email')); + } + $subject = '['.get_option('home').'] '. __('Site Lockout Notification', 'all-in-one-wp-security-and-firewall'); + $email_msg = __('User login lockout events had occurred due to too many failed login attempts or invalid username:', 'all-in-one-wp-security-and-firewall')."\n\n"; + + foreach ($lockout_ips_list as $lockout_ip) { + /* translators: %s: User name. */ + $email_msg .= sprintf(__('Username: %s', 'all-in-one-wp-security-and-firewall'), $lockout_ip['username']) . "\n"; + + /* translators: %s: IP Address. */ + $email_msg .= sprintf(__('IP address: %s', 'all-in-one-wp-security-and-firewall'), $lockout_ip['ip']) . "\n"; + if ('' != $lockout_ip['ip_range']) { + /* translators: %s: IP Range. */ + $email_msg .= sprintf(__('IP range: %s', 'all-in-one-wp-security-and-firewall'), $lockout_ip['ip_range']) . '.*' . "\n"; + } + if (!empty($lockout_ip['ip_lookup_result'])) { + $ip_lookup_result = json_decode($lockout_ip['ip_lookup_result'], true); + + $org = empty($ip_lookup_result['org']) ? __('Not Found', 'all-in-one-wp-security-and-firewall') : $ip_lookup_result['org']; + $as = empty($ip_lookup_result['as']) ? __('Not Found', 'all-in-one-wp-security-and-firewall') : $ip_lookup_result['as']; + + /* translators: %s: Org. */ + $email_msg .= sprintf(__('Org: %s', 'all-in-one-wp-security-and-firewall'), $org) . "\n"; + /* translators: %s: AS. */ + $email_msg .= sprintf(__('AS: %s', 'all-in-one-wp-security-and-firewall'), $as) . "\n"; + + $email_msg = apply_filters('aiowps_login_lockdown_email_message', $email_msg, $ip_lookup_result); + } + $email_msg .= "\n"; + } + + $email_msg .= __("Log into your site WordPress administration panel to see the duration of the lockout or to unlock the user.", 'all-in-one-wp-security-and-firewall') . "\n"; + + $email_header = ''; + $send_mail = wp_mail($to_email_address, $subject, $email_msg, $email_header, $backtrace_filepath); + + if (false === $send_mail) { + $ips_list = implode(', ', wp_list_pluck($lockout_ips_list, 'ip')); + $aio_wp_security->debug_logger->log_debug("Lockout notification email failed to send to " . implode(', ', $to_email_address) . " for IPs ".$ips_list, 4); + } + } + } + return $send_mail; + } + + /** + * Generates and returns an unlock request link which will be used to send to the user. + * + * @global type $wpdb + * @global AIO_WP_Security $aio_wp_security + * @param type $ip_range + * @return string or false on failure + */ + public static function generate_unlock_request_link($ip_range) { + //Get the locked user row from locout table + global $wpdb, $aio_wp_security; + $unlock_link = ''; + $lockout_table_name = AIOWPSEC_TBL_LOGIN_LOCKOUT; + $secret_rand_key = (md5(uniqid(wp_rand(), true))); + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP wanting. Ignore. + $res = $wpdb->query($wpdb->prepare("UPDATE $lockout_table_name SET unlock_key = %s WHERE released > UNIX_TIMESTAMP() AND failed_login_ip LIKE %s", $secret_rand_key, "%" . esc_sql($ip_range) . "%")); + if (null == $res) { + $aio_wp_security->debug_logger->log_debug("No locked user found with IP range ".$ip_range, 4); + return false; + } else { + // Check if unlock request or submitted from a WooCommerce account login page + if (isset($_POST['aiowps-woo-login'])) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- PCP warning. No nonce. + $date_time = current_time('mysql'); + $data = array('date_time' => $date_time, 'meta_key1' => 'woo_unlock_request_key', 'meta_value1' => $secret_rand_key); + $aiowps_global_meta_tbl_name = AIOWPSEC_TBL_GLOBAL_META_DATA; + // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.QuotedSimplePlaceholder, WordPress.DB.PreparedSQL.NotPrepared -- PCP error. Direct query required. Table name cannot be prepared pre WP 6.2. + $sql = $wpdb->prepare("INSERT INTO ".$aiowps_global_meta_tbl_name." (date_time, meta_key1, meta_value1, created) VALUES ('%s', '%s', '%s', UNIX_TIMESTAMP())", $data['date_time'], $data['meta_key1'], $data['meta_value1']); + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Prepared above. + $result = $wpdb->query($sql); + if (false === $result) { + $aio_wp_security->debug_logger->log_debug("generate_unlock_request_link() - Error inserting woo_unlock_request_key to AIOWPSEC_TBL_GLOBAL_META_DATA table for secret key ".$secret_rand_key, 4); + } + } + $query_param = array('aiowps_auth_key' => $secret_rand_key); + $wp_site_url = AIOWPSEC_WP_URL; + $unlock_link = esc_url(add_query_arg($query_param, $wp_site_url)); + } + return $unlock_link; + } + + /** + * This function will process an unlock request when someone clicks on the special URL + * It will check if the special random code matches that in lockdown table for the relevant user + * If so, it will unlock the user + * + * @param string $unlock_key + * @return void + */ + public static function process_unlock_request($unlock_key) { + global $wpdb, $aio_wp_security; + $lockout_table_name = AIOWPSEC_TBL_LOGIN_LOCKOUT; + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- PCP error. Direct query required. Table name cannot be prepared pre WP 6.2. + $unlock_command = $wpdb->prepare("UPDATE ".$lockout_table_name." SET released = UNIX_TIMESTAMP() WHERE unlock_key = %s", $unlock_key); + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Prepared above. + $result = $wpdb->query($unlock_command); + if (false === $result) { + $aio_wp_security->debug_logger->log_debug("Error unlocking user with unlock_key ".$unlock_key, 4); + } else { + // Now check if this unlock operation is for a WooCommerce login + $aiowps_global_meta_tbl_name = AIOWPSEC_TBL_GLOBAL_META_DATA; + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- PCP error. Direct query required. Table name cannot be prepared pre WP 6.2. + $sql = $wpdb->prepare("SELECT * FROM $aiowps_global_meta_tbl_name WHERE meta_key1=%s AND meta_value1=%s", 'woo_unlock_request_key', $unlock_key); + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Prepared above. + $woo_result = $wpdb->get_row($sql, OBJECT); + if (empty($woo_result)) { + $woo_unlock = false; + } else { + $woo_unlock = true; + } + if ($aio_wp_security->configs->get_value('aiowps_enable_rename_login_page')=='1') { + if (get_option('permalink_structure')) { + $home_url = trailingslashit(home_url()); + } else { + $home_url = trailingslashit(home_url()) . '?'; + } + if ($woo_unlock) { + $login_url = wc_get_page_permalink('myaccount'); //redirect to woo login page if applicable + //Now let's cleanup after ourselves and delete the woo-related row in the AIOWPSEC_TBL_GLOBAL_META_DATA table + // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore + $delete = $wpdb->delete($aiowps_global_meta_tbl_name, array('meta_key1' => 'woo_unlock_request_key', 'meta_value1' => $unlock_key)); + if (false === $delete) { + $aio_wp_security->debug_logger->log_debug("process_unlock_request(): Error deleting row from AIOWPSEC_TBL_GLOBAL_META_DATA for meta_key1=woo_unlock_request_key and meta_value1=".$unlock_key, 4); + } + } else { + $login_url = $home_url.$aio_wp_security->configs->get_value('aiowps_login_page_slug'); + } + + AIOWPSecurity_Utility::redirect_to_url($login_url); + } else { + AIOWPSecurity_Utility::redirect_to_url(wp_login_url()); + } + } + } + + /** + * This function sends an unlock request email to a locked out user + * + * @param string $email + * @param string $unlock_link + * @return void + */ + public static function send_unlock_request_email($email, $unlock_link) { + global $aio_wp_security; + $subject = '['.network_site_url().'] '. __('Unlock request notification', 'all-in-one-wp-security-and-firewall'); + /* translators: 1: Email 2: Link */ + $email_msg = sprintf(__('You have requested for the account with email address %s to be unlocked.', 'all-in-one-wp-security-and-firewall') . ' ' . __('Please press the link below to unlock your account:', 'all-in-one-wp-security-and-firewall'), $email) . "\n" . sprintf(__('Unlock link: %s', 'all-in-one-wp-security-and-firewall'), $unlock_link) . "\n\n" . __('After pressing the above link you will be able to login to the WordPress administration panel.', 'all-in-one-wp-security-and-firewall') . "\n"; + + $sendMail = wp_mail($email, $subject, $email_msg); + if (false === $sendMail) { + $aio_wp_security->debug_logger->log_debug("Unlock Request Notification email failed to send to " . $email, 4); + } + } + + /** + * Check the settings and log the user after the configured time period + * + * @param bool $return_url Optional. If true, the function returns the logout URL with a nonce. + * Otherwise, it redirects to the logout URL. Default is false. + * + * @return void|string + */ + public function aiowps_force_logout_action_handler($return_url = false) { + global $aio_wp_security; + //$aio_wp_security->debug_logger->log_debug("Force Logout - Checking if any user need to be logged out..."); + //if this feature is enabled then do something + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_forced_logout')) { + if (is_user_logged_in()) { + $current_user = wp_get_current_user(); + $user_id = $current_user->ID; + $current_time = current_time('mysql', true); + $login_time = $this->get_wp_user_aiowps_last_login_time($user_id); + if (empty($login_time)) { + return; + } + $diff = strtotime($current_time) - strtotime($login_time); + $logout_time_interval_value = $aio_wp_security->configs->get_value('aiowps_logout_time_period'); + $logout_time_interval_val_seconds = $logout_time_interval_value * 60; + if ($diff > $logout_time_interval_val_seconds) { + $aio_wp_security->debug_logger->log_debug("Force Logout - This user logged in more than (".$logout_time_interval_value.") minutes ago. Doing a force log out for the user with username: ".$current_user->user_login); + $this->wp_logout_action_handler($user_id); //this will register the logout time/date in the logout_date column + + + $curr_page_url = AIOWPSecurity_Utility::get_current_page_url(); + $after_logout_payload = array('redirect_to' => $curr_page_url, 'msg' => $this->key_login_msg.'=session_expired'); + //Save some of the logout redirect data to a transient + is_multisite() ? set_site_transient('aiowps_logout_payload', $after_logout_payload, 30 * 60) : set_transient('aiowps_logout_payload', $after_logout_payload, 30 * 60); + $logout_url = AIOWPSEC_WP_URL.'?aiowpsec_do_log_out=1'; + $logout_url = AIOWPSecurity_Utility::add_query_data_to_url($logout_url, 'al_additional_data', '1'); + $logout_url_with_nonce = html_entity_decode(wp_nonce_url($logout_url, 'aio_logout')); + if ($return_url) { + return $logout_url_with_nonce; + } + AIOWPSecurity_Utility::redirect_to_url($logout_url_with_nonce); + } + } + } + } + + /** + * Get last logged in time of given user id. + * + * @param integer $user_id + * @return mixed Last login time. False for an invalid $user_id (non-numeric, zero, or negative value). An empty string if a valid but non-existing user ID is passed. + */ + public function get_wp_user_aiowps_last_login_time($user_id) { + $last_login = apply_filters('aiowps_get_last_login_time', get_user_meta($user_id, 'aiowps_last_login_time', true), $user_id); + return $last_login; + } + + /** + * Updates the last login time in user meta, the login activity table. + * + * @global wpdb $wpdb + * @global AIO_WP_Security $aio_wp_security + * + * @param string $user_login + * @param WP_User $user + * + * @return void + */ + private static function update_login_activity($user_login, $user) { + AIOWPSecurity_Audit_Events::event_successful_login($user_login); + $login_date_time = current_time('mysql', true); + + update_user_meta($user->ID, 'aiowps_last_login_time', $login_date_time); //store last login time in meta table + } + + /** + * Remove the last login time for all users from meta table on deactivation. + * + * @return void + */ + public static function remove_login_activity() { + delete_metadata('user', '0', 'aiowps_last_login_time', '', true); //remove from meta table for all users last login time + } + + public static function wp_login_action_handler($user_login, $user = '') { + global $aio_wp_security; + + if ('' == $user) { + //Try and get user object + $user = get_user_by('login', $user_login); //This should return WP_User obj + if (!$user) { + $aio_wp_security->debug_logger->log_debug("AIOWPSecurity_User_Login::wp_login_action_handler: Unable to get WP_User object for login ".$user_login, 4); + return; + } + } + + if (is_super_admin($user->ID)) { + $logging_into_correct_site = true; + } else { + $user_sites = get_blogs_of_user($user->ID); + + $current_site_id = get_current_blog_id(); + + $logging_into_correct_site = false; + + foreach ($user_sites as $site) { + if ($site->userblog_id == $current_site_id) { + $logging_into_correct_site = true; + break; + } + } + } + + if ($logging_into_correct_site) { + self::update_login_activity($user_login, $user); + } else { + $user_primary_site = get_active_blog_for_user($user->ID); + switch_to_blog($user_primary_site->blog_id); + self::update_login_activity($user_login, $user); + + restore_current_blog(); + } + } + + /** + * Handles logout events and modifies the login activity record for the current user. + * + * @param int $user_id - ID of user logging out + * @param boolean $force_logout - if user is force logged out + * + * @return void + */ + public function wp_logout_action_handler($user_id, $force_logout = false) { + global $aio_wp_security; + $user = get_userdata($user_id); + + if (false === $user) { + $aio_wp_security->debug_logger->log_debug("AIOWPSecurity_User_Login::wp_logout_action_handler: Unable to get WP_User object", 4); + return; + } + + $this->delete_logged_in_user($user->ID); + + if (is_super_admin($user->ID)) { + $logging_out_of_correct_site = true; + } else { + $user_sites = get_blogs_of_user($user->ID); + + $current_site_id = get_current_blog_id(); + + $logging_out_of_correct_site = false; + + foreach ($user_sites as $site) { + if ($site->userblog_id == $current_site_id) { + $logging_out_of_correct_site = true; + break; + } + } + } + + if ($logging_out_of_correct_site) { + AIOWPSecurity_Audit_Events::event_successful_logout($user->user_login, $force_logout); + } else { + $user_primary_site = get_active_blog_for_user($user->ID); + switch_to_blog($user_primary_site->blog_id); + AIOWPSecurity_Audit_Events::event_successful_logout($user->user_login, $force_logout); + + restore_current_blog(); + } + } + + /** + * The handler for the WP "login_message" filter + * Adds custom messages to the other messages that appear above the login form. + * + * NOTE: This method is automatically called by WordPress for displaying + * text above the login form. + * + * @param string $message the output from earlier login_message filters + * @return string + */ + public function aiowps_login_message($message = '') { + global $aio_wp_security; + $msg = ''; + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No nonce. + if (isset($_GET[$this->key_login_msg]) && !empty($_GET[$this->key_login_msg])) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No nonce. + $logout_msg = wp_strip_all_tags(sanitize_title(wp_unslash($_GET[$this->key_login_msg]))); + } + if (!empty($logout_msg)) { + switch ($logout_msg) { + case 'session_expired': + /* translators: %s: Minute count */ + $msg = sprintf(__('Your session has expired because it has been over %d minutes since your last login.', 'all-in-one-wp-security-and-firewall'), $aio_wp_security->configs->get_value('aiowps_logout_time_period')); + $msg .= ' ' . __('Please log back in to continue.', 'all-in-one-wp-security-and-firewall'); + break; + case 'admin_user_changed': + $msg = __('You were logged out because you just changed the "admin" username.', 'all-in-one-wp-security-and-firewall'); + $msg .= ' ' . __('Please log back in to continue.', 'all-in-one-wp-security-and-firewall'); + break; + default: + } + } + if (!empty($msg)) { + $msg = htmlspecialchars($msg, ENT_QUOTES, 'UTF-8'); + $message .= ''; + } + return $message; + } + /** + * This function will generate an unlock request form to be inserted inside + * error message when user gets locked out. + * + * @return string + */ + public function get_unlock_request_form() { + global $aio_wp_security; + $unlock_request_form = ''; + //Let's encode some hidden data and make a form + $unlock_secret_string = $aio_wp_security->configs->get_value('aiowps_unlock_request_secret_key'); + $current_time = time(); + $enc_result = base64_encode($current_time.$unlock_secret_string); + $unlock_request_form .= '
'; + $unlock_request_form .= ''; + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- No nonce. + if (isset($_POST['woocommerce-login-nonce'])) { + $unlock_request_form .= ''; + } + $unlock_request_form .= '
'; + return $unlock_request_form; + } + + /** + * Returns all logged in users for specific subsite of multisite installation. + * + * @param bool $sitewide - checks if logged in users should be fetched sitewide + * + * @return array + */ + public static function get_logged_in_users($sitewide = true) { + global $wpdb; + + $logged_in_users_table = AIOWPSEC_TBL_LOGGED_IN_USERS; + if ($sitewide) { + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $users_online = $wpdb->get_results("SELECT * FROM `{$logged_in_users_table}`", 'ARRAY_A'); + } else { + $current_blog_id = get_current_blog_id(); + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $users_online = $wpdb->get_results($wpdb->prepare("SELECT * FROM `{$logged_in_users_table}` WHERE site_id = %d", $current_blog_id), 'ARRAY_A'); + } + + if (empty($users_online)) return array(); + + return $users_online; + } + + /** + * Send email notification to an user that has flag is_lockout_email_sent is 0. + * + * @return Void + */ + public function send_login_lockout_emails() { + global $wpdb, $aio_wp_security; + // if user enabled notification email then only have to send + $email_notification_enabled = $aio_wp_security->configs->get_value('aiowps_enable_email_notify'); + if (0 == $email_notification_enabled) { + return; + } + // get recent lockout records on top to notify + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- PCP error. Direct query required. + $sql = $wpdb->prepare('SELECT id, user_login, failed_login_ip, backtrace_log, ip_lookup_result FROM ' .AIOWPSEC_TBL_LOGIN_LOCKOUT. ' WHERE is_lockout_email_sent = %d ORDER BY id DESC', 0); + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Prepared above. + $result = $wpdb->get_results($sql); + if (empty($result)) { + return; + } + $login_lockout_ids_send_emails = array(); + $lockout_ips_backtrace_log = array(); + $lockout_ips_list = array(); + $backtrace_filepath = ''; + foreach ($result as $row) { + $ip_range = AIOWPSecurity_Utility_IP::get_sanitized_ip_range($row->failed_login_ip); + $lockout_ips_list[] = array('username' => $row->user_login, 'ip' => $row->failed_login_ip, 'ip_range' => $ip_range, 'ip_lookup_result' => $row->ip_lookup_result); + $login_lockout_ids_send_emails[] = $row->id; + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_php_backtrace_in_email') && '' != $row->backtrace_log) { + $lockout_ips_backtrace_log[] = array('backtrace_log' => $row->backtrace_log); + } + } + + if (0 != count($lockout_ips_backtrace_log)) { + $backtrace_filepath = AIOWPSecurity_Utility::login_lockdown_email_backtrace_log_file($lockout_ips_backtrace_log); + } + + $this->send_ip_lock_notification_email($lockout_ips_list, $backtrace_filepath); + + if ('' != $backtrace_filepath) { + wp_delete_file($backtrace_filepath); + } + + if (!empty($login_lockout_ids_send_emails)) { + $aio_wp_security->debug_logger->log_debug(sprintf('The IP lock notification emails of login lockout ids [%s] are sent.', implode(', ', $login_lockout_ids_send_emails)), 4); + // update all email to as sent. + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- PCP error. Direct query required. Table name cannot be prepared pre WP 6.2. + $sql = $wpdb->prepare('UPDATE '.AIOWPSEC_TBL_LOGIN_LOCKOUT.' SET is_lockout_email_sent = %d WHERE is_lockout_email_sent = %d', 1, 0); + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Prepared above. + $update_result = $wpdb->query($sql); + if (false === $update_result) { + $error_msg = empty($wpdb->last_error) ? 'Could not receive the reason for the failure' : $wpdb->last_error; + $aio_wp_security->debug_logger->log_debug_cron("Lockout email flag is not updated in database due to error: {$error_msg}", 4); + } + } + } + + /** + * Stores logged-in user in the logged_in_user table + * + * @param int $user_id - id of user logging in + * @param int $expiration - expiration timestamp of cookie + * + * @return void + */ + public function store_logged_in_user($user_id, $expiration) { + global $wpdb, $aio_wp_security; + + $logged_in_users_table = AIOWPSEC_TBL_LOGGED_IN_USERS; + $ip_address = AIOWPSecurity_Utility_IP::get_user_ip_address(); + $userdata = get_userdata($user_id); + $username = $userdata->user_login; + $login_time = time(); + + // Check if a record with the given user_id already exists + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Direct query required. Table name cannot be prepared pre WP 6.2. + $existing_record = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . $logged_in_users_table . " WHERE user_id = %d", $user_id)); + + if ($existing_record) { + // Update the existing record + // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $result = $wpdb->update( + $logged_in_users_table, + array( + 'ip_address' => $ip_address, + 'site_id' => get_current_blog_id(), + 'username' => $username, + 'expires' => $expiration + ), + array('user_id' => $user_id) + ); + } else { + // Create a new record + // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $result = $wpdb->insert( + $logged_in_users_table, + array( + 'user_id' => $user_id, + 'ip_address' => $ip_address, + 'expires' => $expiration, + 'site_id' => get_current_blog_id(), + 'username' => $username, + 'created' => $login_time + ) + ); + } + + if (false === $result) { + $generic_error_message = $existing_record ? "Error updating record in " . $logged_in_users_table : "Error inserting record into ".$logged_in_users_table; + $error_message = empty($wpdb->last_error) ? $generic_error_message : $wpdb->last_error; + $aio_wp_security->debug_logger->log_debug($error_message, 4); + } + } + + /** + * Handles the data coming from the 'set_auth_cookie' hook + * + * @param string $auth_cookie - the generated auth_cookie + * @param int $expire - expiration timestamp of cookie if remember is marked + * @param int $expiration - expiration timestamp of cookie + * @param int $user_id - id of user logging in + * + * @return void + */ + public function handle_logged_in_user($auth_cookie, $expire, $expiration, $user_id) { + + if (empty($auth_cookie)) return; //check if auth cookie is empty, meaning login was not successful + $expiration = $expire > 0 ? $expire : $expiration; + + if (is_multisite() && !is_super_admin()) { + $user_blog = get_active_blog_for_user($user_id); + switch_to_blog($user_blog->blog_id); // switch to user blog incase they try to log in from wrong subsite + + $this->store_logged_in_user($user_id, $expiration); + restore_current_blog(); + } else { + $this->store_logged_in_user($user_id, $expiration); + } + } + + /** + * Deletes logged-in user from the logged_in_user table + * + * @param int $user_id + * @return bool + */ + public function delete_logged_in_user($user_id) { + global $wpdb, $aio_wp_security; + + $logged_in_users_table = AIOWPSEC_TBL_LOGGED_IN_USERS; + + if (empty($user_id)) return true; + + // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $result = $wpdb->delete( + $logged_in_users_table, + array('user_id' => $user_id) + ); + + + if (false === $result) { + $error_message = empty($wpdb->last_error) ? "Error deleting record from " . $logged_in_users_table : $wpdb->last_error; + $aio_wp_security->debug_logger->log_debug($error_message, 4); + } + + return $result; + } + + /** + * Cron job function for removing data with expired session from the logged-in user table + * + * @return void + */ + public function delete_expired_logged_in_users() { + global $wpdb, $aio_wp_security; + $logged_in_users_table = AIOWPSEC_TBL_LOGGED_IN_USERS; + + // Delete data with expired cookie + // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- PCP warning. Direct query required, + $result = $wpdb->query( + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- PCP error. Direct query required. Table name cannot be prepared pre WP 6.2. + $wpdb->prepare("DELETE FROM " . $logged_in_users_table . " WHERE expires < %d", time()) + ); + + if (false === $result) { + $error_message = empty($wpdb->last_error) ? "Error deleting records from ".$logged_in_users_table : $wpdb->last_error; + $aio_wp_security->debug_logger->log_debug($error_message, 4); + } + } + + /** + * This function rewrites the password reset message + * + * @param string $message - The password reset email message to be edited + * + * @return string - Email message to be sent for password reset + */ + public function aiowps_retrieve_password_message($message) { + $ip = AIOWPSecurity_Utility_IP::get_user_ip_address(); //Get the IP address of user + + // Find the position of the IP Address string in the message + $ip_string = isset($_SERVER['REMOTE_ADDR']) ? rest_is_ip_address(wp_unslash($_SERVER['REMOTE_ADDR'])) : ''; + $ip_pos = strpos($message, $ip_string); + + // If the IP Address string is found in the message and not the same as AIOWPS ip, replace it with the replacement string + if (false !== $ip_pos && $ip !== $ip_string) { + $replacement = "$ip.\r\n\r\n"; + $message = substr_replace($message, $replacement, $ip_pos); + } + + return $message; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-user-registration.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-user-registration.php new file mode 100755 index 00000000..879b2dfe --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-user-registration.php @@ -0,0 +1,100 @@ +configs->get_value('aiowps_enable_manual_registration_approval') == '1') { + add_filter("woocommerce_registration_auth_new_customer", array($this, 'aios_registration_auth_new_customer')); + } + + if ($aio_wp_security->configs->get_value('aiowps_enable_registration_page_captcha') == '1') { + add_filter('registration_errors', array($this, 'aiowps_validate_registration_with_captcha'), 10, 3); + } + } + + /** + * This public function will add a special meta string in the users table + * Meta field name: 'aiowps_account_status' + * Meta field value: 'pending' + * + * @param int $user_id + * @return void + */ + public function aiowps_user_registration_action_handler($user_id) { + global $aio_wp_security; + //Check if auto pending new account status feature is enabled + if ($aio_wp_security->configs->get_value('aiowps_enable_manual_registration_approval') == '1') { + if (AIOWPSecurity_Utility_Permissions::has_manage_cap() || (defined('WP_CLI') && WP_CLI)) { + AIOWPSecurity_Audit_Events::event_user_registration($user_id, 'admin'); + return; //if the user has been added from admin side don't put in pending state + } + $res = add_user_meta($user_id, 'aiowps_account_status', 'pending'); + if (!$res) { + $aio_wp_security->debug_logger->log_debug("aiowps_user_registration_action_handler: Error adding user meta data: aiowps_account_status", 4); + } + $user_ip_address = AIOWPSecurity_Utility_IP::get_user_ip_address(); + $res = add_user_meta($user_id, 'aiowps_registrant_ip', $user_ip_address); + if (!$res) { + $aio_wp_security->debug_logger->log_debug("aiowps_user_registration_action_handler: Error adding user meta data: aiowps_registrant_ip", 4); + } + AIOWPSecurity_Audit_Events::event_user_registration($user_id, 'pending'); + } else { + if (AIOWPSecurity_Utility_Permissions::has_manage_cap()) { + AIOWPSecurity_Audit_Events::event_user_registration($user_id, 'admin'); + } else { + AIOWPSecurity_Audit_Events::event_user_registration($user_id, 'registered'); + } + } + } + + /** + * This public function will set the special meta string in the usermeta table so that the account becomes active + * Meta field name: 'aiowps_account_status' + * Meta field values: 'active', 'pending', etc + * + * @param int $user_id + * @param string $status + * @return void + */ + public function aiowps_set_user_account_status($user_id, $status) { + global $aio_wp_security; + $res = update_user_meta($user_id, 'aiowps_account_status', $status); + if (!$res) { + $aio_wp_security->debug_logger->log_debug("aiowps_set_user_account_status: Error updating user meta data: aiowps_account_status", 4); + } + } + + public function aiowps_validate_registration_with_captcha($errors) { + global $aio_wp_security; + + $locked = $aio_wp_security->user_login_obj->check_locked_user(); + if (null == $locked) { + //user is not locked continue + } else { + $errors->add('authentication_failed', __('ERROR: You are not allowed to register because your IP address is currently locked!', 'all-in-one-wp-security-and-firewall')); + return $errors; + } + $verify_captcha = $aio_wp_security->captcha_obj->verify_captcha_submit(); + if (false === $verify_captcha) { + // wrong answer was entered + $errors->add('authentication_failed', __('ERROR: Your answer was incorrect - please try again.', 'all-in-one-wp-security-and-firewall')); + return $errors; + } + return $errors; + } + + /** + * This function serves the purpose of preventing login in certain plugins that enable user registration, such as WooCommerce and others. + * + * @return bool Returns false means do not authenticate on registration + */ + public function aios_registration_auth_new_customer() { + return false; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-api.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-api.php new file mode 100755 index 00000000..02860efa --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-api.php @@ -0,0 +1,121 @@ +debug_logger->log_debug("AIOWPSecurity_Utility_API::make_api_request() - Invalid request method. Only GET and POST are supported.", 4); + return new WP_Error('aios_api_invalid_method', 'Invalid request method. Only GET and POST are supported.'); + } + + // Validate the URL + if ('' !== $url && !filter_var($url, FILTER_VALIDATE_URL)) { + $aio_wp_security->debug_logger->log_debug("AIOWPSecurity_Utility_API::make_api_request() - Invalid or missing request URL.", 4); + return new WP_Error('aios_api_invalid_url', 'Invalid or missing request URL.'); + } + + // Set up default arguments + $default_args = array( + 'headers' => array(), + 'body' => array(), + 'timeout' => 10, + ); + + // Merge default arguments with provided arguments + $request_args = wp_parse_args($args, $default_args); + + // Make the request + if ('POST' === $method) { + $response = wp_remote_post($url, $request_args); + } else { + $response = wp_remote_get($url, $request_args); + } + + // Check for errors + if (is_wp_error($response)) { + // Get error code and message + $error_code = $response->get_error_code(); + $error_message = $response->get_error_message(); + $error_data = $response->get_error_data(); // Optional additional error data + + // Log the error details + $aio_wp_security->debug_logger->log_debug("AIOWPSecurity_Utility_API::make_api_request() | Response error - Code: {$error_code}, Message: {$error_message}", 4); + + // Log any additional error data (could be useful for debugging) + if ($error_data) { + if (is_array($error_data) || is_object($error_data)) { + $aio_wp_security->debug_logger->log_debug("AIOWPSecurity_Utility_API::make_api_request() | Response error - Additional Error Data: " . json_encode($error_data), 4); + } else { + $aio_wp_security->debug_logger->log_debug("AIOWPSecurity_Utility_API::make_api_request() | Response error - Additional Error Data: {$error_data}", 4); + } + } + + return $response; + } + + // Get the response body + $response_body = wp_remote_retrieve_body($response); + + // Check for JSON response + $content_type = wp_remote_retrieve_header($response, 'content-type'); + if (false !== strpos($content_type, 'application/json')) { + + // Decode the response body if it's JSON + $decoded_body = json_decode($response_body, true); + + // Log JSON decoding error if any + if (JSON_ERROR_NONE !== json_last_error()) { + $aio_wp_security->debug_logger->log_debug("AIOWPSecurity_Utility_API::make_api_request() - JSON decode error: " . json_last_error_msg(), 4); + return new WP_Error('aios_api_json_decode_error', json_last_error_msg()); + } + + // Return the decoded JSON response body + return $decoded_body; + } + + // Return raw response body if it's not JSON + return $response_body; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-file.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-file.php new file mode 100755 index 00000000..07d1b6a7 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-file.php @@ -0,0 +1,522 @@ + 'root directory', 'path' => ABSPATH, 'permissions' => '0755'), + array('name' => 'wp-includes/', 'path' => ABSPATH."wp-includes", 'permissions' => '0755'), + array('name' => '.htaccess', 'path' => $home_path.".htaccess", 'permissions' => '0644'), + array('name' => 'wp-admin/index.php', 'path' => ABSPATH."wp-admin/index.php", 'permissions' => '0644'), + array('name' => 'wp-admin/js/', 'path' => ABSPATH."wp-admin/js/", 'permissions' => '0755'), + array('name' => 'wp-content/themes/', 'path' => WP_CONTENT_DIR."/themes", 'permissions' => '0755'), + array('name' => 'wp-content/plugins/', 'path' => WP_PLUGIN_DIR, 'permissions' => '0755'), + array('name' => 'wp-admin/', 'path' => ABSPATH."wp-admin", 'permissions' => '0755'), + array('name' => 'wp-content/', 'path' => WP_CONTENT_DIR, 'permissions' => '0755'), + array('name' => 'wp-config.php', 'path' => $wp_config_path, 'permissions' => '0640'), + //Add as many files or dirs as needed by following the convention above + ); + + return apply_filters('aiowpsecurity_file_permission_list', $file_list); + } + + /** + * Returns full path to mu-plugin directory + * + * @return string + */ + public static function get_mu_plugin_dir() { + return WPMU_PLUGIN_DIR; + } + + /** + * Returns path to wp-config + * + * @return string + */ + public static function get_wp_config_file_path() { + $wp_config_file = ABSPATH . 'wp-config.php'; + if (file_exists($wp_config_file)) { + return $wp_config_file; + } elseif (file_exists(dirname(ABSPATH) . '/wp-config.php')) { + return dirname(ABSPATH) . '/wp-config.php'; + } + return $wp_config_file; + } + + public static function write_content_to_file($file_path, $new_contents) { + // Get the file permissions so we can revert back to it when we are done + $permissions = octdec(substr(sprintf('%o', fileperms($file_path)), -4)); + @chmod($file_path, 0777); + if (is_writeable($file_path)) { + $handle = fopen($file_path, 'w'); + foreach ($new_contents as $line) { + fwrite($handle, $line); + } + fclose($handle); + @chmod($file_path, $permissions); //Let's change the file back to it's original permission setting + return true; + } else { + return false; + } + } + + public static function backup_and_rename_wp_config($src_file_path, $prefix = 'backup') { + global $aio_wp_security; + + //Check to see if the main "backups" directory exists - create it otherwise + $aiowps_backup_dir = WP_CONTENT_DIR.'/'.AIO_WP_SECURITY_BACKUPS_DIR_NAME; + if (!AIOWPSecurity_Utility_File::create_dir($aiowps_backup_dir)) { + $aio_wp_security->debug_logger->log_debug("backup_and_rename_wp_config - Creation of backup directory failed!", 4); + return false; + } + + $src_parts = pathinfo($src_file_path); + $backup_file_name = $prefix . '.' . $src_parts['basename']; + + $backup_file_path = $aiowps_backup_dir . '/' . $backup_file_name; + if (!copy($src_file_path, $backup_file_path)) { + //Failed to make a backup copy + return false; + } + return true; + } + + /** + * Backs up and renames the .htaccess file. + * + * This function creates a backup of the specified .htaccess file by copying it + * to a designated backup directory with a randomly generated filename. + * + * @param string $src_file_path The path to the source .htaccess file to be backed up. + * + * @return string|false The name of the backup file on success, or false on failure. + */ + public static function backup_and_rename_htaccess($src_file_path) { + global $aio_wp_security; + + // Define the backup directory path + $aiowps_backup_dir = WP_CONTENT_DIR . '/' . AIO_WP_SECURITY_BACKUPS_DIR_NAME; + + // Ensure the backup directory exists or create it + if (!AIOWPSecurity_Utility_File::create_dir($aiowps_backup_dir)) { + $aio_wp_security->debug_logger->log_debug("backup_and_rename_htaccess - Creation of backup directory failed!", 4); + return false; + } + + // Generate a random prefix for the backup file name + $random_prefix = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(10); + $backup_file_name = $random_prefix . '_htaccess_backup'; + + // Define the backup file path + $backup_file_path = $aiowps_backup_dir . '/' . $backup_file_name .'.txt'; + + // Copy the source file to the backup location + if (!copy($src_file_path, $backup_file_path)) { + // Failed to make a backup copy + return false; + } + + // Return the backup file name on success + return $backup_file_name; + } + + /** + * This function will perform a recursive search for files in the path that match the passed in pattern + * + * @param string $pattern - the file pattern to search for + * @param integer $flags - flags to apply on the search + * @param string $path - the path we want to search + * + * @return boolean|array - an array of files matching the pattern or false if there was an error (directory traversal in path) or none found + */ + public static function recursive_file_search($pattern = '*', $flags = 0, $path = '') { + $paths = glob($path.'*', GLOB_MARK|GLOB_ONLYDIR|GLOB_NOSORT); + if (false === $paths) { + return false; + } + $files = glob($path.$pattern, $flags); + if (false === $files) { + return false; + } + foreach ($paths as $path) { + $files = array_merge($files, AIOWPSecurity_Utility_File::recursive_file_search($pattern, $flags, $path)); + } + return $files; + } + + /** + * Useful when wanting to echo file contents to screen with
tags + * + * @param string $src_file + * @return string + */ + public static function get_file_contents_with_br($src_file) { + $file_contents = file_get_contents($src_file); + return nl2br($file_contents); + } + + /** + * Useful when wanting to echo file contents inside textarea + * + * @param string $src_file + * @return string + */ + public static function get_file_contents($src_file) { + $file_contents = file_get_contents($src_file); + return $file_contents; + } + + /** + * Returns the file's permission value eg, "0755" + * + * @param string $filepath + * @return string + */ + public static function get_file_permission($filepath) { + if (!function_exists('fileperms')) { + $perms = '-1'; + } else { + clearstatcache(); + $perms = substr(sprintf("%o", @fileperms($filepath)), -4); + } + return $perms; + } + + /** + * Checks if a write operation is possible for the file in question + * + * @param string $filepath + * @return boolean + */ + public static function is_file_writable($filepath) { + $test_string = ""; //We will attempt to append an empty string at the end of the file for the test + $write_result = @file_put_contents($filepath, $test_string, FILE_APPEND | LOCK_EX); + if (false === $write_result) { + return false; + } else { + return true; + } + } + + /** + * This function will compare the current permission value for a file or dir with the recommended value. + * It will compare the individual "execute", "write" and "read" bits for the "public", "group" and "owner" permissions. + * If the permissions for an actual bit value are greater than the recommended value it returns '0' (=less secure) + * Otherwise it returns '1' which means it is secure + * Accepts permission value parameters in octal, ie, "0777" or "777" + * + * @param string $recommended + * @param string $actual + * @return boolean + */ + public static function is_file_permission_secure($recommended, $actual) { + $result = 1; //initialize return result + + //Check "public" permissions + $public_value_actual = substr($actual, -1, 1); //get dec value for actual public permission + $public_value_rec = substr($recommended, -1, 1); //get dec value for recommended public permission + + $pva_bin = sprintf('%04b', $public_value_actual); //Convert value to binary + $pvr_bin = sprintf('%04b', $public_value_rec); //Convert value to binary + //Compare the "executable" bit values for the public actual versus the recommended + if (substr($pva_bin, -1, 1)<=substr($pvr_bin, -1, 1)) { + //The "execute" bit is the same or less as the recommended value + $result = 1*$result; + } else { + //The "execute" bit is switched on for the actual value - meaning it is less secure + $result = 0*$result; + } + + //Compare the "write" bit values for the public actual versus the recommended + if (substr($pva_bin, -2, 1)<=substr($pvr_bin, -2, 1)) { + //The "write" bit is the same or less as the recommended value + $result = 1*$result; + } else { + //The "write" bit is switched on for the actual value - meaning it is less secure + $result = 0*$result; + } + + //Compare the "read" bit values for the public actual versus the recommended + if (substr($pva_bin, -3, 1)<=substr($pvr_bin, -3, 1)) { + //The "read" bit is the same or less as the recommended value + $result = 1*$result; + } else { + //The "read" bit is switched on for the actual value - meaning it is less secure + $result = 0*$result; + } + + //Check "group" permissions + $group_value_actual = substr($actual, -2, 1); + $group_value_rec = substr($recommended, -2, 1); + $gva_bin = sprintf('%04b', $group_value_actual); //Convert value to binary + $gvr_bin = sprintf('%04b', $group_value_rec); //Convert value to binary + + //Compare the "executable" bit values for the group actual versus the recommended + if (substr($gva_bin, -1, 1)<=substr($gvr_bin, -1, 1)) { + //The "execute" bit is the same or less as the recommended value + $result = 1*$result; + } else { + //The "execute" bit is switched on for the actual value - meaning it is less secure + $result = 0*$result; + } + + //Compare the "write" bit values for the public actual versus the recommended + if (substr($gva_bin, -2, 1)<=substr($gvr_bin, -2, 1)) { + //The "write" bit is the same or less as the recommended value + $result = 1*$result; + } else { + //The "write" bit is switched on for the actual value - meaning it is less secure + $result = 0*$result; + } + + //Compare the "read" bit values for the public actual versus the recommended + if (substr($gva_bin, -3, 1)<=substr($gvr_bin, -3, 1)) { + //The "read" bit is the same or less as the recommended value + $result = 1*$result; + } else { + //The "read" bit is switched on for the actual value - meaning it is less secure + $result = 0*$result; + } + + //Check "owner" permissions + $owner_value_actual = substr($actual, -3, 1); + $owner_value_rec = substr($recommended, -3, 1); + $ova_bin = sprintf('%04b', $owner_value_actual); //Convert value to binary + $ovr_bin = sprintf('%04b', $owner_value_rec); //Convert value to binary + + //Compare the "executable" bit values for the group actual versus the recommended + if (substr($ova_bin, -1, 1)<=substr($ovr_bin, -1, 1)) { + //The "execute" bit is the same or less as the recommended value + $result = 1*$result; + } else { + //The "execute" bit is switched on for the actual value - meaning it is less secure + $result = 0*$result; + } + + //Compare the "write" bit values for the public actual versus the recommended + if (substr($ova_bin, -2, 1)<=substr($ovr_bin, -2, 1)) { + //The "write" bit is the same or less as the recommended value + $result = 1*$result; + } else { + //The "write" bit is switched on for the actual value - meaning it is less secure + $result = 0*$result; + } + + //Compare the "read" bit values for the public actual versus the recommended + if (substr($ova_bin, -3, 1)<=substr($ovr_bin, -3, 1)) { + //The "read" bit is the same or less as the recommended value + $result = 1*$result; + } else { + //The "read" bit is switched on for the actual value - meaning it is less secure + $result = 0*$result; + } + + return $result; + } + + /** + * Checks if a directory exists and creates one if it does not + * + * @param string $dirpath + * @return boolean + */ + public static function create_dir($dirpath = '') { + $res = true; + if ('' != $dirpath) { + //TODO - maybe add some checks to make sure someone is not passing a path with a filename, ie, something which has "." at the end + //$path_parts = pathinfo($dirpath); + //$dirpath = $path_parts['dirname'] . '/' . $path_parts['basename']; + if (!file_exists($dirpath)) { + $res = mkdir($dirpath, 0755); + } + } + return $res; + } + + /** + * Remove a directory from the local filesystem + * + * @param string $dir - the directory + * @param boolean $contents_only - if set to true, then do not remove the directory, but only empty it of contents + * + * @return boolean - success/failure + */ + public static function remove_local_directory($dir, $contents_only = false) { + + $handle = opendir($dir); + if ($handle) { + while (false !== ($entry = readdir($handle))) { + if ('.' !== $entry && '..' !== $entry) { + if (is_dir($dir.'/'.$entry)) { + self::remove_local_directory($dir.'/'.$entry, false); + } else { + @unlink($dir.'/'.$entry);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore warning and proceed to try and remove the rest of the files + } + } + } + if (is_resource($handle)) closedir($handle); + } + + return $contents_only ? true : rmdir($dir); + } + + /** + * Get home path. + * + * @return string + */ + public static function get_home_path() { + // Make the scope of $wp_file_descriptions global, so that when wp-admin/includes/file.php assigns to it, it is adjusting the global variable as intended + global $wp_file_descriptions; // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- We need to make this global see above comment + if (!function_exists('get_home_path')) require_once(ABSPATH. '/wp-admin/includes/file.php'); + return wp_normalize_path(get_home_path()); + } + + /** + * Check if wp config file. + * + * @param string $file_contents File contents + * + * @return bool + */ + public static function check_if_wp_config_contents($file_contents) { + return !empty($file_contents) && preg_match("/define\(\s*['\"]DB_NAME['\"]/i", $file_contents); + } + + /** + * Check if valid aios settings text + * + * @param string $text - Settings text + * + * @return boolean + */ + public static function check_is_aiowps_settings($text) { + return (false !== strpos($text, 'aiowps_enable_login_lockdown')); + } + + /** + * Checks if valid AIOS settings file contents and returns contents as string + * + * @param string $file_contents File contents + * + * @return int|string + */ + public static function check_if_valid_aiowps_settings_content($file_contents) { + // Check a known AIOS config strings to see if it is contained within this file + return !empty($file_contents) && self::check_is_aiowps_settings($file_contents); + } + + /** + * Scans WP key core files and directory permissions and populates a wp wide_fat table + * Displays a red background entry with a "Fix" button for permissions which are "777" + * Displays a yellow background entry with a "Fix" button for permissions which are less secure than the recommended + * Displays a green entry for permissions which are as secure or better than the recommended + * + * @param string $name - file name + * @param string $path - file path + * @param string $recommended - file permission + * + * @return void + */ + public static function show_wp_filesystem_permission_status($name, $path, $recommended) { + $fix = false; + $configmod = self::get_file_permission($path); + if (self::is_file_world_writable($configmod)) { + $trclass = "aio_table_row_red"; // Display a red background if permissions are set as least secure ("777") + $fix = true; + } elseif ($configmod != $recommended) { + // $res = $this->is_file_permission_secure($recommended, $configmod); + $res = self::is_file_permission_secure($recommended, $configmod); + if ($res) { + $trclass = "aio_table_row_green"; //If the current permissions are even tighter than recommended then display a green row + } else { + $trclass = "aio_table_row_yellow"; // Display a yellow background if permissions are set to something different than recommended + $fix = true; + } + } else { + $trclass = "aio_table_row_green"; + } + echo ""; + echo '' . $name . '' . ""; + echo '' . $path . ""; + echo '' . $configmod . ''; + echo '' . $recommended . ''; + if ($fix) { + echo ' + + '; + } else { + echo ''.__('No action required', 'all-in-one-wp-security-and-firewall').''; + } + echo ""; + } + + /** + * Checks if the given file permissions indicate that the file is world-writable. + * + * This function accepts a string representation of file permissions (in octal format) + * and checks if the write bit is set for 'others' (world). It ensures the string + * is 4 characters long by prepending a '0' if necessary and then extracts and + * evaluates the last digit to determine if the file is world-writable. + * + * @param string $permissions The file permissions in octal format (e.g., "0777", "0755"). + * @return bool Returns true if the file is world-writable, otherwise false. + */ + public static function is_file_world_writable($permissions) { + if (strlen($permissions) == 3) { + $permissions = '0' . $permissions; + } + + // Get the 'others' permissions (last digit) + $others_permissions = (int) substr($permissions, -1); + + // Check if the write bit (2) is set for 'others' + return (bool) ($others_permissions & 0x2); + } + + /** + * Read the larger file and get last 100 lines etc in an efficient way + * + * @param string $filepath - file path + * @param integer $offset - offest to start reading the file from that line + * @param integer $num - number of lines to read + * @param boolean $reverse - return in reverse order + * + * @return array|boolean - file lines + */ + public static function read_file_lines($filepath, $offset = 0, $num = 10, $reverse = false) { + global $aio_wp_security; + try { + $file = new \SplFileObject($filepath, 'r'); + if (-1 == $offset) { + $file->seek(PHP_INT_MAX); // PHP_INT_MAX to seeek to last line + $last_line = $file->key(); + $offset = $last_line > $num ? $last_line - $num : 0; + } + $lines = new \LimitIterator($file, $offset, $offset + $num); + $lines_arr = iterator_to_array($lines); + if ($reverse) $lines_arr = array_reverse($lines_arr); + return $lines_arr; + } catch (\Exception $e) { + $aio_wp_security->debug_logger->log_debug("AIOS - Unable to read file: ". $filepath . " - " .$e->getMessage(), 4); + } + return false; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-firewall.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-firewall.php new file mode 100755 index 00000000..9aa6a970 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-firewall.php @@ -0,0 +1,238 @@ +debug_logger->log_debug($exception->getMessage(), 4); + return ''; + } catch (Error $error) { // phpcs:ignore PHPCompatibility.Classes.NewClasses.errorFound -- this won't run on PHP 5.6 so we still want to catch it on other versions + $aio_wp_security->debug_logger->log_debug($error->getMessage(), 4); + return ''; + } + } + } else { + $directive = ini_get('auto_prepend_file'); + if (false !== $directive) { + return $directive; + } + } + + return ''; + } + + /** + * Returns the file that's necessary to load our firewall + * + * @return AIOWPSecurity_Block_File|null file needed to load the firewall + */ + public static function get_server_file() { + $server_type = AIOWPSecurity_Utility::get_server_type(); + $is_cgi = false; + $sapi = PHP_SAPI; + + if (false !== stripos($sapi, 'cgi')) { + $is_cgi = true; + } + + if (AIOWPSecurity_Utility::UNSUPPORTED_SERVER_TYPE === $server_type) { + return self::MANUAL_SETUP; + + } elseif (false === $is_cgi && 'apache' === $server_type) { + $htpath = path_join(AIOWPSecurity_Utility_File::get_home_path(), '.htaccess'); + return new AIOWPSecurity_Block_Htaccess($htpath); + + } elseif ('litespeed' === $server_type || 'litespeed' === $sapi) { + $htpath = path_join(AIOWPSecurity_Utility_File::get_home_path(), '.htaccess'); + return new AIOWPSecurity_Block_Litespeed($htpath); + + } else { + $userini = path_join(AIOWPSecurity_Utility_File::get_home_path(), '.user.ini'); + return new AIOWPSecurity_Block_Userini($userini); + } + + } + + /** + * Checks whether the firewall has been setup + * + * @return boolean + */ + public static function is_firewall_setup() { + $is_in_bootstrap = (true === self::get_bootstrap_file()->contains_contents()); + + $files = array( + self::get_server_file(), + self::get_wpconfig_file(), + self::get_muplugin_file(), + ); + + foreach ($files as $file) { + if (AIOWPSecurity_Utility_Firewall::MANUAL_SETUP === $file) continue; + + if ($is_in_bootstrap && (true === $file->contains_contents())) return true; + } + + return false; + } + + /** + * Attempts to remove our firewall. + * + * @return void + */ + public static function remove_firewall() { + global $aio_wp_security; + + $firewall_files = array( + 'server' => AIOWPSecurity_Utility_Firewall::get_server_file(), + 'bootstrap' => AIOWPSecurity_Utility_Firewall::get_bootstrap_file(), + 'wpconfig' => AIOWPSecurity_Utility_Firewall::get_wpconfig_file(), + 'muplugin' => AIOWPSecurity_Utility_Firewall::get_muplugin_file(), + ); + + foreach ($firewall_files as $file) { + if (AIOWPSecurity_Utility_Firewall::MANUAL_SETUP === $file) { + continue; + } + + if (true === $file->contains_contents()) { + + $removed = $file->remove_contents(); + + if (is_wp_error($removed)) { + $error_message = $removed->get_error_message(); + $error_message .= ' - '; + $error_message .= $removed->get_error_data(); + $aio_wp_security->debug_logger->log_debug($error_message, 4); + } + } + } + + //Delete our mu-plugin, if it's created + clearstatcache(); + $muplugin_path = $firewall_files['muplugin']; + if (file_exists($muplugin_path)) { + @wp_delete_file($muplugin_path); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore this + } + + $aio_wp_security->configs->set_value('aios_firewall_dismiss', false, true); + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-htaccess.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-htaccess.php new file mode 100755 index 00000000..0b6bd5f4 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-htaccess.php @@ -0,0 +1,726 @@ + 1) return false; + } + + return true; + } + + /** + * This function checks if .htaccess file exists and is readable + * + * @param string $htaccess - The path to .htaccess file + * @return boolean + */ + public static function htaccess_exist_and_readable($htaccess) { + global $aio_wp_security; + + if (!file_exists($htaccess)) { + $aio_wp_security->debug_logger->log_debug("The .htaccess file is missing", 4); + return false; + } elseif (!is_readable($htaccess)) { + $aio_wp_security->debug_logger->log_debug("The .htaccess file exists, but it is not readable.", 4); + return false; + } + return true; + } + + /** + * Write all active rules to .htaccess file. + * + * @param boolean $show_error - if the error should be shown + * + * @return boolean True on success, false on failure. + */ + public static function write_to_htaccess($show_error = true) { + global $aio_wp_security; + + if (!class_exists('AIOWPSecurity_Admin_Menu')) { + include_once AIO_WP_SECURITY_PATH . '/admin/wp-security-admin-menu.php'; + } + + // figure out what server is being used + $serverType = AIOWPSecurity_Utility::get_server_type(); + + if (in_array($serverType, array('-1', 'nginx', 'iis')) && !defined('WP_CLI')) { + if ($show_error) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('The .htaccess file is not supported by your web server.', 'all-in-one-wp-security-and-firewall'), !$show_error); + } + $aio_wp_security->debug_logger->log_debug("Unable to write to .htaccess - server type not supported.", 4); + return false; // unable to write to the file + } + + $home_path = AIOWPSecurity_Utility_File::get_home_path(); + $htaccess = $home_path . '.htaccess'; + if (!self::htaccess_exist_and_readable($htaccess)) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('The .htaccess file either does not exist or is unreadable', 'all-in-one-wp-security-and-firewall'), !$show_error); + $aio_wp_security->debug_logger->log_debug("The .htaccess file either does not exist or is unreadable", 4); + return false; + } // check the existence of the file and if its readable + + // confirm the hataccess has valid markers + if (!self::htaccess_has_valid_markers($htaccess)) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('The .htaccess file contains invalid content, please manually verify the file contents', 'all-in-one-wp-security-and-firewall'), !$show_error); + $aio_wp_security->debug_logger->log_debug("Unable to edit the .htaccess file as it contains invalid content, please manually verify the file contents", 4); + return false; + } + + AIOWPSecurity_Utility_File::backup_and_rename_htaccess($htaccess); + + // creating a copy of htaccess file to work on + $temp_htaccess = $home_path.'.htaccess_temp'; + if (!copy($htaccess, $temp_htaccess)) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('A copy of the .htaccess file could not be created', 'all-in-one-wp-security-and-firewall'), !$show_error); + $aio_wp_security->debug_logger->log_debug("Write operation on .htaccess file failed, unable to create a copy of the file", 4); + return false; + } + + // clean up old rules first + if (-1 == AIOWPSecurity_Utility_Htaccess::delete_from_htaccess($temp_htaccess)) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__("Unable to delete plugin's content from .htaccess file.", 'all-in-one-wp-security-and-firewall'), !$show_error); + $aio_wp_security->debug_logger->log_debug("Unable to delete plugin's content from .htaccess file.", 4); + return false; //unable to write to the file + } + + + $ht = explode("\n", implode('', file($temp_htaccess))); // parse each line of file into array + + $rules = AIOWPSecurity_Utility_Htaccess::getrules(); + + $rulesarray = explode("\n", $rules); + $rulesarray = apply_filters('aiowps_htaccess_rules_before_writing', $rulesarray); + $contents = array_merge($rulesarray, $ht); + + $f = @fopen($temp_htaccess, 'w+'); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore warning as we try to handle it below + if (!$f) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Write operation on .htaccess failed.', 'all-in-one-wp-security-and-firewall'), !$show_error); + $aio_wp_security->debug_logger->log_debug("Write operation on .htaccess failed.", 4); + return false; //we can't write to the file + } + + $blank = false; + + // write each line to file + foreach ($contents as $insertline) { + if (trim($insertline) == '') { + if (false == $blank) { + fwrite($f, "\n" . trim($insertline)); + } + $blank = true; + } else { + $blank = false; + fwrite($f, "\n" . trim($insertline)); + } + } + if (is_resource($f)) @fclose($f); + + // before writing into the live htaccess confirm the markers still valid + if (!self::htaccess_has_valid_markers($temp_htaccess)) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('The .htaccess file has invalid content, please manually verify that the file is properly formatted', 'all-in-one-wp-security-and-firewall'), !$show_error); + $aio_wp_security->debug_logger->log_debug("The .htaccess file has invalid content, please manually verify that the file is properly formatted", 4); + return false; + } + + // copy the changes from the temp htaccess into the live htaccess from here + if (!copy($temp_htaccess, $htaccess)) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('An error has occurred while writing to the .htaccess file.', 'all-in-one-wp-security-and-firewall'), !$show_error); + $aio_wp_security->debug_logger->log_debug("Failed to write to the .htaccess file", 4); + return false; + } + // Remove the temp htaccess file created + unlink($temp_htaccess); + + return true; //success + } + + /** + * This function will delete the code which has been added to the .htaccess file by this plugin + * It will try to find the comment markers "# BEGIN All In One WP Security" and "# END All In One WP Security" and delete contents in between + * + * @param string $htaccess - The htaccess file path to manipulate + * @param string $section - All in One Security + * @return Integer {-1,1} -1 for failure, 1 for success. + */ + public static function delete_from_htaccess($htaccess = '', $section = 'All In One WP Security') { + + if (empty($htaccess)) { + $home_path = AIOWPSecurity_Utility_File::get_home_path(); + $htaccess = $home_path . '.htaccess'; + } + + if (!file_exists($htaccess)) { + $ht = @fopen($htaccess, 'a+');// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore warning as we try to handle it below + if (false === $ht) { + global $aio_wp_security; + $aio_wp_security->debug_logger->log_debug('Failed to create .htaccess file', 4); + return -1; + } + if (is_resource($ht)) @fclose($ht); + } + + // Bug Fix: On some environments such as windows (xampp) this function was clobbering the non-aiowps-related .htaccess contents for certain cases. + // In some cases when WordPress saves the .htaccess file (eg, when saving permalink settings), + // the line endings differ from the expected "\n" endings. (WordPress saves with "\n" (UNIX style) but "\n" may be set as "\r\n" (WIN/DOS)) + // In this case exploding via "\n" may not yield the result we expect. + // Therefore we need to do the following extra checks. + $ht_contents_imploded = implode('', file($htaccess)); + if (empty($ht_contents_imploded)) { + return 1; + } elseif (strstr($ht_contents_imploded, "\n")) { + $ht_contents = explode("\n", $ht_contents_imploded); //parse each line of file into array + } elseif (strstr($ht_contents_imploded, "\r")) { + $ht_contents = explode("\r", $ht_contents_imploded); //parse each line of file into array + } elseif (strstr($ht_contents_imploded, "\r\n")) { + $ht_contents = explode("\r\n", $ht_contents_imploded); //parse each line of file into array + } + + if ($ht_contents) { //as long as there are lines in the file + $state = true; + $f = @fopen($htaccess, 'w+'); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore warning as we try to handle it below + if (!$f) { + @chmod($htaccess, 0644);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore warning as we try to handle it below + $f = @fopen($htaccess, 'w+'); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore warning as we try to handle it below + if (!$f) return -1; + } + + foreach ($ht_contents as $markerline) { //for each line in the file + if (strpos($markerline, '# BEGIN ' . $section) !== false) { //if we're at the beginning of the section + $state = false; + } + if (true == $state) { //as long as we're not in the section keep writing + fwrite($f, trim($markerline) . "\n"); + } + if (strpos($markerline, '# END ' . $section) !== false) { //see if we're at the end of the section + $state = true; + } + } + if (is_resource($f)) @fclose($f); + return 1; + } + return 1; + } + + public static function getrules() { + global $aio_wp_security; + $rules = ""; + $rules .= AIOWPSecurity_Utility_Htaccess::getrules_basic_htaccess(); + $rules .= AIOWPSecurity_Utility_Htaccess::getrules_block_debug_log_access_htaccess(); + $rules .= AIOWPSecurity_Utility_Htaccess::getrules_disable_index_views(); + $rules .= AIOWPSecurity_Utility_Htaccess::getrules_disable_trace_and_track(); + $rules .= AIOWPSecurity_Utility_Htaccess::getrules_5g_blacklist(); + $rules .= AIOWPSecurity_Utility_Htaccess::prevent_image_hotlinks(); + $custom_rules = AIOWPSecurity_Utility_Htaccess::getrules_custom_rules(); + if ($aio_wp_security->configs->get_value('aiowps_place_custom_rules_at_top')=='1') { + $rules = $custom_rules . $rules; + } else { + $rules .= $custom_rules; + } + + //TODO: The following utility functions are ready to use when we write the menu pages for these features + + //Add more functions for features as needed + //$rules .= AIOWPSecurity_Utility_Htaccess::getrules_somefeature(); + + //Add outer markers if we have rules + if ('' != $rules) { + $rules = "# BEGIN All In One WP Security" . "\n" . $rules . "# END All In One WP Security" . "\n"; + } + + return $rules; + } + + /** + * TODO - info + */ + public static function getrules_basic_htaccess() { + global $aio_wp_security; + + $rules = ''; + if ($aio_wp_security->configs->get_value('aiowps_enable_basic_firewall') == '1') { + $rules .= AIOWPSecurity_Utility_Htaccess::$basic_htaccess_rules_marker_start . "\n"; //Add feature marker start + //protect the htaccess file - this is done by default with apache config file but we are including it here for good measure + $rules .= self::create_apache2_access_denied_rule('.htaccess'); + + //disable the server signature + $rules .= 'ServerSignature Off' . "\n"; + + //limit file upload size + $upload_limit = $aio_wp_security->configs->get_value('aiowps_max_file_upload_size'); + //Shouldn't be empty but just in case + $upload_limit = empty($upload_limit) ? AIOS_FIREWALL_MAX_FILE_UPLOAD_LIMIT_MB : $upload_limit; + $upload_limit = $upload_limit * 1024 * 1024; // Convert from MB to Bytes - approx but close enough + + $rules .= 'LimitRequestBody '.$upload_limit . "\n"; + + // protect wpconfig.php. + $rules .= self::create_apache2_access_denied_rule('wp-config.php'); + + $rules .= AIOWPSecurity_Utility_Htaccess::$basic_htaccess_rules_marker_end . "\n"; //Add feature marker end + } + return $rules; + } + + public static function getrules_block_debug_log_access_htaccess() { + global $aio_wp_security; + + $rules = ''; + if ($aio_wp_security->configs->get_value('aiowps_block_debug_log_file_access') == '1') { + $rules .= AIOWPSecurity_Utility_Htaccess::$debug_log_block_htaccess_rules_marker_start . "\n"; //Add feature marker start + $rules .= self::create_apache2_access_denied_rule('debug.log'); + $rules .= AIOWPSecurity_Utility_Htaccess::$debug_log_block_htaccess_rules_marker_end . "\n"; //Add feature marker end + } + return $rules; + } + + /** + * This function will disable directory listings for all directories, add this line to the + * site’s root .htaccess file. + * NOTE: AllowOverride must be enabled in the httpd.conf file for this to work! + */ + public static function getrules_disable_index_views() { + global $aio_wp_security; + $rules = ''; + if ($aio_wp_security->configs->get_value('aiowps_disable_index_views') == '1') { + $rules .= AIOWPSecurity_Utility_Htaccess::$disable_index_views_marker_start . "\n"; //Add feature marker start + $rules .= 'Options -Indexes' . "\n"; + $rules .= AIOWPSecurity_Utility_Htaccess::$disable_index_views_marker_end . "\n"; //Add feature marker end + } + + return $rules; + } + + /** + * This function will write rules to disable trace and track. + * HTTP Trace attack (XST) can be used to return header requests + * and grab cookies and other information and is used along with + * a cross site scripting attacks (XSS) + */ + public static function getrules_disable_trace_and_track() { + global $aio_wp_security; + $rules = ''; + if ($aio_wp_security->configs->get_value('aiowps_disable_trace_and_track') == '1') { + $rules .= AIOWPSecurity_Utility_Htaccess::$disable_trace_track_marker_start . "\n"; //Add feature marker start + $rules .= '' . "\n"; + $rules .= 'RewriteEngine On' . "\n"; + $rules .= 'RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)' . "\n"; + $rules .= 'RewriteRule .* - [F]' . "\n"; + $rules .= '' . "\n"; + $rules .= AIOWPSecurity_Utility_Htaccess::$disable_trace_track_marker_end . "\n"; //Add feature marker end + } + + return $rules; + } + + + /** + * This function contains the rules for the 5G blacklist produced by Jeff Starr from perishablepress.com + * NOTE: Since Jeff regularly updates and evolves his blacklist rules, ie, 5G->6G->7G.... we will update this function to reflect the latest blacklist release + */ + public static function getrules_5g_blacklist() { + global $aio_wp_security; + $rules = ''; + if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_5g_firewall')) { + $rules .= AIOWPSecurity_Utility_Htaccess::$five_g_blacklist_marker_start . "\n"; //Add feature marker start + + $rules .= '# 5G BLACKLIST/FIREWALL (2013) + # @ http://perishablepress.com/5g-blacklist-2013/ + + # 5G:[QUERY STRINGS] + + RewriteEngine On + RewriteBase / + RewriteCond %{QUERY_STRING} (\"|%22).*(<|>|%3) [NC,OR] + RewriteCond %{QUERY_STRING} (javascript:).*(\;) [NC,OR] + RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3) [NC,OR] + RewriteCond %{QUERY_STRING} (\\\|\.\./|`|=\'$|=%27$) [NC,OR] + RewriteCond %{QUERY_STRING} (\;|\'|\"|%22).*(union|select|insert|drop|update|md5|benchmark|or|and|if) [NC,OR] + RewriteCond %{QUERY_STRING} (base64_encode|localhost|mosconfig) [NC,OR] + RewriteCond %{QUERY_STRING} (boot\.ini|echo.*kae|etc/passwd) [NC,OR] + RewriteCond %{QUERY_STRING} (GLOBALS|REQUEST)(=|\[|%) [NC] + RewriteRule .* - [F] + + + # 5G:[USER AGENTS] + + # SetEnvIfNoCase User-Agent ^$ keep_out + SetEnvIfNoCase User-Agent (binlar|casper|cmsworldmap|comodo|diavol|dotbot|feedfinder|flicky|ia_archiver|jakarta|kmccrew|nutch|planetwork|purebot|pycurl|skygrid|sucker|turnit|vikspider|zmeu) keep_out + + Order Allow,Deny + Allow from all + Deny from env=keep_out + + + + # 5G:[REQUEST STRINGS] + + RedirectMatch 403 (https?|ftp|php)\:// + RedirectMatch 403 /(https?|ima|ucp)/ + RedirectMatch 403 /(Permanent|Better)$ + RedirectMatch 403 (\=\\\\\\\'|\=\\\%27|/\\\\\\\'/?|\)\.css\()$ + RedirectMatch 403 (\,|\)\+|/\,/|\{0\}|\(/\(|\.\.\.|\+\+\+|\||\\\\\"\\\\\") + RedirectMatch 403 \.(cgi|asp|aspx|cfg|dll|exe|jsp|mdb|sql|ini|rar)$ + RedirectMatch 403 /(contac|fpw|install|pingserver|register)\.php$ + RedirectMatch 403 (base64|crossdomain|localhost|wwwroot|e107\_) + RedirectMatch 403 (eval\(|\_vti\_|\(null\)|echo.*kae|config\.xml) + RedirectMatch 403 \.well\-known/host\-meta + RedirectMatch 403 /function\.array\-rand + RedirectMatch 403 \)\;\$\(this\)\.html\( + RedirectMatch 403 proc/self/environ + RedirectMatch 403 msnbot\.htm\)\.\_ + RedirectMatch 403 /ref\.outcontrol + RedirectMatch 403 com\_cropimage + RedirectMatch 403 indonesia\.htm + RedirectMatch 403 \{\$itemURL\} + RedirectMatch 403 function\(\) + RedirectMatch 403 labels\.rdf + RedirectMatch 403 /playing.php + RedirectMatch 403 muieblackcat + + + # 5G:[REQUEST METHOD] + + RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK) + RewriteRule .* - [F] + ' . "\n"; + $rules .= AIOWPSecurity_Utility_Htaccess::$five_g_blacklist_marker_end . "\n"; //Add feature marker end + } + + return $rules; + } + + /** + * This function will write some directives to prevent image hotlinking + */ + public static function prevent_image_hotlinks() { + global $aio_wp_security; + $rules = ''; + if ($aio_wp_security->configs->get_value('aiowps_prevent_hotlinking') == '1') { + $url_string = AIOWPSecurity_Utility_Htaccess::return_regularized_url(AIOWPSEC_WP_HOME_URL); + if (false == $url_string) { + $url_string = AIOWPSEC_WP_HOME_URL; + } + $rules .= AIOWPSecurity_Utility_Htaccess::$prevent_image_hotlinks_marker_start . "\n"; //Add feature marker start + $rules .= '' . "\n"; + $rules .= 'RewriteEngine On' . "\n"; + $rules .= 'RewriteCond %{HTTP_REFERER} !^$' . "\n"; + $rules .= 'RewriteCond %{REQUEST_FILENAME} -f' . "\n"; + $rules .= 'RewriteCond %{REQUEST_FILENAME} \.(gif|jpe?g?|png)$ [NC]' . "\n"; + $rules .= 'RewriteCond %{HTTP_REFERER} !^' . $url_string . ' [NC]' . "\n"; + $rules .= 'RewriteRule \.(gif|jpe?g?|png)$ - [F,NC,L]' . "\n"; + $rules .= '' . "\n"; + $rules .= AIOWPSecurity_Utility_Htaccess::$prevent_image_hotlinks_marker_end . "\n"; //Add feature marker end + } + + return $rules; + } + + /** + * This function will write any custom htaccess rules into the server's .htaccess file + * + * @return string + */ + public static function getrules_custom_rules() { + global $aio_wp_security; + $rules = ''; + if ($aio_wp_security->configs->get_value('aiowps_enable_custom_rules') == '1') { + $custom_rules = $aio_wp_security->configs->get_value('aiowps_custom_rules'); + $rules .= AIOWPSecurity_Utility_Htaccess::$custom_rules_marker_start . "\n"; //Add feature marker start + $rules .= $custom_rules . "\n"; + $rules .= AIOWPSecurity_Utility_Htaccess::$custom_rules_marker_end . "\n"; //Add feature marker end + } + + return $rules; + } + + /** + * This function will do a quick check to see if a file's contents are actually .htaccess specific. + * At the moment it will look for the following tag somewhere in the file - "# BEGIN WordPress" + * If it finds the tag it will deem the file as being .htaccess specific. + * This was written to supplement the .htaccess restore functionality + * + * @param string $file_contents - the contents of the .htaccess file + * + * @return boolean + */ + public static function check_if_htaccess_contents($file_contents) { + $is_htaccess = false; + + if (false === $file_contents || strlen($file_contents) == 0) { + return -1; + } + + if ((strpos($file_contents, '# BEGIN WordPress') !== false) || (strpos($file_contents, '# BEGIN') !== false)) { + $is_htaccess = true; // It appears that we have some sort of .htaccess file + } else { + //see if we're at the end of the section + $is_htaccess = false; + } + + if ($is_htaccess) { + return 1; + } else { + return -1; + } + } + + /** + * This function will take a URL string and convert it to a form useful for using in htaccess rules. + * Example: If URL passed to function = "http://www.mysite.com" + * Result = "http(s)?://(.*)?mysite\.com" + * + * @param string $url + * @return string + */ + public static function return_regularized_url($url) { + if (filter_var($url, FILTER_VALIDATE_URL)) { + $xyz = explode('.', $url); + $y = ''; + if (count($xyz) > 1) { + $j = 1; + foreach ($xyz as $x) { + if (strpos($x, 'www') !== false) { + $y .= str_replace('www', '(.*)?', $x); + } elseif (1 == $j) { + $y .= $x; + } elseif ($j > 1) { + $y .= '\.' . $x; + } + $j++; + } + //Now replace the "http" with "http(s)?" to cover both secure and non-secure + if (strpos($y, 'https') !== false) { + $y = str_replace('https', 'http(s)?', $y); + } elseif (strpos($y, 'http') !== false) { + $y = str_replace('http', 'http(s)?', $y); + } + return $y; + } else { + return $url; + } + } else { + return false; + } + } + + /** + * Returns a string with directive that contains rules + * to effectively block access to any file that has basename matching + * $filename under Apache webserver. + * + * @link http://httpd.apache.org/docs/current/mod/core.html#files + * + * @param string $filename + * @return string + */ + protected static function create_apache2_access_denied_rule($filename) { + return << + + Require all denied + + + Order deny,allow + Deny from all + + + +END; + // Keep the empty line at the end of heredoc string, + // otherwise the string will not end with end-of-line character! + } + + + /** + * Convert an array of optionally asterisk-masked or partial IPv4 addresses + * into network/netmask notation. Netmask value for a "full" IP is not + * added (see example below) + * + * Example: + * In: array('1.2.3.4', '5.6', '7.8.9.*') + * Out: array('1.2.3.4', '5.6.0.0/16', '7.8.9.0/24') + * + * Simple validation is performed: + * In: array('1.2.3.4.5', 'abc', '1.2.xyz.4') + * Out: array() + * + * Simple sanitization is performed: + * In: array('6.7.*.9') + * Out: array('6.7.0.0/16') + * + * @param array $ips + * @return array + */ + protected static function add_netmask($ips = array()) { + + $output = array(); + if (empty($ips)) return array(); + foreach ($ips as $ip) { + //Check if ipv6 + if (strpos($ip, ':') !== false) { + //for now support whole ipv6 and CIDR range. + $checked_ip = AIOWPSecurity_Utility_IP::is_ipv6_address_or_ipv6_range($ip); + if (false != $checked_ip) { + $output[] = $ip; + } + } + + $parts = explode('.', $ip); + + // Skip any IP that is empty, has more parts than expected or has + // a non-numeric first part. + if (empty($parts) || (count($parts) > 4) || !is_numeric($parts[0])) { + continue; + } + + $ip_out = array($parts[0]); + $netmask = 8; + + for ($i = 1, $force_zero = false; ($i < 4) && $ip_out; $i++) { + if ($force_zero || !isset($parts[$i]) || ('' === $parts[$i]) || ('*' === $parts[$i])) { + $ip_out[$i] = '0'; + $force_zero = true; // Forces all subsequent parts to be a zero + } elseif (is_numeric($parts[$i])) { + $ip_out[$i] = $parts[$i]; + $netmask += 8; + } else { + // Invalid IP part detected, invalidate entire IP + $ip_out = false; + } + } + + if ($ip_out) { + // Glue IP back together, add netmask if IP denotes a subnet, store for output. + $output[] = implode('.', $ip_out) . (($netmask < 32) ? ('/' . $netmask) : ''); + } + } + + return $output; + } + + public static function get_htaccess_path() { + $home_path = AIOWPSecurity_Utility_File::get_home_path(); + return $home_path . '.htaccess'; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-ip-address.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-ip-address.php new file mode 100755 index 00000000..26418dd4 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-ip-address.php @@ -0,0 +1,220 @@ +debug_logger->log_debug("AIOWPSecurity_Utility_IP - Invalid IP received ".$ip, 4); + } + return $ip_range; + } + + + public static function create_ip_list_array_from_string_with_newline($ip_addresses) { + $ip_list_array = preg_split("/\R/", $ip_addresses); + return $ip_list_array; + } + + /** + * Returns IPv6 ip address or IPv6 range if valid + * + * @param string $item possible IPv6 ip address or IPv6 range + * @return string|boolean $checked_ip trimmed IPv6 ip address or IPv6 range if given input is valid otherwise false. + */ + public static function is_ipv6_address_or_ipv6_range($item) { + $checked_ip = false; + $res = WP_Http::is_ip_address($item); + if ('6' == $res && class_exists('WpOrg\Requests\Ipv6') && WpOrg\Requests\Ipv6::check_ipv6($item)) { + $checked_ip = trim($item); + } elseif ('6' == $res && class_exists('Requests_IPv6') && Requests_IPv6::check_ipv6($item)) { + $checked_ip = trim($item); + } else { + //ipv6 - range check for valid CIDR range + $item_ip_range = explode('/', $item); + $ip_part_valid = filter_var($item_ip_range[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6); + //1 - 164 range of the IPv6 subnect masking as per CISCO propersed change from 128. + if (2 == count($item_ip_range) && $ip_part_valid && $item_ip_range[1] >= 1 && $item_ip_range[1] <= 164) { + $checked_ip = trim($item); + } + } + return $checked_ip; + } + + /** + * Validates IP or IP range + * + * @param array $ip_list_array + * @param string $list_type + * @return array|WP_Error + */ + public static function validate_ip_list($ip_list_array, $list_type = '') { + $errors = ''; + + $current_user_ip = AIOWPSecurity_Utility_IP::get_user_ip_address(); + + //validate list + $submitted_ips = $ip_list_array; + $list = array(); + if (!(include_once AIO_WP_SECURITY_PATH.'/vendor/mlocati/ip-lib/ip-lib.php')) { + throw new \Exception("AIOWPSecurity_Utility_IP::validate_ip_list failed to load ip-lib.php"); + } + + if (!empty($submitted_ips)) { + foreach ($submitted_ips as $item) { + $item = sanitize_text_field($item); + + // Skip items that are comments (start with #) + if (strpos($item, '#') === 0) { + $list[] = trim($item); + continue; + } + + if (strlen($item) > 0) { + $ip_address = \IPLib\Factory::addressFromString($item); + $ip_address_range = \IPLib\Factory::rangeFromString($item); + if (null == $ip_address && null == $ip_address_range) { + /* translators: %s: IP Address */ + $errors .= "\n" . sprintf(__('%s is not a valid IP address format.', 'all-in-one-wp-security-and-firewall'), $item); + } + + if (strlen($item) > 4 && !in_array($item, $list)) { + if ($item == $current_user_ip && 'blacklist' == $list_type) { + //You can't ban your own IP + $errors .= "\n".__('You cannot ban your own IP address:', 'all-in-one-wp-security-and-firewall') . ' ' . $item; + } else { + $list[] = trim($item); + } + } + } + } + } else { + //This function was called with an empty IP address array list + } + + if (strlen($errors) > 0) { + return new WP_Error('invalid_ips', trim($errors)); + } + + if (sizeof($list) >= 1) return array_unique($list, SORT_STRING); + + return array(); + } + + /** + * If login whitelist enabled and the user IP is not whitelisted, Then forbid access. + * + * @return void + */ + public static function check_login_whitelist_and_forbid() { + if (defined('AIOS_DISABLE_LOGIN_WHITELIST') && AIOS_DISABLE_LOGIN_WHITELIST) { + return; + } + + global $aio_wp_security; + + if ('1' != $aio_wp_security->configs->get_value('aiowps_enable_whitelisting')) { + return; + } + + $whitelisted_ips = $aio_wp_security->configs->get_value('aiowps_allowed_ip_addresses'); + $is_whitelisted = AIOWPSecurity_Utility_IP::is_userip_whitelisted($whitelisted_ips); + + if ($is_whitelisted) { + return; + } + + header('HTTP/1.1 403 Forbidden'); + exit(); + } + + /** + * Checks if user IP address matches against the specified whitelist of IP addresses or IP ranges + * + * @param type $whitelisted_ips (newline separated string of IPs) + * @return boolean + */ + public static function is_userip_whitelisted($whitelisted_ips) { + if (empty($whitelisted_ips)) return false; + + $ip_list_array = AIOWPSecurity_Utility_IP::create_ip_list_array_from_string_with_newline($whitelisted_ips); + if (empty($ip_list_array)) return false; + + return AIOS_Helper::is_user_ip_address_within_list($ip_list_array); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-permissions.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-permissions.php new file mode 100755 index 00000000..a198848b --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-permissions.php @@ -0,0 +1,65 @@ +role_names as $id => $name) { + $user_roles[$id] = translate_user_role($name); + } + return $user_roles; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-ui.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-ui.php new file mode 100755 index 00000000..de7d361f --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility-ui.php @@ -0,0 +1,129 @@ + $value) { + $other_attributes .= $attribute . '="' . esc_attr($value) . '" '; + } + } + ?> + + + + + + +
+ + include_template('info/ip-address-ip-range-info.php'); ?> + + '; + + // Check if an array is multidimensional + $is_multi_dimensional = function($array) { + if (!is_array($array)) { + return false; + } + foreach ($array as $item) { + if (is_array($item)) { + return true; + } + } + return false; + }; + + // Check if the input data is a multidimensional array + if ($is_multi_dimensional($data)) { + // Add table headers based on the keys of the first array element + $table_html .= ''; + foreach (array_keys($data[0]) as $header) { + $table_html .= '' . esc_html($header) . ''; + } + $table_html .= ''; + + // Recursively format the multidimensional array + $table_html .= self::format_data_recursive($data); + } else { + // If the input data is not a multidimensional array, treat it as a single key-value pair + $table_html .= self::format_data_recursive(array($data)); + } + + $table_html .= ''; + + return $table_html; + } + + /** + * Recursively format data as a table + * + * @param array $data Data to be formatted + * + * @return string Formatted data as a table + */ + private static function format_data_recursive($data) { + $html = ''; + foreach ($data as $key => $value) { + if (is_array($value)) { + // If the value is an array, recursively format it + $html .= self::format_data_recursive($value); + } else { + // If the value is not an array, format it as a table row + $escaped_key = esc_html($key); + $escaped_value = esc_html($value); + $html .= '' . $escaped_key . '' . $escaped_value . ''; + } + } + return $html; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility.php new file mode 100755 index 00000000..7a1a9837 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-utility.php @@ -0,0 +1,1578 @@ +Error! The URL value is empty. Please specify a correct URL value to redirect to!"; + exit; + } + if (!headers_sent()) { + header('Location: ' . $url); + } else { + echo ''; + } + if ('1' == $exit) { + exit; + } + } + + /** + * Checks if a particular username exists in the WP Users table + * + * @global type $wpdb + * @param type $username + * @return boolean + */ + public static function check_user_exists($username) { + global $wpdb; + + //if username is empty just return false + if ('' == $username) { + return false; + } + + //If multisite + if (is_multisite()) { + $blog_id = get_current_blog_id(); + $admin_users = get_users('blog_id=' . $blog_id . '&orderby=login&role=administrator'); + foreach ($admin_users as $user) { + if ($user->user_login == $username) { + return true; + } + } + return false; + } + + //check users table + $sanitized_username = sanitize_user($username); + // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- PCP warning. Direct query required + $user_login = $wpdb->get_var( + $wpdb->prepare("SELECT user_login FROM $wpdb->users WHERE user_login=%s", $sanitized_username) + ); + + if ($user_login == $sanitized_username) { + return true; + } else { + //make sure that the sanitized username is an integer before comparing it to the users table's ID column + $sanitized_username_is_an_integer = (1 === preg_match('/^\d+$/', $sanitized_username)); + if ($sanitized_username_is_an_integer) { + // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- PCP warning. Direct query required + $userid = $wpdb->get_var( + $wpdb->prepare("SELECT ID FROM $wpdb->users WHERE ID=%d", intval($sanitized_username)) + ); + return ($userid == $sanitized_username); + } else { + return false; + } + } + } + + /** + * This function will return a list of user accounts which have login and nick names which are identical + * + * @global type $wpdb + * @return type + */ + public static function check_identical_login_and_nick_names() { + global $wpdb; + // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- PCP warning. Direct query required. + $accounts_found = $wpdb->get_results("SELECT ID,user_login FROM `" . $wpdb->users . "` WHERE user_login<=>display_name;", ARRAY_A); + return $accounts_found; + } + + + public static function add_query_data_to_url($url, $name, $value) { + if (strpos($url, '?') === false) { + $url .= '?'; + } else { + $url .= '&'; + } + $url .= $name . '=' . urlencode($value); + return $url; + } + + + /** + * Generates a random alpha-numeric number + * + * @param type $string_length + * @return string + */ + public static function generate_alpha_numeric_random_string($string_length) { + //Characters present in table prefix + $allowed_chars = 'abcdefghijklmnopqrstuvwxyz0123456789'; + $string = ''; + //Generate random string + for ($i = 0; $i < $string_length; $i++) { + $string .= $allowed_chars[wp_rand(0, strlen($allowed_chars) - 1)]; + } + return $string; + } + + + /** + * Generates a random string using a-z characters + * + * @param type $string_length + * @return string + */ + public static function generate_alpha_random_string($string_length) { + //Characters present in table prefix + $allowed_chars = 'abcdefghijklmnopqrstuvwxyz'; + $string = ''; + //Generate random string + for ($i = 0; $i < $string_length; $i++) { + $string .= $allowed_chars[wp_rand(0, strlen($allowed_chars) - 1)]; + } + return $string; + } + + /** + * Sets cookie + * + * @param type $cookie_name + * @param type $cookie_value + * @param type $expiry_seconds + * @param type $path + * @param string $cookie_domain + */ + public static function set_cookie_value($cookie_name, $cookie_value, $expiry_seconds = 86400, $path = '/', $cookie_domain = '') { + $expiry_time = time() + intval($expiry_seconds); + if (empty($cookie_domain)) { + $cookie_domain = COOKIE_DOMAIN; + } + return setcookie($cookie_name, $cookie_value, $expiry_time, $path, $cookie_domain, is_ssl(), true); + } + + /** + * Get brute force secret cookie name. + * + * @return String Brute force secret cookie name. + */ + public static function get_brute_force_secret_cookie_name() { + return 'aios_brute_force_secret_' . COOKIEHASH; + } + + /** + * Gets cookie + * + * @param type $cookie_name + * @return string + */ + public static function get_cookie_value($cookie_name) { + if (isset($_COOKIE[$cookie_name])) { + return sanitize_text_field(wp_unslash($_COOKIE[$cookie_name])); + } + return ""; + } + + /** + * Checks if installation is multisite or not. + * + * @return Boolean True if the site is network multisite, false otherwise. + */ + public static function is_multisite_install() { + return function_exists('is_multisite') && is_multisite(); + } + + /** + * This is a general yellow box message for when we want to suppress a feature's config items on multisite because current user is not super admin. + * + * @return void + */ + public static function display_multisite_super_admin_message() { + echo '
'; + echo '

' . esc_html__('The plugin has detected that you are using a Multi-Site WordPress installation.', 'all-in-one-wp-security-and-firewall') . '

+

' . esc_html__('Some features on this page can only be configured by the "superadmin".', 'all-in-one-wp-security-and-firewall') . '

'; + echo '
'; + } + + /** + * Modifies the wp-config.php file to disable PHP file editing from the admin panel + * This function will add the following code: + * define('DISALLOW_FILE_EDIT', false); + * + * NOTE: This function will firstly check if the above code already exists + * and it will modify the bool value, otherwise it will insert the code mentioned above + * + * @global type $aio_wp_security + * @return boolean + */ + public static function disable_file_edits() { + global $aio_wp_security; + $edit_file_config_entry_exists = false; + + //Config file path + $config_file = AIOWPSecurity_Utility_File::get_wp_config_file_path(); + + //Get wp-config.php file contents so we can check if the "DISALLOW_FILE_EDIT" variable already exists + $config_contents = file($config_file); + + foreach ($config_contents as $line_num => $line) { + if (strpos($line, "'DISALLOW_FILE_EDIT', false")) { + $config_contents[$line_num] = str_replace('false', 'true', $line); + $edit_file_config_entry_exists = true; + //$this->show_msg_updated(__('Settings Saved - The ability to edit PHP files via the admin the panel has been DISABLED.', 'all-in-one-wp-security-and-firewall')); + } elseif (strpos($line, "'DISALLOW_FILE_EDIT', true")) { + $edit_file_config_entry_exists = true; + //$this->show_msg_updated(__('Your system config file is already configured to disallow PHP file editing.', 'all-in-one-wp-security-and-firewall')); + return true; + + } + + //For wp-config.php files originating from early WP versions we will remove the closing php tag + if (strpos($line, "?>") !== false) { + $config_contents[$line_num] = str_replace("?>", "", $line); + } + } + + if (!$edit_file_config_entry_exists) { + //Construct the config code which we will insert into wp-config.php + $new_snippet = '//Disable File Edits' . PHP_EOL; + $new_snippet .= 'if (!defined(\'DISALLOW_FILE_EDIT\')) { define(\'DISALLOW_FILE_EDIT\', true); }'; + $config_contents[] = $new_snippet; //Append the new snippet to the end of the array + } + + //Make a backup of the config file + if (!AIOWPSecurity_Utility_File::backup_and_rename_wp_config($config_file)) { + AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Failed to make a backup of the wp-config.php file.', 'all-in-one-wp-security-and-firewall') . ' ' . __('This operation will not go ahead.', 'all-in-one-wp-security-and-firewall')); + //$aio_wp_security->debug_logger->log_debug("Disable PHP File Edit - Failed to make a backup of the wp-config.php file.",4); + return false; + } else { + //$this->show_msg_updated(__('A backup copy of your wp-config.php file was created successfully....', 'all-in-one-wp-security-and-firewall')); + } + + //Now let's modify the wp-config.php file + if (AIOWPSecurity_Utility_File::write_content_to_file($config_file, $config_contents)) { + //$this->show_msg_updated(__('Settings Saved - Your system is now configured to not allow PHP file editing.', 'all-in-one-wp-security-and-firewall')); + return true; + } else { + //$this->show_msg_error(__('Operation failed! Unable to modify wp-config.php file!', 'all-in-one-wp-security-and-firewall')); + $aio_wp_security->debug_logger->log_debug("Disable PHP File Edit - Unable to modify wp-config.php", 4); + return false; + } + } + + /** + * Modifies the wp-config.php file to allow PHP file editing from the admin panel + * This func will modify the following code by replacing "true" with "false": + * define('DISALLOW_FILE_EDIT', true); + * + * @global type $aio_wp_security + * @return boolean + */ + public static function enable_file_edits() { + $edit_file_config_entry_exists = false; + + //Config file path + $config_file = AIOWPSecurity_Utility_File::get_wp_config_file_path(); + + //Get wp-config.php file contents + $config_contents = file($config_file); + foreach ($config_contents as $line_num => $line) { + if (strpos($line, "'DISALLOW_FILE_EDIT', true")) { + $config_contents[$line_num] = str_replace('true', 'false', $line); + $edit_file_config_entry_exists = true; + } elseif (strpos($line, "'DISALLOW_FILE_EDIT', false")) { + $edit_file_config_entry_exists = true; + //$this->show_msg_updated(__('Your system config file is already configured to allow PHP file editing.', 'all-in-one-wp-security-and-firewall')); + return true; + } + } + + if (!$edit_file_config_entry_exists) { + //if the DISALLOW_FILE_EDIT settings don't exist in wp-config.php then we don't need to do anything + //$this->show_msg_updated(__('Your system config file is already configured to allow PHP file editing.', 'all-in-one-wp-security-and-firewall')); + return true; + } else { + //Now let's modify the wp-config.php file + if (AIOWPSecurity_Utility_File::write_content_to_file($config_file, $config_contents)) { + //$this->show_msg_updated(__('Settings Saved - Your system is now configured to allow PHP file editing.', 'all-in-one-wp-security-and-firewall')); + return true; + } else { + //$this->show_msg_error(__('Operation failed! Unable to modify wp-config.php file!', 'all-in-one-wp-security-and-firewall')); + //$aio_wp_security->debug_logger->log_debug("Disable PHP File Edit - Unable to modify wp-config.php",4); + return false; + } + } + } + + + /** + * Inserts event logs to the database + * For now we are using for 404 events but in future will expand for other events + * Event types: 404 (...add more as we expand this) + * + * @param string $event_type :Event type, eg, 404 (see below for list of event types) + * @param string $username (optional): username + * @return bool + */ + public static function event_logger($event_type, $username = '') { + global $wpdb, $aio_wp_security; + + //Some initialising + $url = ''; + $referer_info = ''; + + $events_table_name = AIOWPSEC_TBL_EVENTS; + + $ip_or_host = AIOWPSecurity_Utility_IP::get_user_ip_address(); //Get the IP address of user + $username = sanitize_user($username); + $user = get_user_by('login', $username); //Returns WP_User object if exists + if ($user) { + //If valid user set variables for DB storage later on + $user_id = (absint($user->ID) > 0) ? $user->ID : 0; + } else { + //If the login attempt was made using a non-existent user then let's set user_id to blank and record the attempted user login name for DB storage later on + $user_id = 0; + } + + if ('404' == $event_type || 'spam_discard' == $event_type) { + //if 404 event get some relevant data + $url = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : ''; + $referer_info = isset($_SERVER['HTTP_REFERER']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_REFERER'])) : ''; + } + + $current_time = current_time('mysql', true); + $data = array( + 'event_type' => $event_type, + 'username' => $username, + 'user_id' => $user_id, + 'event_date' => $current_time, + 'ip_or_host' => $ip_or_host, + 'referer_info' => $referer_info, + 'url' => $url, + 'event_data' => '', + ); + + $data = apply_filters('aiowps_filter_event_logger_data', $data); + //log to database + $country_code = isset($data['country_code']) ? $data['country_code'] : ''; + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- PCP error. irect query required. Table name cannot be prepared pre WP 6.2. + $sql = $wpdb->prepare("INSERT INTO ".$events_table_name." (event_type, username, user_id, event_date, ip_or_host, referer_info, url, event_data, country_code, created) VALUES (%s, %s, %d, %s, %s, %s, %s, %s, %s, UNIX_TIMESTAMP())", $data['event_type'], $data['username'], $data['user_id'], $data['event_date'], $data['ip_or_host'], $data['referer_info'], $data['url'], $data['event_data'], $country_code); + + // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared -- PCP warning. Query prepared above. + $result = $wpdb->query($sql); + if (false === $result) { + $aio_wp_security->debug_logger->log_debug("event_logger: Error inserting record into " . $events_table_name, 4);//Log the highly unlikely event of DB error + return false; + } + return true; + } + + /** + * Checks if an IP address is locked. + * + * @param string $ip The IP address to be checked. + * @param string $lock_reason Optional. Defaults to any lockout reason if not provided. + * + * @return bool True if locked, false otherwise. + **/ + public static function check_locked_ip($ip, $lock_reason = null) { + global $wpdb; + $login_lockdown_table = AIOWPSEC_TBL_LOGIN_LOCKOUT; + + if (null === $lock_reason) { + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $locked_ip = $wpdb->get_row($wpdb->prepare("SELECT * FROM `$login_lockdown_table` WHERE released > UNIX_TIMESTAMP() AND failed_login_ip = %s", $ip), ARRAY_A); + } else { + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $locked_ip = $wpdb->get_row($wpdb->prepare("SELECT * FROM `$login_lockdown_table` WHERE released > UNIX_TIMESTAMP() AND failed_login_ip = %s AND lock_reason = %s", $ip, $lock_reason), ARRAY_A); + } + + return null != $locked_ip; + } + + /** + * Check if an IP address is blacklisted. + * + * @param string $ip The IP address to check. + * @return bool True if the IP address is blacklisted, false otherwise. + */ + public static function check_blacklist_ip($ip) { + global $aio_wp_security; + $blacklisted_ips = $aio_wp_security->configs->get_value('aiowps_banned_ip_addresses'); + $blacklisted_ips_array = explode("\n", $blacklisted_ips); + if (in_array($ip, $blacklisted_ips_array)) { + return true; + } else { + return false; + } + } + + /** + * Returns list of IP addresses locked out + * + * @global type $wpdb + * @return array of addresses found or false otherwise + */ + public static function get_locked_ips() { + global $wpdb; + $login_lockdown_table = AIOWPSEC_TBL_LOGIN_LOCKOUT; + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $locked_ips = $wpdb->get_results("SELECT * FROM $login_lockdown_table WHERE released > UNIX_TIMESTAMP()", ARRAY_A); + if (empty($locked_ips)) { + return false; + } else { + return $locked_ips; + } + } + + + /** + * Locks an IP address - Adds an entry to the AIOWPSEC_TBL_LOGIN_LOCKOUT table. + * + * @global wpdb $wpdb + * @global AIO_WP_Security $aio_wp_security + * + * @param String $ip + * @param String $lock_reason + * @param String $username + * + * @return Void + */ + public static function lock_ip($ip, $lock_reason, $username = '') { + global $wpdb, $aio_wp_security; + $login_lockdown_table = AIOWPSEC_TBL_LOGIN_LOCKOUT; + + if ('404' == $lock_reason) { + + // Query for existing lockouts record with that ip and 404 reason. + $existing_lock_query = $wpdb->prepare( + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- PCP warning. Direct query required. Table name cannot be prepared pre WP 6.2. + "SELECT * FROM {$login_lockdown_table} WHERE failed_login_IP = %s AND lock_reason = %s AND released > UNIX_TIMESTAMP() LIMIT 1", + $ip, + $lock_reason + ); + + // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared -- PCP warning. Prepared above. + $existing_lock_count = $wpdb->get_var($existing_lock_query); + + if ($existing_lock_count) return; // IP is already blocked for '404', return. + + $lock_minutes = $aio_wp_security->configs->get_value('aiowps_404_lockout_time_length'); + } elseif ('audit-log' == $lock_reason) { + $lock_minutes = 24 * 60; + } else { + $lock_minutes = $aio_wp_security->user_login_obj->get_dynamic_lockout_time_length(); + } + + $username = sanitize_user($username); + $user = get_user_by('login', $username); //Returns WP_User object if exists + + if (false == $user) { + // Not logged in. + $username = ''; + $user_id = 0; + } else { + // Logged in. + $username = sanitize_user($user->user_login); + $user_id = $user->ID; + } + + $ip = esc_sql($ip); + + $lock_seconds = $lock_minutes * MINUTE_IN_SECONDS; + $lock_time = current_time('mysql', true); + $ip_lookup_result = AIOS_Helper::get_ip_reverse_lookup($ip); + $ip_lookup_result = wp_json_encode($ip_lookup_result); + if (false === $ip_lookup_result) $ip_lookup_result = null; + + $release_time = gmdate('Y-m-d H:i:s', time() + ($lock_seconds)); + $data = array( + 'user_id' => $user_id, + 'user_login' => $username, + 'lockdown_date' => $lock_time, + 'release_date' => $release_time, + 'failed_login_IP' => $ip, + 'lock_reason' => $lock_reason, + 'lock_seconds' => $lock_seconds, + 'ip_lookup_result' => $ip_lookup_result + ); + + $result = AIOWPSecurity_Utility::add_lockout($data); + + if (false === $result) { + $error_msg = empty($wpdb->last_error) ? "lock_ip: Error inserting record into " . $login_lockdown_table : $wpdb->last_error; + $aio_wp_security->debug_logger->log_debug($error_msg, 4);//Log the highly unlikely event of DB error + } + } + + /** + * Adds an entry to the AIOWPSEC_TBL_LOGIN_LOCKOUT table. + * + * @global wpdb $wpdb + * + * @param Array $data + * + * @return Boolean + */ + public static function add_lockout($data) { + global $wpdb; + if (!isset($data['is_lockout_email_sent'])) $data['is_lockout_email_sent'] = 0; + if (!isset($data['backtrace_log'])) $data['backtrace_log'] = ''; + if (!isset($data['ip_lookup_result'])) $data['ip_lookup_result'] = ''; + $login_lockdown_table = AIOWPSEC_TBL_LOGIN_LOCKOUT; + // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.QuotedSimplePlaceholder, WordPress.DB.PreparedSQL.NotPrepared -- PCP error. Direct query required. Table name cannot be prepared pre WP 6.2. + $sql = $wpdb->prepare("INSERT INTO ".$login_lockdown_table." (user_id, user_login, lockdown_date, created, release_date, released, failed_login_IP, lock_reason, is_lockout_email_sent, backtrace_log, ip_lookup_result) VALUES ('%d', '%s', '%s', UNIX_TIMESTAMP(), '%s', UNIX_TIMESTAMP()+%d, '%s', '%s', '%d', '%s', '%s')", $data['user_id'], $data['user_login'], $data['lockdown_date'], $data['release_date'], $data['lock_seconds'], $data['failed_login_IP'], $data['lock_reason'], $data['is_lockout_email_sent'], $data['backtrace_log'], $data['ip_lookup_result']); + // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared -- PCP warning. Prepared above. + $result = $wpdb->query($sql); + return $result; + } + + /** + * Returns an array of blog_ids for a multisite install + * + * @global type $wpdb + * @global type $wpdb + * @return array or empty array if not multisite + */ + public static function get_blog_ids() { + global $wpdb; + if (is_multisite()) { + global $wpdb; + // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- PCP warning. Direct query required. + $blog_ids = $wpdb->get_col("SELECT blog_id FROM " . $wpdb->prefix . "blogs"); + } else { + $blog_ids = array(); + } + return $blog_ids; + } + + /** + * Purges old records of table + * + * @global type $wpdb WP Database object + * @global type $aio_wp_security AIO WP Security object + * @param type $table_name Table name + * @param type $purge_records_after_days Records after days to be deleted + * @param type $date_field Date field of table + * @return void + */ + public static function purge_table_records($table_name, $purge_records_after_days, $date_field) { + global $wpdb, $aio_wp_security; + + $older_than_date_time = strtotime('-' . $purge_records_after_days . ' days', time()); + if ('created' != $date_field) $older_than_date_time = gmdate('Y-m-d H:i:s', $older_than_date_time); + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- PCP error. Direct query required. Table name cannot be prepared pre WP 6.2. + $sql = $wpdb->prepare('DELETE FROM ' . $table_name . ' WHERE '.$date_field.' < %s', $older_than_date_time); + // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared -- PCP warning. Prepared above. + $ret_deleted = $wpdb->query($sql); + if (false === $ret_deleted) { + $err_db = !empty($wpdb->last_error) ? ' ('.$wpdb->last_error.' - '.$wpdb->last_query.')' : ''; + // Status level 4 indicates failure status. + $aio_wp_security->debug_logger->log_debug_cron('Purge records error - failed to purge older records for ' . $table_name . '.' . $err_db, 4); + } else { + $aio_wp_security->debug_logger->log_debug_cron(sprintf('Purge records - %d records were deleted for ' . $table_name . '.', $ret_deleted)); + } + } + + /** + * This function will delete the oldest rows from a table which are over the max amount of rows specified + * + * @global type $wpdb WP Database object + * @global type $aio_wp_security AIO WP Security object + * @param type $table_name Table name + * @param type $max_rows More than max to be deleted + * @param type $id_field Primary field of table + * @return bool + */ + public static function cleanup_table($table_name, $max_rows = '10000', $id_field = 'id') { + global $wpdb, $aio_wp_security; + + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $num_rows = $wpdb->get_var("select count(*) from $table_name"); + $result = true; + if ($num_rows > $max_rows) { + //if the table has more than max entries delete oldest rows + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- PCP error. Direct query necessary. Table name cannot be prepared pre WP 6.2. + $del_sql = $wpdb->prepare("DELETE FROM $table_name WHERE ".$id_field." <= (SELECT ".$id_field." FROM (SELECT ".$id_field." FROM $table_name ORDER BY ".$id_field." DESC LIMIT 1 OFFSET $max_rows) foo_tmp)"); + + // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.LikeWildcardsInQuery -- PCP warning. Prepared above. + $result = $wpdb->query($del_sql); + if (false === $result) { + $aio_wp_security->debug_logger->log_debug("AIOWPSecurity_Utility::cleanup_table failed for table name: " . $table_name, 4); + } + } + return (false === $result) ? false : true; + } + + /** + * Add backquotes to tables and db-names in SQL queries. Taken from phpMyAdmin. + * + * @param string $a_name - the table name + * @return string - the quoted table name + */ + public static function backquote($a_name) { + if (!empty($a_name) && '*' != $a_name) { + if (is_array($a_name)) { + $result = array(); + foreach ($a_name as $key => $val) { + $result[$key] = '`'.$val.'`'; + } + return $result; + } else { + return '`'.$a_name.'`'; + } + } else { + return $a_name; + } + } + + /** + * Replace the first, and only the first, instance within a string + * + * @param String $needle - the search term + * @param String $replace - the replacement term + * @param String $haystack - the string to replace within + * + * @return String - the filtered string + */ + public static function str_replace_once($needle, $replace, $haystack) { + $pos = strpos($haystack, $needle); + return (false !== $pos) ? substr_replace($haystack, $replace, $pos, strlen($needle)) : $haystack; + } + + /** + * Delete expired CAPTCHA info option + * + * Note: A unique instance these option is created everytime the login page is loaded with CAPTCHA enabled + * This function will help prune the options table of old expired entries. + * + * @global wpdb $wpdb + */ + public static function delete_expired_captcha_options() { + global $wpdb; + $current_unix_time = current_time('timestamp', true); + $previous_hour = $current_unix_time - 3600; + $tbl = is_multisite() ? $wpdb->sitemeta : $wpdb->prefix . 'options'; + $key_name = is_multisite() ? 'meta_key' : 'option_name'; + $key_val = is_multisite() ? 'meta_value' : 'option_value'; + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.LikeWildcardsInQuery -- PCP warning. Direct query required. Table name cannot be prepared pre WP 6.2. + $query = $wpdb->prepare("SELECT * FROM {$tbl} WHERE {$key_name} LIKE 'aiowps_captcha_string_info_time_%' AND {$key_val} < %s", $previous_hour); + // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared -- PCP warning. Prepared above. + $res = $wpdb->get_results($query, ARRAY_A); + if (!empty($res)) { + foreach ($res as $item) { + $option_name = $item[$key_name]; + if (is_multisite()) { + delete_site_option($option_name); + delete_site_option(str_replace('time_', '', $option_name)); + } else { + delete_option($option_name); + delete_option(str_replace('time_', '', $option_name)); + } + } + } + } + + /** + * Get server type. + * + * @return string|integer Server type or -1 if server is not supported + */ + public static function get_server_type() { + if (!isset($_SERVER['SERVER_SOFTWARE'])) { + return apply_filters('aios_server_type', -1); + } + + // Figure out what server they're using. + $server_software = strtolower(sanitize_text_field(wp_unslash(($_SERVER['SERVER_SOFTWARE'])))); + + if (strstr($server_software, 'apache')) { + $server_type = 'apache'; + } elseif (strstr($server_software, 'nginx')) { + $server_type = 'nginx'; + } elseif (strstr($server_software, 'litespeed')) { + $server_type = 'litespeed'; + } elseif (strstr($server_software, 'iis')) { + $server_type = 'iis'; + } elseif (strstr($server_software, 'lighttpd')) { + $server_type = 'lighttpd'; + } else { // Unsupported server + $server_type = -1; + } + + return apply_filters('aios_server_type', $server_type); + } + + /** + * Checks if the string exists in the array key value of the provided array. + * If it doesn't exist, it returns the first key element from the valid values. + * + * @param type $to_check + * @param type $valid_values + * @return type + */ + public static function sanitize_value_by_array($to_check, $valid_values) { + $keys = array_keys($valid_values); + $keys = array_map('strtolower', $keys); + if (in_array(strtolower($to_check), $keys)) { + return $to_check; + } + return reset($keys); //Return the first element from the valid values + } + + /** + * Get textarea string from array or string. + * + * @param String|Array $vals value to render as textarea val + * @return String value to render in textarea. + */ + public static function get_textarea_str_val($vals) { + if (empty($vals)) { + return ''; + } + + if (is_array($vals)) { + return implode("\n", array_filter(array_map('trim', $vals))); + } + + return $vals; + } + + /** + * Get array from textarea val. + * + * @param String|Array $vals value from textarea val + * @return Array value to from textarea value. + */ + public static function get_array_from_textarea_val($vals) { + if (empty($vals)) { + return array(); + } + + if (is_array($vals)) { + return $vals; + } + + return array_filter(array_map('trim', explode("\n", $vals))); + } + + /** + * Partially or fully masks a string using '*' to replace original characters + * + * @param type string $str + * @param type int $chars_unmasked + * @return type string + */ + public static function mask_string($str, $chars_unmasked = 0) { + $str_length = strlen($str); + $chars_unmasked = absint($chars_unmasked); + + if (0 == $chars_unmasked) { + if (8 < $str_length) { + // mask all but last 4 characters + return preg_replace("/(.{4}$)(*SKIP)(*F)|(.)/u", "*", $str); + } elseif (3 < $str_length) { + // mask all but last 2 characters + return preg_replace("/(.{2}$)(*SKIP)(*F)|(.)/u", "*", $str); + } else { + // return whole string masked + return str_pad("", $str_length, "*", STR_PAD_LEFT); + } + } + if ($chars_unmasked >= $str_length) return $str; + return preg_replace("/(.{".$chars_unmasked."}$)(*SKIP)(*F)|(.)/u", "*", $str); + } + + /** + * Create a php backtrace log file for login lockdown email + * + * @param Array $logs + * @global AIO_WP_Security $aio_wp_security + * @return string + */ + public static function login_lockdown_email_backtrace_log_file($logs = array()) { + global $aio_wp_security; + + $temp_dir = get_temp_dir(); + $backtrace_filename = wp_unique_filename($temp_dir, 'log_backtrace_' . time() . '.txt'); + $backtrace_filepath = $temp_dir.$backtrace_filename; + if (count($logs) > 0) { + $dbg = ""; + foreach ($logs as $log) { + $dbg.= "############ BACKTRACE STARTS ########\n"; + $dbg.= $log['backtrace_log']; + $dbg.= "############ BACKTRACE ENDS ########\n\n"; + } + } else { + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace, PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection -- PCP and compatibility warnings. Safe to ignore. + $dbg = debug_backtrace(); + } + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r -- PCP warning. Ignore + $is_log_file_written = file_put_contents($backtrace_filepath, print_r($dbg, true)); + if ($is_log_file_written) { + return $backtrace_filepath; + } else { + $aio_wp_security->debug_logger->log_debug("Error in writing php backtrace file " . $backtrace_filepath . " to attach in email.", 4); + return ''; + } + } + + /** + * Normalise call stacks by clearing out unnecessary objects from their arguments list, leaving only the first arguments as a string. The call stacks should be one that is generated by debug_backtrace() function. + * + * @param array $backtrace The output of the debug_backtrace() function + * @return array An array of associative arrays after being normalised + */ + public static function normalise_call_stack_args($backtrace) { + foreach ($backtrace as $index => $element) { + if (!isset($element['args']) || !is_array($element['args']) || !isset($element['args'][0])) $backtrace[$index]['args'] = array(''); + foreach ($backtrace[$index]['args'] as $key => $arg) { + if (is_object($arg)) { + $backtrace[$index]['args'][$key] = array(get_class($backtrace[$index]['args'][$key])); + } elseif (!is_string($arg)) { + $backtrace[$index]['args'][$key] = array(''); + } + } + + if ('apply_filters' == $backtrace[$index]['function'] && 'authenticate' == $backtrace[$index]['args'][0]) { + $backtrace[$index]['args'] = array('authenticate'); + } + + if ('do_action' == $backtrace[$index]['function'] && 'password_reset' == $backtrace[$index]['args'][0]) { + $backtrace[$index]['args'] = array('password_reset'); + } + + $keys_to_filter = array('wp_create_user', 'wpmu_create_user', 'wp_authenticate', 'post_authenticate', 'reset_password'); + if (in_array($backtrace[$index]['function'], $keys_to_filter)) { + $backtrace[$index]['args'] = array(); + } + } + return $backtrace; + } + + /** + * Check whether the WooCommerce plugin is active. + * + * @return Boolean True if the WooCommerce plugin is active, otherwise false. + */ + public static function is_woocommerce_plugin_active() { + return is_plugin_active('woocommerce/woocommerce.php'); + } + + /** + * Check whether incompatible TFA premium plugin version active. + * + * @return boolean True if the incompatible TFA premium plugin version active, otherwise false. + */ + public static function is_incompatible_tfa_premium_version_active() { + if (!function_exists('get_plugin_data')) { + require_once(ABSPATH . '/wp-admin/includes/plugin.php'); + } + + $active_plugins = wp_get_active_and_valid_plugins(); + + foreach ($active_plugins as $plugin_file) { + if ('two-factor-login.php' == basename($plugin_file) && is_dir(dirname($plugin_file) . '/simba-tfa/premium') && version_compare(get_plugin_data($plugin_file, false, false)['Version'], AIOS_TFA_PREMIUM_LATEST_INCOMPATIBLE_VERSION, '<=')) { + return true; + } + } + + return false; + } + + /** + * Check whether TFA plugin activating. + * + * @return boolean True if the TFA plugin activating, otherwise false. + */ + public static function is_tfa_or_self_plugin_activating() { + // The $GLOBALS['pagenow'] doesn't set in the network admin plugins page and it throws the warning "Notice: Undefined index: pagenow in ..." so we can't use it. + // https://core.trac.wordpress.org/ticket/42656 + return is_admin() && + isset($_SERVER['PHP_SELF']) && preg_match('#/wp-admin/plugins.php$#i', sanitize_text_field(wp_unslash($_SERVER['PHP_SELF']))) && isset($_GET['plugin']) && (preg_match("/\/two-factor-login.php/", sanitize_text_field(wp_unslash($_GET['plugin']))) || preg_match("/all-in-one-wp-security-and-firewall/", sanitize_text_field(wp_unslash($_GET['plugin'])))); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. Ignore. + } + + /** + * Check whether the site is running on localhost or not. + * + * @return Boolean True if the site is on localhost, otherwise false. + */ + public static function is_localhost() { + if (defined('AIOS_IS_LOCALHOST')) { + return AIOS_IS_LOCALHOST; + } + + if (empty($_SERVER['REMOTE_ADDR'])) { + return false; + } + return in_array($_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1')) ? true : false; + } + + /** + * Get server software. + * + * @return string Server software or empty. + */ + public static function get_server_software() { + static $server_software; + if (!isset($server_software)) { + $server_software = (isset($_SERVER['SERVER_SOFTWARE']) ? sanitize_text_field(wp_unslash($_SERVER['SERVER_SOFTWARE'])) : ''); + } + return $server_software; + } + + /** + * Check whether the server is apache or not. + * + * @return Boolean True the server is apache, otherwise false. + */ + public static function is_apache_server() { + return (false !== strpos(self::get_server_software(), 'Apache')); + } + + /** + * Change salt postfixes. + * + * @return boolean True if the salt postfixes are changed otherwise false. + */ + public static function change_salt_postfixes() { + global $aio_wp_security; + + $salt_postfixes_scheme = array('auth', 'secure_auth', 'logged_in', 'nonce', 'wpcf7_submission'); + $salt_postfixes_scheme = apply_filters('aios_salt_postfixes_scheme', $salt_postfixes_scheme); + $salt_postfixes = array(); + foreach ($salt_postfixes_scheme as $scheme) { + $salt_postfixes[$scheme] = wp_generate_password(64, true, true); + } + return $aio_wp_security->configs->set_value('aiowps_salt_postfixes', $salt_postfixes, true); + } + + /** + * This function checks to see if there is a display condition for the item and if so runs it otherwise it returns true to display the item + * + * @param array $item_info - the item information array + * + * @return boolean - true if the item should be displayed or false to hide it + */ + public static function should_display_item($item_info) { + if (!empty($item_info['display_condition_callback']) && is_callable($item_info['display_condition_callback'])) { + return call_user_func($item_info['display_condition_callback']); + } elseif (!empty($item_info['display_condition_callback']) && !is_callable($item_info['display_condition_callback'])) { + $item = isset($item_info['page_title']) ? $item_info['page_title'] : ''; + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- PCP warning. Ignore. + error_log("Callback function set but not callable (coding error). Item: " . $item); + return false; + } + return true; + } + + /** + * Verify the username is valid based on logged_in cookie information + * + * @see https://developer.wordpress.org/reference/functions/wp_validate_auth_cookie/ + * @param string $info - Cookie info + * @param int $grace - A grace period for the expiration in seconds + * @return string - Username if valid; blank string otherwise + */ + public static function verify_username($info, $grace = 3600) { + + if (!is_string($info)) return ''; + + $elements = wp_parse_auth_cookie($info, 'logged_in'); + + if (empty($elements)) return ''; + + $username = $elements['username']; + $expiration = $elements['expiration']; + $token = $elements['token']; + $hmac = $elements['hmac']; + $scheme = $elements['scheme']; + + // Add a grace period to the expiration check since there may be a delay in processing the user data + if (!empty($grace) && ($expiration + absint($grace)) < time()) return ''; + + $user = get_user_by('login', $username); + + if (false === $user) return ''; + + $pass_frag = substr($user->user_pass, 8, 4); + + $key = wp_hash($username . '|' . $pass_frag . '|' . $expiration . '|' . $token, $scheme); + + // Use sha1, if sha256 is not available + $algo = function_exists('hash') ? 'sha256' : 'sha1'; + $hash = hash_hmac($algo, $username . '|' . $expiration . '|' . $token, $key); + + if (hash_equals($hash, $hmac)) { + return $username; + } + + return ''; + } + + /** + * Get the blog ID from the provided request + * + * @param array $request + * @return int - returns the blog_id or 0 if it cannot be found + */ + public static function get_blog_id_from_request($request) { + + if (!is_multisite()) return get_current_blog_id(); + + $can_get_blog_id = isset($request['REQUEST_SCHEME']) && isset($request['HTTP_HOST']) && isset($request['REQUEST_URI']); + if (!$can_get_blog_id) return 0; + + $site_url = $request['REQUEST_SCHEME'].'://'.$request['HTTP_HOST'].$request['REQUEST_URI']; + $components = wp_parse_url(trailingslashit($site_url)); + + $can_get_blog_id = isset($components['host']) && isset($components['path']); + if (!$can_get_blog_id) return 0; + + $default_path = defined('PATH_CURRENT_SITE') ? constant('PATH_CURRENT_SITE') : '/'; + + $domain = $components['host']; + $path = SUBDOMAIN_INSTALL ? $default_path : ($default_path === $components['path'] ? $components['path'] : '/'.explode('/', $components['path'])[1].'/'); + + $blog_id = get_blog_id_from_url($domain, $path); + + // On a subdirectory installation, if the blog_id cannot be found for the subdirectory given, we assume it's a path belonging to the main site + // So use the main site's blog_id. + if (0 === $blog_id && !SUBDOMAIN_INSTALL) $blog_id = get_blog_id_from_url($domain, $default_path); + + return $blog_id; + } + + /** + * Checks if the bbPress plugin is active. + * + * @return Boolean True if the bbPress plugin is active, otherwise false. + */ + public static function is_bbpress_plugin_active() { + return is_plugin_active('bbpress/bbpress.php'); + } + + /** + * Checks if the Buddypress plugin is active. + * + * @return Boolean True if the Buddypress plugin is active, otherwise false. + */ + public static function is_buddypress_plugin_active() { + return is_plugin_active('buddypress/bp-loader.php'); + } + + /** + * Checks if the Contact Form 7 plugin is active. + * + * @return Boolean - True if the Contact Form 7 plugin is active, otherwise false. + */ + public static function is_contact_form_7_plugin_active() { + return is_plugin_active('contact-form-7/wp-contact-form-7.php'); + } + + /** + * Checks if the Memberpress plugin is active. + * + * @return Boolean - True if the Memberpress plugin is active, otherwise false. + */ + public static function is_memberpress_plugin_active() { + return is_plugin_active('memberpress/memberpress.php'); + } + + /** + * Retrieves and returns current WP general settings date time format. + * + * @return string + */ + public static function get_wp_datetime_format() { + return get_option('date_format') . ' ' . get_option('time_format'); + } + + /** + * This function gets the timezone of the site as a DateTimeZone object + * + * @see https://developer.wordpress.org/reference/functions/wp_timezone/ + * + * @return DateTimeZone - the timezone of the site as a DateTimeZone object + */ + public static function get_wp_timezone() { + return new DateTimeZone(self::get_wp_timezone_string()); + } + + /** + * This function gets the timezone of the site as a string + * + * @see https://developer.wordpress.org/reference/functions/wp_timezone_string/ + * + * @return string - PHP timezone name or a ±HH:MM offset + */ + public static function get_wp_timezone_string() { + $timezone_string = get_option('timezone_string'); + + if ($timezone_string) return $timezone_string; + + $offset = (float) get_option('gmt_offset'); + $hours = (int) $offset; + $minutes = ($offset - $hours); + $sign = ($offset < 0) ? '-' : '+'; + $abs_hour = abs($hours); + $abs_mins = abs($minutes * 60); + $tz_offset = sprintf('%s%02d:%02d', $sign, $abs_hour, $abs_mins); + + return $tz_offset; + } + + /** + * Converts a Unix timestamp to WP general settings timezone and format. It will also translate with wp_date if available. + * + * @param string $timestamp Optional. Will default to time() if not provided. + * @param string $format Optional. Will default to WP general settings format if not provided. + * + * @return string + */ + public static function convert_timestamp($timestamp = null, $format = null) { + + if (!$format) $format = self::get_wp_datetime_format(); + + if (!$timestamp) $timestamp = time(); + + return function_exists('wp_date') ? wp_date($format, $timestamp) : get_date_from_gmt(gmdate('Y-m-d H:i:s', $timestamp), $format); + } + + /** + * Deletes unneeded default WP files. + * + * @global AIO_WP_Security $aio_wp_security + * + * @param bool $echo_results + * + * @return array + */ + public static function delete_unneeded_default_files($echo_results = false) { + global $aio_wp_security; + + $files = array('readme.html', 'wp-config-sample.php', 'license.txt'); + $info = array(); + $error = array(); + foreach ($files as $file_name) { + $file_path = ABSPATH . $file_name; + + if (file_exists($file_path)) { + if (@wp_delete_file($file_path)) { + /* translators: %s: File name */ + $success_message = sprintf(__('Successfully deleted the %s file.', 'all-in-one-wp-security-and-firewall'), $file_name); + $aio_wp_security->debug_logger->log_debug($success_message, 0); + + if ($echo_results) { + AIOWPSecurity_Admin_Menu::show_msg_updated_st($success_message); + } + } else { + /* translators: %s: File name */ + $failure_message = sprintf(__('Failed to delete the %s file.', 'all-in-one-wp-security-and-firewall'), $file_name) . ' ' . sprintf(__('Check the file/directory permissions at: %s', 'all-in-one-wp-security-and-firewall'), $file_path); + $error[] = $file_name; + $aio_wp_security->debug_logger->log_debug($failure_message, 4); + + if ($echo_results) { + AIOWPSecurity_Admin_Menu::show_msg_error_st($failure_message); + } + } + } else { + /* translators: %s: File name */ + $message = sprintf(__('The %s file has already been deleted.', 'all-in-one-wp-security-and-firewall'), $file_name); + $info[] = $message; + $aio_wp_security->debug_logger->log_debug($message, 0); + + if ($echo_results) { + AIOWPSecurity_Admin_Menu::show_msg_updated_st($message); + } + } + } + + + return array( + 'info' => $info, + 'error' => empty($error) ? '' : implode(', ', $error) + ); + } + + /** + * Convert a number of bytes into a suitable textual string + * + * @param Integer $size - the number of bytes + * + * @return String - the resulting textual string + */ + public static function convert_numeric_size_to_text($size) { + if ($size > 1073741824) { + return round($size / 1073741824, 1).' GB'; + } elseif ($size > 1048576) { + return round($size / 1048576, 1).' MB'; + } elseif ($size > 1024) { + return round($size / 1024, 1).' KB'; + } else { + return round($size, 1).' B'; + } + } + + /** + * Updates the Googlebot IP ranges config. + * + * @return array|WP_Error + */ + public static function get_googlebot_ip_ranges() { + $response = wp_safe_remote_get('https://developers.google.com/static/search/apis/ipranges/googlebot.json'); + + $body = wp_remote_retrieve_body($response); + $json_array = json_decode($body, true); + + $ip_list_array = array(); + + foreach ($json_array['prefixes'] as $prefix) { + $ip_list_array[] = array_key_exists('ipv4Prefix', $prefix) ? $prefix['ipv4Prefix'] : $prefix['ipv6Prefix']; + } + + return AIOWPSecurity_Utility_IP::validate_ip_list($ip_list_array, 'whitelist'); + } + + /** + * This function creates and outputs the csv file for download + * + * @param array $items - the content + * @param array $export_keys - the keys for the content + * @param string $filename - the filename + * + * @return void + */ + public static function output_csv($items, $export_keys, $filename = 'data.csv') { + header("Content-Type: text/csv; charset=utf-8"); + header("Content-Disposition: attachment; filename=".$filename); + header("Pragma: no-cache"); + header("Expires: 0"); + $output = fopen('php://output', 'w'); //open output stream + + fputcsv($output, $export_keys, ',', '"', '\\'); // let's put column names first + + foreach ($items as $item) { + $csv_line = array(); + + foreach ($export_keys as $key => $value) { + if (isset($item[$key])) { + $csv_line[] = ('created' == $key) ? AIOWPSecurity_Utility::convert_timestamp($item[$key]) : $item[$key]; + } + } + fputcsv($output, $csv_line, ',', '"', '\\'); + } + } + + /** + * Check if a user is a member of the current blog ID in a multisite environment. + * + * @param int $user_id - User Id to check. + * + * @return bool Whether the user is a member of the current blog ID. + */ + public static function is_user_member_of_blog($user_id) { + $current_user_id = get_current_user_id(); + + if (is_multisite() && !is_super_admin($current_user_id)) { + $blog_id = get_current_blog_id(); + return is_user_member_of_blog($user_id, $blog_id); + } + + // Non-multisite or super admin, consider the user a member + return true; + } + + /** + * Blacklists an IP address. + * + * @global AIO_WP_Security $aio_wp_security + * @global AIOWPS\Firewall\Config $aiowps_firewall_config + * + * @param string $ip The IP address to be blacklisted. + * + * @return void|WP_Error + */ + public static function blacklist_ip($ip) { + global $aio_wp_security; + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + + $blacklisted_ip_addresses = $aio_wp_security->configs->get_value('aiowps_banned_ip_addresses'); + + $ip_list_array = AIOWPSecurity_Utility_IP::create_ip_list_array_from_string_with_newline($blacklisted_ip_addresses); + $ip_list_array[] = $ip; + + $validated_ip_list_array = AIOWPSecurity_Utility_IP::validate_ip_list($ip_list_array, 'blacklist'); + + if (is_wp_error($validated_ip_list_array)) { + return $validated_ip_list_array; + } else { + $banned_ip_data = implode("\n", $validated_ip_list_array); + + $aio_wp_security->configs->set_value('aiowps_enable_blacklisting', '1'); // Force blacklist feature to be enabled. + $aio_wp_security->configs->set_value('aiowps_banned_ip_addresses', $banned_ip_data); + $aio_wp_security->configs->save_config(); + + $aiowps_firewall_config->set_value('aiowps_blacklist_ips', $validated_ip_list_array); + } + } + + /** + * Unlocks an IP address. + * + * @global wpdb $wpdb + * + * @param string $ip The IP address to be blacklisted. + * + * @return boolean + */ + public static function unlock_ip($ip) { + global $wpdb; + + $lockout_table = AIOWPSEC_TBL_LOGIN_LOCKOUT; + + // Unlock single record. + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore. + $result = $wpdb->query($wpdb->prepare("UPDATE $lockout_table SET `released` = UNIX_TIMESTAMP() WHERE `failed_login_ip` = %s", $ip)); + + return null != $result; + } + + /** + * Unblacklists an IP address. + * + * @global AIO_WP_Security $aio_wp_security + * @global AIOWPS\Firewall\Config $aiowps_firewall_config + * + * @param string $ip The IP address to be unblacklisted. + * + * @return boolean + */ + public static function unblacklist_ip($ip) { + global $aio_wp_security; + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + + $blacklisted_ip_addresses = $aio_wp_security->configs->get_value('aiowps_banned_ip_addresses'); + + $ip_list_array = AIOWPSecurity_Utility_IP::create_ip_list_array_from_string_with_newline($blacklisted_ip_addresses); + + if (!in_array($ip, $ip_list_array)) { + return false; + } + + $ip_list_array = array_diff($ip_list_array, array($ip)); + + $banned_ip_data = implode("\n", $ip_list_array); + + $aio_wp_security->configs->set_value('aiowps_banned_ip_addresses', $banned_ip_data); + $aio_wp_security->configs->save_config(); + + $aiowps_firewall_config->set_value('aiowps_blacklist_ips', $ip_list_array); + + return true; + } + + /** + * Determines if the .htaccess file can be written to. + * + * This function checks if the current user has the necessary permissions + * (is the main site and super admin) and whether the server type is supported + * for writing to the .htaccess file. It prevents modifications on unsupported + * server types such as Nginx and IIS. + * + * @return bool True if .htaccess can be written to, false otherwise. + */ + public static function allow_to_write_to_htaccess() { + if (!AIOWPSecurity_Utility_Permissions::is_main_site_and_super_admin()) return false; + $serverType = self::get_server_type(); + + return !in_array($serverType, array('-1', 'nginx', 'iis')); + } + + /** + * Render the 5G Legacy Tab. + * + * This function checks if the current site is the main site and if the user is a super admin. + * If these conditions are met, it checks whether the 5G firewall is enabled or not. + * + * @global object $aio_wp_security The global instance of the All-In-One WP Security & Firewall plugin. + * + * @return bool returns true if the 5G firewall is enabled, false otherwise. + */ + public static function render_5g_legacy_tab() { + global $aio_wp_security; + if (!AIOWPSecurity_Utility_Permissions::is_main_site_and_super_admin()) return false; + + return '1' == $aio_wp_security->configs->get_value('aiowps_enable_5g_firewall'); + } + + /** + * Filters an array item based on a specified callback key. + * + * This function checks if a specified callback is present and callable within the array item. + * If the callback is callable, it executes the callback and returns the result. + * If the callback is set but not callable, it logs an error and returns false. + * If no callback is set, the function returns true. + * + * @param array $item The array item to filter. + * @param string $callback_key The key in the array to check for a callable function. + * + * @return bool|mixed Returns the result of the callback if callable, false if the callback is not callable, + * or true if no callback is set. + */ + public static function apply_callback_filter($item, $callback_key) { + if (isset($item[$callback_key])) { + if (is_callable($item[$callback_key])) { + return call_user_func($item[$callback_key]); + } else { + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- PCP warning. Required for AIOS error reporting. + error_log("Callback function set but not callable (coding error)"); + return false; + } + } else { + return true; + } + } + + /** + * Checks if other specific form-related plugins are active. + * + * @return bool Returns `true` if any of the specified plugins (bbPress, BuddyPress, + * or Contact Form 7) are active, or `false` if none of them are active. + */ + public static function is_other_form_plugins_active() { + return self::is_bbpress_plugin_active() || self::is_buddypress_plugin_active() || self::is_contact_form_7_plugin_active(); + } + + /** + * Unserialize data while maintaining compatibility across PHP versions due to different number of arguments required by PHP's "unserialize" function + * + * @param string $serialized_data Data to be unserialized, should be one that is already serialized + * @param boolean|array $allowed_classes Either an array of class names which should be accepted, false to accept no classes, or true to accept all classes + * @param integer $max_depth The maximum depth of structures permitted during unserialization, and is intended to prevent stack overflows + * + * @return mixed Unserialized data can be any of types (integer, float, boolean, string, array or object) + */ + public static function unserialize($serialized_data, $allowed_classes = false, $max_depth = 0) { + if (version_compare(PHP_VERSION, '7.0', '<')) { + $result = unserialize($serialized_data); + } else { + $result = unserialize($serialized_data, array('allowed_classes' => $allowed_classes, 'max_depth' => $max_depth)); // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctionParameters.unserialize_optionsFound -- This is the method used to unserialize data instead of the default unserialize method + } + return $result; + } + + /** + * Gets the rest route starting with namespace from the REST API endpoint + * It excludes rest url prefix 'wp-json' and multisite folder from the endpoint + * For example 'wc/store/v1/cart', 'contact-form-7/v1/contact-forms/45/feedback' + * + * @return string rest route starting with namespace + */ + public static function get_rest_route() { + $rest_route = !empty($_GET['rest_route']) ? sanitize_text_field(stripslashes($_GET['rest_route'])) : ''; + // If route is not found in query parameter, extract from REQUEST_URI + if (empty($rest_route)) { + $request_uri = !empty($_SERVER['REQUEST_URI']) ? urldecode($_SERVER['REQUEST_URI']) : ''; + $parsed_url = parse_url(trim($request_uri, '/')); + $path = isset($parsed_url['path']) ? $parsed_url['path'] : ''; + if (false !== strpos($path, rest_get_url_prefix())) { + $path = preg_replace('/index\.php\//', '', $path); // index.php from path removed. + $rest_route = preg_replace('/(.*)\/?'.rest_get_url_prefix().'\/?/', '', $path); // wp-json rest prefix and multisite folder excluded + $rest_route = trim($rest_route, '/'); + if (empty($rest_route)) $rest_route = '/'; // "wp-json" rest request without name space called. + } else { + $rest_route = ''; + } + } + return $rest_route; + } + + /** + * Get the registered namespace for REST routes end points 'wc', 'contact-form-7' + * + * @return array namespace. + */ + public static function get_rest_namespaces() { + $rest_server = rest_get_server(); + $namespaces = $rest_server->get_namespaces(); + $rest_route_namespaces = array(); + foreach ($namespaces as $namesapce) { + $rest_route_namespaces[] = explode('/', $namesapce)[0]; // Namespace 'wc' only to consider instead 'wc/v1', 'wc/v2', 'wc/v3', 'wc/store' + } + $route_namespaces = array_unique($rest_route_namespaces); + sort($route_namespaces); + return $route_namespaces; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-wp-footer-content.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-wp-footer-content.php new file mode 100755 index 00000000..97bf1dde --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/classes/wp-security-wp-footer-content.php @@ -0,0 +1,57 @@ +configs->get_value('aiowps_enable_woo_login_captcha') || '1' == $aio_wp_security->configs->get_value('aiowps_enable_woo_register_captcha') || '1' == $aio_wp_security->configs->get_value('aiowps_enable_woo_checkout_captcha') || '1' == $aio_wp_security->configs->get_value('aiowps_enable_woo_lostpassword_captcha')) { + $aio_wp_security->captcha_obj->print_captcha_api_woo(); + } + } + + // Activate the copy protection feature for non-admin users + $copy_protection_active = $aio_wp_security->configs->get_value('aiowps_copy_protection') == '1'; + if ($copy_protection_active && !AIOWPSecurity_Utility_Permissions::has_manage_cap()) { + $this->output_copy_protection_code(); + } + + //TODO - add other footer output content here + } + + public function output_copy_protection_code() { + ?> + + + configs->get_value('aiowps_enable_rename_login_page') == '1') { + include_once(AIO_WP_SECURITY_PATH . '/classes/wp-security-process-renamed-login-page.php'); + new AIOWPSecurity_Process_Renamed_Login_Page(); + AIOWPSecurity_Process_Renamed_Login_Page::renamed_login_init_tasks(); + } else { + add_action('login_init', array($this, 'aiowps_login_init')); + } + + $this->do_lockout_tasks(); + + do_action('aiowps_wp_loaded_tasks_end', $this); + + } + + /** + * Perform lockout task if it is applicable. + * + * @return void + */ + private function do_lockout_tasks() { + global $aio_wp_security; + + if (1 != $aio_wp_security->configs->get_value('aiowps_site_lockout')) { + return; + } + + if ('admin-ajax.php' == $GLOBALS['pagenow']) { + return; + } + + // Show login screen to all non-logged in users. + if ('wp-login.php' == $GLOBALS['pagenow']) { + return; + } + + // WP CLI and cronjob do not required site lockout. + if ((defined('DOING_CRON') && DOING_CRON) || 'cli' == PHP_SAPI) { + return; + } + + // The lockout message should not be displayed to an administrator user. + if (is_user_logged_in() && current_user_can('manage_options')) { + return; + } + + // Non administrator users to lockout accessing admin area. + if (is_user_logged_in() && !current_user_can('manage_options') && is_admin()) { + wp_redirect(home_url()); + } + + // Non-logged in users try access admin area, redirect to login page. + if (is_admin()) { + return; + } + + self::site_lockout_tasks(); + } + + /** + * Render lockout output. + * + * @return void + */ + public static function site_lockout_tasks() { + $lockout_output = apply_filters('aiowps_site_lockout_output', ''); + if (empty($lockout_output)) { + nocache_headers(); + header("HTTP/1.0 503 Service Unavailable"); + remove_action('wp_head', 'head_addons', 7); + $template = apply_filters('aiowps_site_lockout_template_include', AIO_WP_SECURITY_PATH . '/other-includes/wp-security-visitor-lockout-page.php'); + include_once($template); + } else { + echo wp_kses_post($lockout_output); + } + + exit(); + } + + public static function aiowps_login_init() { + //if user is logged in and tries to access login page - redirect them to wp-admin + //this will prevent issues such as the following: + //https://wordpress.org/support/topic/already-logged-in-no-captcha + if (is_user_logged_in()) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce. + $redirect_to = (isset($_REQUEST['redirect_to'])) ? sanitize_text_field(wp_unslash($_REQUEST['redirect_to'])) : admin_url(); + wp_safe_redirect($redirect_to); + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce. + } elseif (!(isset($_GET['action']) && 'postpass' == $_GET['action'])) { + AIOWPSecurity_Utility_IP::check_login_whitelist_and_forbid(); + } + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/css/index.html b/wp-content/plugins/all-in-one-wp-security-and-firewall/css/index.html new file mode 100755 index 00000000..e69de29b diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/css/wp-security-admin-styles.css b/wp-content/plugins/all-in-one-wp-security-and-firewall/css/wp-security-admin-styles.css new file mode 100755 index 00000000..4ffeaaa6 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/css/wp-security-admin-styles.css @@ -0,0 +1,1211 @@ +.aio_bold { + font-weight: bold; +} + +.aio_half_width { + width: 50%; +} + +.aio_one_third_width { + width: 33%; +} + +.aio_width_80 { + width: 80%; +} + +.aio_max_500 { + max-width: 500px; +} + +.aio_spacer_15 { + margin-top: 15px; +} + +.aio_spacer_10_tb { + margin: 10px 0; +} + +.aio_spacer_10_tblr { + margin: 10px; +} + +.aio_clear_float { + clear: both; +} + +.aio_float_left { + float: left; +} + +.aio_padding_10 { + padding: 10px !important; +} + +.aio_section_separator_1 { + border-bottom: 1px solid #DEDEDE; + height: 10px; +} + +.aiowps_admin_ul_grp1 { + list-style: circle; + padding: 0 0 0 30px; +} + +.aio_grey_box { + margin: 10px 0 15px 0; + background-color: #ECECEC; + border: 1px solid #CFCFCF; + padding: 0 0 0 1em; +} + +.aio_yellow_box { + margin: 10px 0 15px 0; + background-color: #FFFFE0; + border-color: #E6DB55; + border-radius: 3px; + border-style: solid; + border-width: 1px; + padding: 0 0 0 1em; +} + +.aio_blue_box { + margin: 10px 0 15px 0; + background-color: #F0F9FF; + border-color: #16B; + color: #16B; + border-radius: 3px; + border-style: solid; + border-width: 1px; + padding: 0 0 0 1em; + line-height: 20px; + overflow-wrap: break-word; +} + +.aio_green_box { + margin: 10px 0 15px 0; + background-color: #CCF4D6; + border-color: #059B53; + color: #043B14; + border-radius: 3px; + border-style: solid; + border-width: 1px; + padding: 0 1em; +} + +.aio_red_box { + margin: 10px 0 15px 0; + background-color: #FFEBE8; + border-color: #C00; + color: #333; + border-radius: 3px; + border-style: solid; + border-width: 1px; + padding: 0 1em; +} + +.aio_orange_box { + margin: 10px 0 15px 0; + background-color: #FFB900; + border-color: #D64500; + border-radius: 3px; + border-style: solid; + border-width: 1px; + padding: 0 1em; +} + +.aio_success_with_icon { + background-image: url("../images/success.png"); + background-repeat: no-repeat; + color: #529901; + padding-left: 20px; + font-size: 14px; +} + +.aio_error_with_icon { + color: #F00; + background-image: url("../images/error.png"); + background-repeat: no-repeat; + padding-left: 20px; + font-size: 14px; +} + +.aio_info_with_icon { + background-image: url("../images/info-icon.png"); + background-repeat: no-repeat; + color: #16B; + padding-left: 20px; + font-size: 14px; +} + +.file_permission_table { + margin: 20px 0; +} + +.file_permission_table thead tr th { + background: #CCC; +} + +.file_permission_table td { + padding: 7px; + font-family: "Courier 10 Pitch",courier,monospace; + color: #262626; + border-bottom: 1px solid #F2F2F2; + border-top: none; +} + +.aio_table_row_red { + background-color: #FD6D73; +} + +.aio_table_row_yellow { + background-color: #F5E679; +} + +.aio_table_row_green { + background-color: #C8F18B; +} + +.aiowps_loading_1 { + margin: 0 5px; +} + +.aio_text_area_file_output { + background: none repeat scroll 0 0 #F9F9F9; + font-family: consolas,monaco,monospace; + font-size: 12px; + outline: 0 none; +} + +.aiowps_more_info_anchor { + display: inline-block; + background-color: #D9D9D9; + color: #21759B; + font: 0.9em/1.455em "Lucida Grande","Lucida Sans Unicode",tahoma,verdana,sans-serif; + text-decoration: none; + padding: 3px 5px; +} + +.aiowps_more_info_anchor:hover { + color: #333; + cursor: pointer; +} + +.aiowps_more_info_toggle_char { + display: inline-block; + margin-right: 3px; + padding: 0 3px; + text-align: center; + background-color: #EDEDED; + width: 10px; +} + +.aiowps_more_info_body { + margin: 10px 0 15px 0; + background-color: #FFFFE0; + border-color: #E6DB55; + border-radius: 3px; + border-style: solid; + border-width: 1px; + padding: 0 0 0 1em; +} + +.aiowps_dashboard_box_small { + float: left; + max-width: 350px; + margin-right: 15px; +} + +#canvas-holder { + width: 300px; + margin: auto; + padding-top: 20px; +} + +#website-strength-text { + text-align: center !important; + font-size: 1.5em !important; + padding-bottom: 20px !important; +} + +#security_strength_chart_div table { + margin-right: auto !important; + margin-left: auto !important; +} + +.aiowps_dashboard_widget_footer { + background-color: #E6E6E6; + padding: 10px; +} + +.aiowps_feature_status_bar { + display: block; + float: left; + width: 120px; + height: 26px; + position: relative; + background: rgba(0, 0, 0, 0.25); + border-radius: 3px; + -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px rgba(255, 255, 255, 0.1); /* phpcs:ignore Squiz.CSS.ForbiddenStyles.FoundWithAlternative -- This is a fallback for older browsers */ + box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px rgba(255, 255, 255, 0.1); +} + +.aiowps_feature_status_name { + width: 50%; + font-weight: bold; + float: left; + padding: 5px 10px 5px 0; +} + +.aiowps_feature_status_label { + display: block; + float: left; + padding: 4px; + text-align: center; + width: 52px; + color: #F7F7F7; + font-weight: bold; + text-transform: uppercase; +} + +.aiowps_feature_status_on { + color: #043B14; + background: #65BD63; + border-radius: 3px; + background-image: -webkit-linear-gradient(top, #9DD993, #65BD63); /* phpcs:ignore Squiz.CSS.DuplicateStyleDefinition.Found -- For Safari and Chrome */ + background-image: -moz-linear-gradient(top, #9DD993, #65BD63); /* phpcs:ignore Squiz.CSS.DuplicateStyleDefinition.Found -- For Mozilla */ + background-image: -o-linear-gradient(top, #9DD993, #65BD63); /* phpcs:ignore Squiz.CSS.DuplicateStyleDefinition.Found -- For Opera */ + background-image: linear-gradient(top bottom, #9DD993, #65BD63); /* phpcs:ignore Squiz.CSS.DuplicateStyleDefinition.Found -- Previous definitions are for outdated browsers */ + -webkit-box-shadow: inset 0 1px rgba(255, 255, 255, 0.5), 0 0 2px rgba(0, 0, 0, 0.2); /* phpcs:ignore Squiz.CSS.ForbiddenStyles.FoundWithAlternative -- This is a fallback for older browsers */ + box-shadow: inset 0 1px rgba(255, 255, 255, 0.5), 0 0 2px rgba(0, 0, 0, 0.2); +} + +.aiowps_feature_status_off { + color: #4D0000; + background: #BD6363; + border-radius: 3px; + background-image: -webkit-linear-gradient(top, #D99393, #BD6363); /* phpcs:ignore Squiz.CSS.DuplicateStyleDefinition.Found -- For Safari and Chrome */ + background-image: -moz-linear-gradient(top, #D99393, #BD6363); /* phpcs:ignore Squiz.CSS.DuplicateStyleDefinition.Found -- For Mozilla */ + background-image: -o-linear-gradient(top, #D99393, #BD6363); /* phpcs:ignore Squiz.CSS.DuplicateStyleDefinition.Found -- For Opera */ + background-image: linear-gradient(top bottom, #D99393, #BD6363); /* phpcs:ignore Squiz.CSS.DuplicateStyleDefinition.Found -- Previous definitions are for outdated browsers */ + -webkit-box-shadow: inset 0 1px rgba(255, 255, 255, 0.5), 0 0 2px rgba(0, 0, 0, 0.2); /* phpcs:ignore Squiz.CSS.ForbiddenStyles.FoundWithAlternative -- This is a fallback for older browsers */ + box-shadow: inset 0 1px rgba(255, 255, 255, 0.5), 0 0 2px rgba(0, 0, 0, 0.2); +} + +.aiowps_features_grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); + grid-gap: 0 10px; + margin: 10px 0; +} + +.aiowps_critical_feature_link, +.aiowps_critical_feature_link:hover { + text-decoration: none; + color: inherit; +} + +.aiowps_critical_feature_status_container { + display: flex; + align-items: center; + padding: 5px 8px; + min-height: 30px; + transition: all 0.2s ease; +} + +.aiowps_critical_feature_status_name { + flex: 1.5; + font-weight: bold; + margin-right: 8px; +} + +.aiowps_feature_status_circle { + width: 24px; + height: 24px; + display: flex; + justify-content: center; + align-items: center; + flex: 1; +} + +.aiowps_feature_status_circle_on, +.aiowps_feature_status_circle_off { + width: 16px; + height: 16px; + border-radius: 50%; + transition: transform 0.2s ease; +} + +.aiowps_feature_status_circle_on { + background-color: #4CD964; +} + +.aiowps_feature_status_circle_off { + background-color: #E4584F; +} + +.aiowps_critical_feature_status_container:hover .aiowps_feature_status_circle_on, +.aiowps_critical_feature_status_container:hover .aiowps_feature_status_circle_off { + transform: scale(1.1); +} + +@media (max-width: 768px) { + + .aiowps_features_grid { + grid-template-columns: 1fr; + } + +} + +.aiowps_feature_details_badge { + width: 100%; + font-size: 14px; +} + +.aiowps_feature_details_badge_difficulty, .aiowps_feature_details_badge_points { + display: inline-block; + padding: 7px; +} + +.aiowps_feature_details_badge_difficulty { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + margin-right: 0; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); +} + +.aiowps_feature_details_badge_points { + background: #F1F1F1; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + margin-left: -3px; +} + +.aiowps_feature_protection_none { + background: #6D797A; + color: #FFF; +} + +.aiowps_feature_protection_full { + background: #5C3682; + color: #FFF; +} + +#aiowps_pw_tool_main { + padding-top: 10px; +} + +.aiowps_password_tool_field { + padding: 20px 0; +} + +#aiowps_password_crack_info_text, #aiowps_password_hibp_info_text { + display: none; + line-height: 1.16667em; + max-width: 40%; +} + +#aiowps_password_crack_time_calculation { + line-height: 1.16667em; + color: darkorange; +} + +/* bootstrap type labels */ +.aiowps_dashboard_table { + table-layout: fixed; +} + +.aiowps-label-danger { + background-color: #D9534F; +} + +.aiowps-label-warning { + background-color: #F0AD4E; +} + +.aiowps-label-primary { + background-color: #337AB7; +} + +.aiowps-label-success { + background-color: #5CB85C; +} + +.aiowps-label { + border-radius: 0.25em; + color: #FFF; + display: inline; + font-size: 75%; + font-weight: 700; + line-height: 1; + padding: 0.2em 0.6em 0.3em; + text-align: center; + vertical-align: baseline; + white-space: nowrap; +} + +/* Fix for wp list table nav buttons style messed up in 5.1 */ +.tablenav .tablenav-pages .pagination-links a { + display: inline-block; + padding: 4px 5px 6px 5px; + font-size: 16px; + line-height: 1; + text-align: center; + text-decoration: none; + min-width: 17px; + border: 1px solid #CCC; + background: #F7F7F7; +} + +svg > g > g.google-visualization-tooltip { + pointer-events: none; +} + +.wp-security_page_aiowpsec_settings h2, .wp-security_page_aiowpsec_settings #poststuff h2 { + padding-left: 0; +} + +.aio_hidden { + display: none; +} + +/* Fix for WordPress thickbox not respecting the set width and height */ +/* Open issue for 8 years : https://core.trac.wordpress.org/ticket/27473 */ +#TB_ajaxContent { + width: 95% !important; + height: 95% !important; +} + +.aiowps_switch { + position: relative; + display: inline-block; + width: 38px; + height: 18px; + margin-right: 6px; + box-sizing: border-box; +} + +.aiowps_switch input { + opacity: 0; + width: 0; + height: 0; +} + +.aiowps_switch .aiowps_slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #F2F4F5; + transition: 0.2s; + /* Rounded sliders */ +} + +.aiowps_switch .aiowps_slider::before { + position: absolute; + content: ""; + height: 8px; + width: 8px; + left: 2px; + bottom: 2px; + background-color: #555D66; + border: 1px solid #555D66; + transition: all 0.2s; +} + +.aiowps_switch .aiowps_slider::after { + content: ""; + display: block; + position: absolute; + height: 4px; + width: 3px; + right: 4px; + top: 4px; + border-radius: 50%; + border: 1px solid #72777C; + box-sizing: content-box; +} + +.aiowps_switch .aiowps_slider.round { + border-radius: 23px; + border: 2px solid #555D66; +} + +.aiowps_switch .aiowps_slider.round::before { + border-radius: 50%; +} + +.aiowps_switch input:checked + .aiowps_slider { + background: #5C3682; + border-color: #6F30C9; +} + +.aiowps_switch input:checked + .aiowps_slider::before { + background: #FFF; + border-color: #FFF; + transform: translatex(20px); +} + +.aiowps_switch input:checked + .aiowps_slider::after { + content: ""; + display: block; + position: absolute; + height: 6px; + width: 2px; + left: 7px; + top: 4px; + background: #FFF; + border: none; +} + +.aiowps_switch input:disabled + .aiowps_slider, +.aiowps_switch input:disabled:checked + .aiowps_slider { + background: rgba(85, 93, 102, 0.5); + border-color: #555D66; + opacity: 0.3; +} + +.aiowps_switch input:focus + .aiowps_slider { + box-shadow: 0 0 0 2px #F2F4F5, 0 0 0 3px #555D66; +} + +.aiowps_switch input:disabled { + display: none; + /* Hide default HTML checkbox when it's disabled*/ +} + +.aiowps_next_scheduled_scan_wrapper { + display: flex; + background: #FFF; + justify-items: center; + flex-wrap: wrap; +} + +.aiowps_next_scheduled_scan_wrapper > div { + width: 50%; + background: #FFF; + height: auto; + padding: 33px; + box-sizing: border-box; +} + +.aiowps_next_scheduled_entity { + width: 50%; + display: inline-block; + float: left; +} + +.aiowps_next_scheduled_entity .dashicons { + color: #CCC; + font-size: 20px; +} + +.aiowps_next_scheduled_entity strong { + font-size: 20px; +} + +.aiowps_next_scheduled_heading { + margin-bottom: 10px; +} + +.aiowps_time_now_wrapper { + margin-top: 68px; + width: 100%; +} + +.aiowps_time_now_label, .aiowps_time_now { + display: inline-block; + padding: 7px; +} + +.aiowps_time_now_label { + background: #6D797A; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + color: #FFF; + margin-right: 0; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); +} + +.aiowps_time_now { + background: #F1F1F1; + color: #3C434A; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + margin-left: -3px; +} + +.aiowps_scan_btn_wrapper { + text-align: center; + border-left: 1px solid #F1F1F1; + justify-content: center; + align-items: center; +} + +.aiowps_scan_btn_wrapper .button-large { + font-size: 1.3em !important; +} + +.aiowps_next_scheduled_date_time { + color: #46A84B; +} + +#aiowps_activejobs_table { + overflow: hidden; + width: 100%; + background: #FAFAFA; + padding: 0; +} + +#aiowps_activejobs_table p { + text-align: center; +} + +#aiowps_previous_scan_wrapper { + overflow: hidden; + width: 100%; + background: #FAFAFA; + padding: 0; +} + +.aiowps_table_container { + max-height: 300px; + overflow-y: scroll; + margin-top: 20px; + border: 1px solid #C3C4C7; +} + +.aiowps_scan_result_table { + width: 100%; + border: none !important; +} + +.aiowps_scan_result_table_header { + position: sticky; + top: 0; + background-color: #FFF; + z-index: 1; +} + +.aiowps_spinner.spinner { + padding-left: 25px; + float: none; +} + +.aiowps_spinner.spinner.visible { + visibility: visible; + width: auto; +} + +.button-link.aios-toggle-advanced-options { + text-decoration: none; +} + +.button-link.aios-toggle-advanced-options:hover { + background-color: #FFF; +} + +.button-link.aios-toggle-advanced-options:focus { + background-color: #FFF; +} + +button.button-link.aios-toggle-advanced-options.advanced-options-disabled, button.button-link.aios-toggle-advanced-options.advanced-options-disabled span.dashicons-arrow-down-alt2:before { + color: #A7AAAD!important; + box-shadow: none!important; + cursor: default; + transform: none!important; +} + +.aios-toggle-advanced-options { + display: block; + width: 100%; + margin-left: -20px; + margin-right: -20px; + padding-left: 20px; + padding-right: 20px; + position: relative; + text-decoration: none; +} + +.aios-toggle-advanced-options span.text { + background: #FFF; + z-index: 1; + position: relative; + padding-right: 5px; +} + +.aios-toggle-advanced-options span.dashicons { + text-decoration: none; + font-size: 16px; + height: 16px; + vertical-align: middle; + transition: .2s all; + color: #444; +} + +.aios-toggle-advanced-options.opened::before { + content: ''; + border-top: 1px solid #CCC; + width: calc(100% + 13px); + position: absolute; + top: 16px; + left: -5px; +} + +.aios-toggle-advanced-options.opened span.dashicons { + transform: rotate(180deg); +} + +.aios-toggle-advanced-options.opened .aios-toggle-advanced-options__text-hide { + display: inline-block; +} + +.aios-toggle-advanced-options.opened .aios-toggle-advanced-options__text-show { + display: none; +} + +.aios-toggle-advanced-options .aios-toggle-advanced-options__text-show { + display: inline-block; +} + +.aios-toggle-advanced-options .aios-toggle-advanced-options__text-hide { + display: none; +} + +.aios-advanced-options-panel { + display: none; +} + +.aios-toggle-advanced-options.opened + div.aios-advanced-options-panel { + display: block; +} + +.aios-advanced-options-panel h3 { + font-size: 14px; + display: inline-block; +} + +.aios-advanced-options-panel span.dashicons.dashicons-editor-help { + vertical-align: middle; + margin-bottom: 10px; +} + +[data-tooltip] { + cursor: pointer; + position: relative; +} + +[data-tooltip]:hover[data-tooltip]::before, [data-tooltip]:hover[data-tooltip]::after { + visibility: visible; + filter: opacity(100); + opacity: 1; + pointer-events: all; +} + +[data-tooltip]::before, [data-tooltip]::after { + visibility: hidden; + filter: opacity(0); + opacity: 0; + pointer-events: none; +} + +[data-tooltip]::before { + position: absolute; + bottom: 150%; + left: 50%; + margin-bottom: 5px; + margin-left: -110px; + padding: 12px; + width: 275px; + z-index: 9999; + border-radius: 3px; + background-color: hsla(0,0%,20%,0.95); + color: #FFF; + content: attr(data-tooltip); + text-align: center; + font-size: .85rem; + font-weight: 400; + line-height: 1.4; +} + +[data-tooltip]::after { + position: absolute; + bottom: 150%; + left: 50%; + margin-left: -5px; + width: 0; + border-top: 5px solid hsla(0,0%,20%,0.9); + border-right: 5px solid transparent; + border-left: 5px solid transparent; + content: " "; + font-size: 0; + line-height: 0; +} + +.dep-warning { + background-color: #EED202; + padding: 1.2em; + margin-right: 20px; + margin-left: 20px; + margin-top: 10px; + line-height: 1.2em; + color: #111E2A; +} + +.dep-warning span { + vertical-align: middle; +} + +@media only screen and (max-width: 782px) { + + .aiowps_next_scheduled_scan_wrapper > .aiowps_scan_btn_wrapper { + padding-top: 0; + } + + .aiowps_next_scheduled_scan_wrapper { + flex-direction: column; + } + + .aiowps_next_scheduled_scan_wrapper > div { + width: 100%; + } + + #aiowps_manual_fcd_scan { + margin: 0; + display: block; + width: 100%; + } + +} + +@media screen and (max-width: 600px) { + + .aiowps_next_scheduled_entity { + float: none; + width: 100%; + margin-bottom: 2em; + } + + .aiowps_time_now_wrapper { + margin-top: 0; + } + +} + +.details.column-details { + max-height: 100px; + overflow-y: auto; + overflow-x: hidden; + display: block; + word-wrap: break-word; +} + +.blockUI.blockOverlay.ui-widget-overlay { + background: #000; +} + +.aios_success_popup { + text-align: center; + padding-bottom: 30px; +} + +.aios_success_popup > .dashicons { + font-size: 100px; + width: 100px; + height: 100px; + line-height: 100px; + padding: 0; + border-radius: 50%; + margin-top: 30px; + display: block; + margin-left: auto; + margin-right: auto; + background: #E2E6E5; +} + +.aios_success_popup > .dashicons.dashicons-yes { + text-indent: -5px; +} + +.aios_success_popup.success > .dashicons { + color: #008000; +} + +.aios_success_popup.warning > .dashicons { + color: #888; +} + +.aios_success_popup--message { + padding: 20px; +} + +.button.aios-close-overlay .dashicons { + text-decoration: none; + font-size: 20px; + margin-left: -5px; + padding: 0; + transform: translatey(5px); +} + +.aios_saving_popup img { + animation-name: aios_blink; + animation-duration: 610ms; + animation-iteration-count: infinite; + animation-direction: alternate; + animation-timing-function: ease-out; +} + +.aios-modal-info { + text-align: justify; + display: inline-block; +} + +@keyframes aios_blink { + + from { + opacity: 1; + transform: scale(1); + } + + to { + opacity: 0.4; + transform: scale(0.85); + } + +} + +#aios_ajax_moreoptions { + max-height: 150px; /* Set the maximum height */ + overflow-y: auto; + overflow-x: hidden; + padding: 6px 10px; + margin: 4px 16px 6px 16px; +} + +.aios_password_meter { + width: 100%; +} + +.aios_meter_bar { + width: 40%; + background-color: #EEE; + border-radius: 10px; + overflow: hidden; + height: 10px; + margin: 10px 10px 0 0; +} + +#aios_meter_fill { + height: 100%; + width: 0; + background-color: #F00; + border-radius: 5px; + transition: width 0.5s ease-in-out; +} + +#aiowps_password_test { + width: 40%; +} + +.simbaotp_qr_container img { + border-collapse: collapse; + max-width: 150px; + width: 100%; + max-height: 150px; +} + +.aiowps-postbox-container { + display: flex; + background: #FFF; + border: 1px solid #D3D3D3; + padding: 5px; +} + +.aiowps-postbox-container .postbox { + border: none; + box-shadow: none; +} + +.aiowps-postbox-container h4 { + margin: 1em 0; + padding: 5px; +} + +.aiowps-postbox-container .aiowps_switch_container .aiowps_more_info_anchor { + margin: 10px 0px; + display: block; + position: relative; + width: fit-content; +} + +.aiowps-rule-list { + list-style: none; + max-height: 450px; + overflow-y: auto; + padding: 5px; + border-top: 0.5px solid #D3D3D3; + margin-bottom: 0; +} + +.aiowps-rule-list li { + padding: 5px 0px; + display: flex; + justify-content: space-between; + margin-bottom: unset; +} + +.aiowps-rule-list li .aiowps-rule-title { + cursor: pointer; + padding: 10px 5px; + border-radius: 3px; + width: 100%; +} + +.aiowps-rule-list li:not(:last-child) { + border-bottom: 0.5px solid #D3D3D3; +} + +.aiowps-rule-list li .aiowps-rule-title:hover { + background: #F8F9FA; +} + +.aiowps-active .aiowps-rule-title { + font-weight: bold; + background: #5C3682 !important; + color: #FFF !important; +} + +.aiowps-rules { + margin-right: 5px; + width: 20%; + border-right: 1px solid #D3D3D3; +} + +.aiowps-settings { + width: 80%; +} + +#aiowps-rule-search { + position: relative; + display: flex; + align-items: center; +} + +#aiowps-rule-search .aiowps-search { + flex: 1; + background-image: none; + position: relative; + padding-right: 25px; + padding-left: 25px; + display: inline-flex; + align-items: center; + align-items: -moz-center; /* phpcs:ignore Squiz.CSS.DuplicateStyleDefinition.Found -- For Mozilla */ + -webkit-align-items: center; + width: fill-available; + width: -webkit-fill-available; /* phpcs:ignore Squiz.CSS.DuplicateStyleDefinition.Found -- For Safari & Chrome */ + width: -moz-available; /* phpcs:ignore Squiz.CSS.DuplicateStyleDefinition.Found -- For Mozilla */ + max-width: fill-available; + max-width: -webkit-fill-available; /* phpcs:ignore Squiz.CSS.DuplicateStyleDefinition.Found -- For Safari & Chrome */ + max-width: -moz-available; /* phpcs:ignore Squiz.CSS.DuplicateStyleDefinition.Found -- For Mozilla */ + margin-right: 5px; +} + +#aiowps-rule-search .dashicons-search { + font-family: dashicons; + font-size: 18px; + line-height: 1; + font-weight: 400; + font-style: normal; + display: inline-block; + text-transform: none; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + position: absolute; + vertical-align: middle; + margin-right: 5px; + top: 50%; + left: 5px; + z-index: 999; + transform: translatey(-50%); +} + +#aiowps-rule-search .clear-search { + position: absolute; + right: 10px; + top: 50%; + transform: translatey(-50%); + cursor: pointer; +} + +#aiowps-rule-search .clear-search:hover { + color: #000; +} + +.aiowps-actions { + background: #FFF; + min-height: 60px; + margin-top: 0px; + border: 1px solid #D3D3D3; + border-top: none; + align-content: center; + padding-right: 15px; + text-align: right; + text-align: -webkit-right; /* phpcs:ignore Squiz.CSS.DuplicateStyleDefinition.Found -- For Safari & Chrome */ + text-align: -moz-right; /* phpcs:ignore Squiz.CSS.DuplicateStyleDefinition.Found -- For Mozilla */ + justify-content: end; + align-items: center; + display: flex; +} + +@media only screen and (max-width: 768px) { + + .aiowps-postbox-container { + flex-direction: column; + } + + .aiowps-settings { + width: 100%; + } + + .aiowps-rules { + width: 100%; + margin-bottom: 10px; + border-right: none; + border-bottom: 1px solid #D3D3D3; + } + + .aiowps-rule-list { + max-height: 390px; + } + +} + +#simba-tfa-admin-wrapper form { + padding: 10px; + position: relative; + min-width: 255px; + border: 1px solid #C3C4C7; + box-shadow: 0 1px 1px rgba(0, 0, 0, .04); + background: #FFF; +} + +.aios-data-table { + border-collapse: collapse; + width: 100%; +} + +.aios-data-table td, .aios-data-table th { + border: 1px solid #DDD; + padding: 8px; +} + +.aios-data-table tr:nth-child(even) { + background-color: #F2F2F2; +} + +.aios-data-table tr:hover { + background-color: #DDD; +} \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/css/wp-security-notices.css b/wp-content/plugins/all-in-one-wp-security-and-firewall/css/wp-security-notices.css new file mode 100755 index 00000000..88a6e74d --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/css/wp-security-notices.css @@ -0,0 +1,121 @@ +/* CSS for adverts */ + +.aiowps_notice_container { + height: auto; + overflow: hidden; +} + +.aiowps_review_notice_container { + padding: 12px; + display: flex; +} + +.aiowps_advert_button_container { + margin-bottom: 10px; + display: flex; + align-items: center; +} + +.aiowps_advert_button_container .dashicons { + margin-left: 10px; +} + +.aiowps_advert_content_left { + float: none; + width: 65px; + padding-top: 9px; + margin-right: 9px; +} + +.aiowps_advert_content_left_extra { + float: none; + width: 100px; + padding-right: 15px; + display: flex; + align-items: center; +} + +.updraft_advert_content_left img { + min-height: 72px; + min-width: 72px; +} + +.aiowps_advert_content_right { + float: none; + width: auto; + overflow: hidden; + font-size: 16px; +} + +.updraft_advert_content_right p { + font-size: 16px !important; +} + +.aiowps_advert_bottom { + margin: 10px 0; + padding: 10px; + font-size: 140%; + background-color: rgb(255, 255, 255); + border-color: #E6DB55; + border: 1px solid; + border-radius: 4px; +} + +.aiowps_advert_dismiss { + float: right; + font-size: 13px; + font-weight: normal; +} + +h3.aiowps_advert_heading { + margin-top: 5px !important; + margin-bottom: 5px !important; +} + +h4.aiowps_advert_heading { + margin-top: 2px !important; + margin-bottom: 3px !important; +} + +.aiowps_center_content { + text-align: center; + margin-bottom: 5px; +} + +.aiowps_text_center { + text-align: center; +} + +#aiowps-dashnotice #aiowps-dashnotice_wrapper ul { + list-style: disc inside; + text-indent: -18px; + margin-left: 18px; +} + +@media screen and (min-width: 560px) { + + .aiowps_advert_content_left, .aiowps_advert_content_left_extra { + float: left; + } + +} + +#aiowps-notice-logo { + border: 0; + float: right; + width: 150px; + height: auto; + margin-right: 10px; + margin-top: 10px; +} + +@media (min-width: 768px) { + + #aiowps-notice-logo { + width: 250px; + height: auto; + margin-right: 40px; + margin-top: 40px; + } + +} \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/css/wp-security-premium-upgrade.css b/wp-content/plugins/all-in-one-wp-security-and-firewall/css/wp-security-premium-upgrade.css new file mode 100755 index 00000000..afc9b5d8 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/css/wp-security-premium-upgrade.css @@ -0,0 +1,241 @@ +.aiowps_col { + display: block; + float: left; + margin: 1% 0 1% 1%; +} + +.aiowps_col:first-child { + margin-left: 0; +} + +.aiowps_half_width { + width: 48%; +} + +@media screen and (max-width: 768px) { + + .aiowps_col { + margin: 1% 0; + } + + .aiowps_half_width { + width: 100%; + } + +} + +img.addons { + display: block; + margin-left: auto; + margin-right: auto; + margin-bottom: 20px; + max-width: 40%; + max-height: 100%; +} + +.postbox.aiowps-tab-postbox { + padding: 25px; +} + +.aiowps-plugin-family__plugins { + display: -ms-flexbox; + display: flex; /* phpcs:ignore Squiz.CSS.DuplicateStyleDefinition.Found -- first definition is for IE */ + -ms-flex-wrap: wrap; + flex-wrap: wrap; + padding-left: 1px; + padding-bottom: 1px; +} + +.aiowps-plugin-family__plugin { + -ms-flex: auto; + flex: auto; + width: 100%; + padding: 30px; + box-sizing: border-box; + border: 1px solid #E3E4E7; + margin-left: -1px; + margin-bottom: -1px; +} + +@media (min-width: 782px) { + + .aiowps-plugin-family__plugin { + width: 50%; + } + + .aiowps-plugin-family__free .aiowps-plugin-family__plugin { + width: 100%; + } + +} + +@media (max-width: 1300px) { + + .aiowps-plugin-family__free .aiowps-plugin-family__plugin { + width: 50%; + } + +} + +@media (max-width: 782px) { + + .aiowps-plugin-family__free .aiowps-plugin-family__plugin { + width: 100%; + } + +} + +.aiowps_feature_cont { + width: 64.5%; +} + +.aiowps_plugin_family_cont { + width: 34.5%; +} + +@media (max-width: 1300px) { + + .aiowps_feature_cont, + .aiowps_plugin_family_cont { + width: 100%; + float: none; + margin: 0; + } + +} + +.aiowps_feature_cont header, +.aiowps_plugin_family_cont header { + padding: 20px; +} + +@media (max-width: 1300px) { + + .aiowps_feature_cont header, + .aiowps_plugin_family_cont header { + padding: 40px; + } + +} + +.aiowps_feature_cont header p, +.aiowps_plugin_family_cont header p { + margin-bottom: 0; +} + +.aiowps_feat_table, +.aiowps_feat_table td { + border: 0; + border-collapse: collapse; + background-color: #FFF; + font-size: 120%; + text-align: center; +} + +.aiowps_feat_table td { + border: 1px solid #F1F1F1; + border-bottom-width: 4px; + padding: 15px; +} + +.aiowps_feat_table td:nth-child(2), +.aiowps_feat_table td:nth-child(3) { + background: rgba(241, 241, 241, 0.38); +} + +.aiowps_feat_table p { + padding: 0 10px; + margin: 5px 0; + font-size: 13px; +} + +.aiowps_feat_table h4 { + padding-left: 10px; + margin: 5px 0; +} + +.aiowps_feat_table .dashicons { + width: 25px; + height: 25px; + font-size: 25px; + line-height: 1; +} + +.aiowps_feat_table .dashicons-yes { + color: #008000; +} + +.aiowps_feat_table .dashicons-no-alt { + color: #FD0000; +} + +.aiowps_feat_table tr td.aiowps-feature-text { + text-align: left; +} + +.aiowps_feat_table tr.aiowps-main-feature-row td { + background: #F1F1F1; + border-bottom-color: #FAFAFA; +} + +.aiowps-premium-image { + display: none; +} + +@media screen and (min-width: 720px) { + + .aiowps-premium-image { + display: block; + float: left; + padding: 16px 18px; + width: 64px; + height: auto; + } + +} + +@media screen and (min-width: 1220px) { + + .aiowps_feat_table td:nth-child(2), + .aiowps_feat_table td:nth-child(3) { + width: 110px; + } + +} + +.other-plugin-title { + text-decoration: none; +} + +@media screen and (max-width: 782px) { + + table.aiowps_feat_table { + display: block; + } + + table.aiowps_feat_table tr { + display: -ms-flexbox; + display: flex; /* phpcs:ignore Squiz.CSS.DuplicateStyleDefinition.Found -- first definition is for IE */ + -ms-flex-wrap: wrap; + flex-wrap: wrap; + } + + table.aiowps_feat_table td { + display: block; + } + + table.aiowps_feat_table td:first-child { + width: 100%; + border-bottom: 0; + } + + table.aiowps_feat_table td:not(:first-child) { + width: 50%; + box-sizing: border-box; + } + + table.aiowps_feat_table td:first-child:empty { + display: none; + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/css/wp-security-site-lockout-page.css b/wp-content/plugins/all-in-one-wp-security-and-firewall/css/wp-security-site-lockout-page.css new file mode 100755 index 00000000..05c07768 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/css/wp-security-site-lockout-page.css @@ -0,0 +1,20 @@ +body { + background-color: #404040 !important; +} + +.aiowps-site-lockout-box { + margin-right: auto; + margin-left: auto; + max-width: 800px; + margin-top: 100px; + padding: 30px; + border: 2px solid #FFE20A; +} + +.aiowps-site-lockout-msg { + color: #FFE20A; + font-size: 48px; + font-weight: bold; + text-align: center; +} + diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/aios-plugin-icon.svg b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/aios-plugin-icon.svg new file mode 100755 index 00000000..b10e4032 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/aios-plugin-icon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/error.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/error.png new file mode 100755 index 0000000000000000000000000000000000000000..cf4526e85c987a5af8b4373d91f9e462b423b726 GIT binary patch literal 786 zcmV+t1MU2YP)T1%m=@F~Syl2(l;>>7j=niij91d=SMY z6H~~vP+KUJgiNRmL^G+d7z0z&CT+1KGr^^(Cd(P;_At}9km3L3KAd~*`JMl{2PXla zC+X&vp^Eas%aM_3SU_d61OV6p@JfH9`SHHJqm{niZRjY-YyA1}{ z<^jN2PCdz`5(5An2BIG%CN}jPJtFRGO1xdFYLd84r!_gpM+hAohSB-MCnX^~)AVaR zwtmEx2EYaYz4mF{O{3xX%DA|E7T`b7Tv4^v>~ORI0MY@?t@t%t+P7`&ccg9*lL^7j zi736W`0`#eh*uG(s~+i;SJtQqQ6Ca=DH+fLK$*9f3$IX7JgC=Ip4A_spZE|Ui+2Vt z?#i^Ul~a3{B0H-%EdqcN&hTGdpd|Q)hE;bdL_DVu7QkM~Xv#wOJx&!%8~`vXF`JkY zy6GtayAzNpxR#NfSd0!S@{$Hh208&@A^3fT(G#sIb9^*OqC}SR0N@mv*Fv`Js+=S7 zpnHV8?*>FCC8A1VWdLwm;cMT9YQ7Ff>%Zm8d<6hx%zi|;&ss*FbpWDAf~b{Q^XwuS zjIVzar4tSQN(%s-Ve=?1GE)A6Kv-2O+Vy-qU*=(dW9h_2SfNS>h9dMLhtT9X$ytn< zEJ3EveLCiRZInf!%*+6g;WiZjvMC1u(&(o&bq8v#y8$(mx+$)OElnESzsvDy^)m4? zR22ZoLMF!orZ$7}y-t;4JY$@se9U`Y{8Zrf&2R(-&9-HZav4JpFlMzmj!~zG^#tMp zxiNK5+sOG`ado+Ck%~3{{%yHzX2BYinHEuC@C|r+Fg50!(NBv-s>VJ3KlZuSd0y~D Q6aWAK07*qoM6N<$f*#RYU;qFB literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/index.html b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/index.html new file mode 100755 index 00000000..e69de29b diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/info-icon.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/info-icon.png new file mode 100755 index 0000000000000000000000000000000000000000..40d49cdbe486ffa81c1472159253c8a13e2e6910 GIT binary patch literal 797 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 EAHN$8j{pDw literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/black_friday.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/black_friday.png new file mode 100755 index 0000000000000000000000000000000000000000..96beec18067862030cb015fe22d8a6791917e604 GIT binary patch literal 4678 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 T7^EKk?;E6{s-se?WET2A_J+|W literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/new_year.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/new_year.png new file mode 100755 index 0000000000000000000000000000000000000000..88c1492168cd9d0f18207efc91869bc041d23213 GIT binary patch literal 5480 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 literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/sale_blackfriday.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/sale_blackfriday.png new file mode 100755 index 0000000000000000000000000000000000000000..36915c17d8fed808cc8086cd0c7c783269e92dc6 GIT binary patch literal 53288 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\q05pso8iXn&bFySoU|E7?!O&1q;#5|vB^1If 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 X?V4A)$_86UNOb9H8fui@Mq~a1xB&Lp literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/sale_collection.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/sale_collection.png new file mode 100755 index 0000000000000000000000000000000000000000..d89d0f88b3c08fa8d5fdf3a066660b57beeb75a8 GIT binary patch literal 57920 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 literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/sale_spring.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/sale_spring.png new file mode 100755 index 0000000000000000000000000000000000000000..aadb99c9188f1e785d9b275faf64bad9ddf7f2ae GIT binary patch literal 54751 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

hN7N-3+-+n zQ^W3CJKu^VtbVZO&({ZE7O$V<@6XTg6Y~9?4_L3;At9viIu@4Y|BmXK7MFi*`hJ{U zdV#l5xa1AJ^_Tp@4@0`XfrqDw92AO@Gh{=GA1{k8(psxKthW4U2sNE={|YHQJ$>H# zc%R$Id_+)O*x5GlD0|NN;3fTPbK;PCje1^)KhpYyHLkxy-vu##%Q1CS)?R(Ca_P@u6G13o%*1L%^ zOr~jpm)VKF1<+~uwH(p#u@il!c|ul3=$^#$%UO)CcZ$LER5shj9ZdJLuP^`WgH|-8 z`1d~CKVF!EXo^(y*7fn|i6+!o(5-b8D_CJ)yOPs?@%M(bMh(k(CsSEupQZa_!N~Pv zIT;(ZJtLKC2tZIJ2TN{wv9ZA8s0skO2s)SVS)pCNTuKSO@4j7ryrY$Pc$~F-x(U8# zQ&R(pwdbDJ79<-3fa!c(&P$czQNfC{4wBq|G8M58WJ@{|ww-tnS96$SD%XJY%VozQ zq|BXf|6W7gh55g5QTKG<5C%;{3Nx%yXqlv_Nw7TG!%%vee3@Jy#SLNOT5A=3-i-|??O_zxHB&bu{QUV(8`I*_9FY4wUxU+ z&J;q>IPrEDAjg46c;ifbn;BY#fVnyKj`P!+W$(SXw-ugUd;6MBmz``+S6AoN+7yq` zUG|O$k(xR4qh-Txw{y_3C_zLix2&vcc{y+J6f!E2dAb0f#d?$D!(ZL2$7Y;gKTrDG zf5HA48;?+uSEr$YXTkgo0R8?Y>EKY`s5dwql92ibNYBJUO<4=qA6jaI;J3_XP^y0Q z%&{ubknl5kJP=0H=W7-RLmXJe$S59+JwAz2-*|d20yQD_32?P)rZ0z6qL5L%oTmCu z+w7sE`$b)AgGVbJ{1-vRbt5|`yZXT`SjgdQ%na1>O7^=okj2^C=7lDQ^JyGk;#}+H zS8&5|g=0r%w~3jtY^#`#xdGoN8Un3QIf-6wqKk*Wm7S;A?v*-MB~FbQd~1`(^ShV{ zjUv!|tS%YtJHMOFLR?cK_&kon<*C#n7k6L56{0&+%?5l8m5i5F#EXh0gme8{`-jDX z{K1ez#o*%Fw^xQAAl~kmmG+FTrpnq8r~M!O5PtRF28`0xectlkYj`)%RW!Ki62Ps6 zdAhw6)c3vYKr-WN>ek_)5PG_8#%*SQuzNYZb_AV6qGLJ#+~Y+C$6F_AfsBxe>DXei zU?m#_FD!;9s}H?Ftwr;dI6K_!u8Zq84b>od2+A%Q~J3FHjvCdyE4KI!z7`1E%Oi&F;#y_VZKkAkeNMJuX(S+A$R(~H8cB3@c!UCefNMC(o|S%slhl& zVfj?=6qPI^J9l@_)2K6K>0GfmW9^bA&udcd0-lN>&T6`I+Dz$E*Yho#9uHvk?fS|# zU;Erv8S{_pv*6g?ITCJqeFO67C;>uQB9@I=2@}uv0N~;RJ1d(|oQg7Op>%>tg%U;QMUdp>!qQX zW(?k?B~wo-r1j7#!%T${0#vu$u5K2$VH~=*{hqEi=$DhLJ>PCeO^86R1OH2%LX9xP zD{K7vcY?v9sJvcg?99gc=$b#Pac{lG6Bn~Tl1r>5b8~mpd$}}0dv0E?p6gZaF@l;#4Xr{vD>s8Lh#&7Uw+Jf3G0ip| z&AA=?F9Tu!RvQvXo@K9_Nj~v4MWjKj=6h_6mvaB)

(<( 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 e|NC}5v|hC?E@OSmPsp)pmhN&i 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�imWXwGkQmZr3eQQc{M6prDQ2PpymI?MT= z(i5~+yKUEZ?aj^MW6gy*d1a}Sa~h?lEw7S5(*VIs~N9szEyhptymYuLU3 zbwx&07@t)+=Fo-DBe;X&SxTbzRq7UG24w$Cl8ud(s!s zF$&mLMtGcWO)Ucv^a6C+LEWJfdxlFqR4rcD^qBPNY?MvkGDuVbvz%Jss9D6RqCLaW zDwzl7K~$kt?p8#bpn|HMKV{rs50>Ou!V=xFtS*&RzO*7L01g+p2|~OcI1`d5C-BJ_ z=3EHzNf5nArYce%j#o|?>I)qKNBvq>V|U`-t+GY?o5A^#k33PO4j1?vsoYN97w;8N ze($AamX!yIeMZcoNsHq)ABJ>A8#d2g&ygy2V$O<@C`BF*6qAigkB$+OJtwduuA3K0 za{iW(9O8_IQ*zF#ypqP{j~2h)g+RS(w6Ob|VSh8sCobK8T(S~{fG^hDlQ$rF z-8?}FyNOnK1?!1G1m9bwP z&>=02_Nc{wu$#SUyeUhBDUJl`T6J;JYE7zxp#y;tmG@5ADGVq@)|0o`l6dfnoXj7T zoR@sC^Zv}Ety40GHm1es1Iby8em$40F&wMBrgFlN7AInYJn+}LmC2_7f;qSwNc@WD zL=jKat5ZKCzcha>my_d27KbT>B-i$Ix9x^I?_Y^5C(K3rxWcHHek!3B5gd~iB$*IB znsPQqJ$SIWxjDReaR`J2iq>%OLMKm4csc%d_i7^M@EgGeE(Dh%+nP4+{06BoQ(o>) zqj#IO-?WkiUyt*xKx)N)6_b%Xm%OiqvT&hFDNV_GsYKbUQsYbqvmKnrQcI4@B0{}$ zSpml?Uvc3vhQ!L`;6ubB#PZ;?7@xu_Sb>C+s60Km>9#A7ww3js5x>bw$T$?)hloZ5lNH264~KI4zTNE_txIkc-bAIiZw|RiN>l`kcdl-i zbX{(faK3@~`vmqPzfP+I05|*5ogQG(#w!cpSY0ZstU|_TiT@x$9wi}$6jvd5HWB?S zBDXJkPb!#(SjMH=kvfWj3nd0yv%(w&4&=ns>DXHD_d_Mky~{0U=aczr5pONg7Nw0= zG8nD(w18!|u{NiMv{9^s5s+7$DgESdvD?*?u7?9iLp>lB&1T*<=8ZS{i;FIx4bdYY zmVne$k9KSLgtE@sqWGw4} zqN3D!TAs-g%7hz3_+p9bAhvIbQZ4}_#XgJEE?C6hCXQtJN! X(nZQB&avUY00000NkvXXu0mjf0r$jq literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/spring.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/spring.png new file mode 100755 index 0000000000000000000000000000000000000000..59f50d7c1ced9e6c6d2b0a4c9d34bfdf89bc5732 GIT binary patch literal 5459 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 JPDHLkV1jzDR@wjn literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/summer.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/notices/summer.png new file mode 100755 index 0000000000000000000000000000000000000000..b66dfb781d7de5469064e68a8fb0ff7a61e0a774 GIT binary patch literal 2437 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 WwS3GB9zXkR0B{5I+b{Io;{O7G-kWIv literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-icon.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-icon.png new file mode 100755 index 0000000000000000000000000000000000000000..932f12996bd40e0b7d3613222444f8ecefca9bf9 GIT binary patch literal 1704 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m=!WZB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%s|1+P|wiV z#N6CmN5ROz&_Lh7NZ-&%*U;R`*vQJjKmiJrfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8EkR}&8R-I5=oVMzl_XZ^<`pZ$OmImpPAEg{v+u2}(t{7puX=A(aKG z`a!A1`K3k4z=%sz23b{L$o& z6x?nx!>Lyv=oo!av?4__ObD2EKuma|1#;lYJ~a=R){B6NT8M384KT0BdAc};RNShW zT1RKGhg!8pPl!w+>3JTcro*y3&%`L&B-U9zq2mbchu&Da2u!4w8tklyp=Y* zSNXwjef*Yx@eHPW1w>`{zqxXA_SK`-U6)x7HnM##UE_C;Z}MZipybUHRi1sykLTr! z$YC~n{Py(m7-9S0%NR=1u65bA&MtqW9kD&L(yy%TT25_m*lp7vhukK7+st$B#_@zu z`vqc;H=3kbhrR6Hkd=DxVE_B-o+8c(5j#@TI}a8p-8VkDVBK>zy9#N=%Nzkg6E|e6 zS~#ItAks2MPu_~@`-C+or~dh0=$Kbj=|zGKoCwG3P2bLL>O;e18VtDG7gN9<6NEIJ=kSzeMjx`MN1j<6YJ-xal!S;qTRb6 zuQf3jDr#8o{4Bk;R^H|AACV~WnXKKvdG~A)Zky%Yap}k*_hSpWv=+L^D7BQBn98l^ z+&lNaV$q!a%hxXbw)3b})0dyp3XcyjwK?>lU79aVfNRCW z6&D__s^_V9OzLkU3$xOm9`1{qSR-avahb21lUGn9ZI)!F8T!!Gx?KKce$6YD{@eDG zUT>YcWZ6xhZK6|WEqPtJxo%nJtl2BPZ|~o>AY-+jW^SB!aq8vY_olP0wEL$2U^)Xc Y!|RUH3?BY<;h?(1)78&qol`;+0Kw6b-~a#s literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-icon2.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-icon2.png new file mode 100755 index 0000000000000000000000000000000000000000..f3bec023297482bd0f47193d8b8f227eeda9968c GIT binary patch literal 1760 zcmaJ?do)ye93Lqrg-|M4U88n$cFfB#xf#!EP>si!%w$&?Gk2Jnxnt%s!}dU_LvfaE zTPBMowI#(m+hQv^QZ21ElA_eIwmefFMate0+CSF*&bjyZIG@kw`}lqCxv2qu-i8Ji z1~?qf(ANjzVDk#?gV)2}>qn*q*t8b);-f)`7*z=rFwR|sgu{TZR1g7kV1Xz;<~P_G zhtmZlTt3QYZwG~llqAq%NNTAZW8-knu4=hJ7zLw1I2<97F$phztswvs5tG1kU{ly~ zPdHNIlc0cu68yNrgeakth~Vl1IIBTSKnkM*KrM}yDM2-pFry1%YwadfVLK)v5=G@8nXFQ&NGf|0qKF_ ztmMYaVKN6+BC!e~c5z}GZ74bDselD2qTnJ(^jsGMA`ui(Mj~>+GspqpNn|2KrJO;t z*`TjXi3(&w*cW0FFg{5l5rHf^ncUMa@^LryTufhce$yT`rSBj#on)-Z9uEJq;Kx+W8nabi9$dObo4H*V=euC@ zyFMoE&DaP9TV9$M1$I|W3^nd;%uyN}a%efrEz~!lskJXW7a~XG+tSgMOVo zsNpBkU?gD8`5^!=&4>#g;q{_m=C0i#_gg#T_cy36#xtGg0GRbP6l+ zt8)4Sic6DKe~g?iZsj+g;@CFzk3)ko>tr=o4T&})hooe;sS5U4PFj0&2!GN}Jv?sx z+}A?s+~AY;EQm|XIaVDybmyUgDdR|4%7#?aq^zt+TelXv(X;i31Ci@LMR$>`J586I z)@`Y?J(12KHs0tAdGhdh_{KHVgMGPsMr8vjyUy!>drIyTgJ;LHBlov0uV^{8J^oYC zqO~j*Yk+vOJ{vt+Bz!W!Jw9F<8jv+MTCy~+On!x`^GXT!oCFb9S{zhmc_MfC2jV?DU+I6!)o{`WO;F8+HQN0ev3(x5&C zpRwd^;mhX%A=}Pe9JTDaTe-LKMzzL2RnTCfdYUir! zd1veUM>PA_or(f2UtJ{f%MnldpOxdNFx~8qIkBEU!+FSq+mp4nhYDt46qJcR}hQ?Wq`A_^_gO29+JNLfc z=L?yh+jnxj)V9f1uTgQU@pfJ3#;?lKa{GB;(?k7%(x(w`Cl6$*@_99}9la4uX1Vch zm*M-@7*mh8JTBK5Iz(*JslPnOuDt!wNj(~=lFX0K^Hv2lK%m>Rl4E; literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/aios-icon.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/aios-icon.png new file mode 100755 index 0000000000000000000000000000000000000000..dd698a647a4a52a59bd3a8d2b87bdb929b66ee3d GIT binary patch literal 2605 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 literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/aios-premium.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/aios-premium.png new file mode 100755 index 0000000000000000000000000000000000000000..1dcc19c4d1311a0ac38d70cbeb325e9016e85c18 GIT binary patch literal 16535 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 b4Eb59B-Y6#R`d18aRddhDyT}@H2D7k`gE+h literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/aios_logo_wide.svg b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/aios_logo_wide.svg new file mode 100755 index 00000000..124f34c4 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/aios_logo_wide.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/easy-updates-manager-logo.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/easy-updates-manager-logo.png new file mode 100755 index 0000000000000000000000000000000000000000..198079d01a9b8af1c55b965703f8a68fc5167a2d GIT binary patch literal 43451 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

g*%JR|wif5ars#tG-H%3OqnP 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 Q0s%jzcj|A;-xvq}2k<~*A^-pY literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/easy-updates-manager-logo.svg b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/easy-updates-manager-logo.svg new file mode 100755 index 00000000..a54510aa --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/easy-updates-manager-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/icon-aios-rgb.svg b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/icon-aios-rgb.svg new file mode 100755 index 00000000..ba055857 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/icon-aios-rgb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/internal-link-juicer-logo-sm.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/internal-link-juicer-logo-sm.png new file mode 100755 index 0000000000000000000000000000000000000000..255cce64fd24f388125f1c7744c05cb647325bbd GIT binary patch literal 6665 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 Tk9iDw00000NkvXXu0mjf>1mRl literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/internal-link-juicer-logo-sm.svg b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/internal-link-juicer-logo-sm.svg new file mode 100755 index 00000000..bde039fc --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/internal-link-juicer-logo-sm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/updraft-central.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/updraft-central.png new file mode 100755 index 0000000000000000000000000000000000000000..6925087ca88609dd09d8621183b0de7818ef1dcb GIT binary patch literal 5139 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 K%+oWMuKyPyPDe%n literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/updraft_logo.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/updraft_logo.png new file mode 100755 index 0000000000000000000000000000000000000000..da85de5c4a58c0f77064dd06df90dfd1540367f0 GIT binary patch literal 2707 zcmZ9Oc{CL49>-<8nlQ2(JA*8Z!6bXBG4^GwA;S<+SGI{v)~v(CNWAtXYnCDjV;TFJ zEkcPH%Vdd+CE3cW`<{F6d+s^U^Zk5(-|zXI=ievJ%v2A=#Lq-WM+Y*{M_Qb6=Jy2x zP8AxZRdWh&Gh-{AQ%<4iKKsGi=>r-DJ6ew`T%##B|*|4IIfU!(BH&6JNo$S9jeX!Mc>wxBlZLB$y ze_AO-54qJ$-BZr`Cnh`ZICT4FHxm{~W1rf>+R|M$b* zpBPf@2>MlQ@1Zspgxu-rhDQ@+1S6NAGPpz!n0+1<+Y-iqN%G-1C_1M0UB9!YU2Twa zR2UM|YW!&jr+;HhbV56C@wtp6qZS7H@^kUQ9pVsNqv`+~<~K8E>QGUd{3Ti5Jk2H2@&Pcc;?_3JDLPp&z^ zIE1FCqhha^=fXJ~?}I8T6TpqhJ7?&hswTKdH$LjgT9|pZJI;82G;0Cvd<+ct5y4BK z*ce58r9HtaP|Iv>WW6YC#WLIe`n_c()8c(o2D4=t5$;G^6`wgdvV`LYwg4$X%G8OI z<139dsvP2UXs&sI8}&4`_MUmVxfE6BUwHv?b9pXvz9|X(EoJ=Kp-yivfb!a)gzgQl&|D608Aix1Q-qV&sm1l;Y@S?Hz80hnFtcSVb% zcyaTN#J7TTiVx4AnBoFv+_U*X$NHG0pFWCJZI376C%#3)ts-DkdD)cNTeLPL3%S?a zO+*O45S0TW1@J6s5p@#JPk>uE0jeLE5Sza8{$~;e)l3$*c?2ugcICU`#5I-6WnhVI z)k$n2y-9)~O}ETd;mk6Csy}7r3egH6Qp4BMk7HrYh&f0cfB-}))>-Eqlt`C=C%#ZZ zUh^PiBaszf!A|b|-d&@jA3M(HQ=Bpwlzngh{9x&dC$)t^?+s#ZK+!H!D)+!rC}2Xl zXi3dWDzC9@%v}AaB02|J)RJZ-@NId!@GFk#-K{Qq+n zLm2PZt8gd{OVST`uQElS+94jG z)A0xgBDQI_6y9x?rp?8ls_GV-55r5i*j~e&>vSNF-{JY$OF%fnYK%&nzJO`i*z!jQ zUh=<96Ng*HI&7W#F`}NaH#eFrIPu4zKR4GNR$4c`!W_JZErlthnJChzW1NGv?)mb) z>goM`4l4s>vt&YO(PH)pl96qW#yW2;2S4M7r*{)YYvIqp^Sp;Tn zi}_jbWWXbmIY>P0=2J5(vtyYxw@XqL+y?QpXVo8ct zUC*dULjvR96nLo+EB93kT!yUTfn9Buwq`|xSedGR3R5FvRSg6qrR1HVyw{hp{BfA? zDq(jj+$OIOuXZ+zc5;32c>2U#B7CdRnlYP}S5*J9<}yblBpBFQ(X|xPWM=Lq`+BP{ zXfM?x{5-|Rx&iV-`B`D~gx4%3b1OeEB=@S?13J`-Sh;7kr!Zpc#J-rswZ;5ure6f@ z*b!J9K)PPybG&vzn-seuOOf#G*)Xfl)!;l#Pd{1hB?33~lS*?Y-N5};tjb`ET{cyF zrySk;@|uVtR@Q?v=T`&opQ%SVo*5aIk=wsY6}rE>27S@{9JJ!4wf?jZh&T@kiT`}) z`7arHdT1tXRAfH4NL_aHcvjs2?b~eiJ%U{{U$2nyW6xbgp6;a4o)%2^Hk>1(g#%$$ zIRUoz!F0qkBG1_C#E>KpjJia;E!^!6O;SA$T#5xNi0Q$}xsg!Co%~`x^JVlEhr^Yc z&WEpt<%XGe?72NBmC^jQG2Qos!fx2x-UE+TsWIA38id`|xFx`Tm?8UaQaf}_TyrRC zbr5(2rZ0UW=6VhVzuQio{p$3X!Z+4oDZ#||&{>Qj2!W7K;%3dIL?U$yrGSMu`b5?3 zft5u5r8jJ`8h699nHhM+^y0Z0-a{^Kib16=Exl7bR=zT$3N32v1M(@EvJuJbSm`_u z;DrV;dC*Y`N@yEN0{yzWk9~FgEU{iLOA@icp>hYov&zv?{@6+sKjsy)vEV2srk5@d zbwd_mYFKnMq~aYLe@(dd97Di(lx9J}3+G52I4SiWM#ym#DkE8K-=YO?u4rhxloH+6 z1iw68ixNoIb**y%6^-F|le|6{lO@PXNL-pBMQ!~a?JCDXzM(K-B(xO574@U+k^+5k z2hLVVaNyzxug5mJ*_I{9?A1cbGnfTHW*~AE=KAiH%xEg)14`d>4ez@gJYfT ze8KX>9h1zj))as%Jt|E)Jkj9&dd)FjzRW*39yhdg**c&*&4a+<*lzulRx9mkgiCte znO0zYfd-H3uqh~r;UzFbg4sK?S>*rRRhu_@(lAcDL`VVpGEG3Irk z!=GQ5*Ch4i7_KIWepg9E)w>@whejLwMzog4`w>t{WxqB>cvb!M!GguxoA^Du;MG^{ z&yccOlQf=npA~&JMg-{XK@PF8s_1Q;0v)7~P_MTABP+j85%|8fJE^)A+i#NmF|e7e zKIuI!8peTI*2f5RSg**A&o9z0{Orr?x<8t+K0h1HKyAD@?Cqy?melwE z1dspfGKm%oq?m0?pWP22kzT+;Dqes2gnL~n(e+){*k*TmwNpUrPMF)`ypjlHYE@GQ zd3X*|qMP99N3yzooJ(GW7+ltSnSxz!5zv#l9n@s(t%zf3xAXWa|HA)-M*g(%py{($ f{q#R@vclQp@G|l3pPzq!_2>+AOp%ocr-;7*7>gc? literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/updraftcentral-logo.svg b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/updraftcentral-logo.svg new file mode 100755 index 00000000..09039972 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/updraftcentral-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/updraftplus-icon.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/updraftplus-icon.png new file mode 100755 index 0000000000000000000000000000000000000000..068071df5cf5f832f7148104f7713f9079fd72b4 GIT binary patch literal 5228 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 Do~|;{ literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/updraftplus_logo.svg b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/updraftplus_logo.svg new file mode 100755 index 00000000..d7f9e00a --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/updraftplus_logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/wp-optimize-icon.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/wp-optimize-icon.png new file mode 100755 index 0000000000000000000000000000000000000000..d3bbb85c7de276e2bc36ec278ac6d745c1a392e6 GIT binary patch literal 6094 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 UL1(r0l>h($07*qoM6N<$f}CYuYybcN literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/wp-optimize.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/wp-optimize.png new file mode 100755 index 0000000000000000000000000000000000000000..5f2ee9814f05c85628b6e4268f9f371727ab8019 GIT binary patch literal 7693 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 literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/wp-optimize.svg b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/wp-optimize.svg new file mode 100755 index 00000000..4f23a1a1 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/wp-optimize.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/wp-overnight-sm.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/wp-overnight-sm.png new file mode 100755 index 0000000000000000000000000000000000000000..55151984f7e71577b2105b92199c7c17d8688682 GIT binary patch literal 8494 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�GT`!)LBWD|AbH+qMSi8qawf#A`m|DTGH|jE} z|I(eL=Z%ggbdq>KC@T0i8Sk4BHFkHqN)Yxj&3L4N6`@@{Jm&3fp2)4F9x`;R2xkp8 zcIA1FSBv{}=`mv!^&XeUemtF{1lo>jaPzym;IH0Wpqk5?8E}5Bj@BWFd}0mO zV(_@0ZRWRDKSRI7wFLVcz)bEQt__|VoRt-d{5gv}ZQH7L7n)cyb!v`fMK>L?&4fsH zlEwrCW8%H!_3Jj866-G4zJ`yLC4rK$t_jBK`tbI-Ci2M0U0mW|pU}|>an-jG-#>)| zvi-O*p6)e5mX1~_>yLog&0lX=(eKkxI(2SYY#l|ry%@xp8CPo#D;mH^6`}JIRPGW# zb;?LmRnRn_R`CvsuLdV1ZU54n7FaG{vTA#0$C5CPlHU^ z&r26RZYP$OK3MJ}y{?<#}EoWuwg--b&^30!|>^H_pv_F;$q{c+xA5NL3`IA5Z!JA__-OD;w^en>P zSs+&z$21W4vkdF$#Q}6Ndp%XQ$O988>GPL|#o(dTF(r(j z@DfU`+@50CbAb#@AEX5|1E0WDgCP*75&IeP=*k9V`%@=bcaN1#;tH;ceeM9M-t@iN zLTO@Jr9+}{^?<||#C|K6ck7>tq!n68WD+VpiOz$1jG5ewCdMQGM4~Q@vSVi;Vin$} zN-DB9o3$5j>Yb<`ck1YMbq{6mhHvGBW_>c)w&(OZW2j`60mfr71=tD7)c|Dt)ZjQV zwmp$y(YDETAECW*il)gC;Xe$)jC+5AI_(AV50PORSz49u+BCF?%BxI`87~F>ls9O9 zHmK*+C65CGmDdk}#=#DGQ~Xovbmz95ZrYob{@f4=4V6>8Sx{Y3+8Zws|4io*eh5Z7 zcSJ+q0ZUDdN6EOfpJ)0gu*ekJ6S4q);~H8#2<1p}Vo zJX$hi`f${|eWtMGT_}XrZh}OUWBG>9$roz(@W0s*108*=n_J2-PaLS$h2Enp-aHd+ zv$+@RZjJhn+|srN(lFay(^x!tT*dhP!!C>d@;A8uW$`jBgyK`!lRte4!(=v`yHPf`MsQrmB9t zXB`RyW3r_KC(E*5ymN`7L5oQ-W#EZ)8l~KnSzOyaLQ7z0MDt+xS?)d9e*4tI>SfND z2Gz%>ks+X@)}PgEuXqb5hJ*mubqbA|(%e^%188Z@-)BbVyvn#_6AL`_s~vXPILmI4 zxzdsljZ>m$1;+JN=_;N3wEa4~J9v1XTUsVvQxFT68Bfl32S<^y)QfqjxKC7A`0{Z= z;f%prY{6!4dd93w-N?cQrd?}}&Fjp4UDY0JxoKM;e*3Ol?CxPmQVG^R4Nu+VG`KZ^ zKWZjKVw326T@NOt_o*}3rlUD-!n+3N(a_YC=BD&7R_;mkdxyIA`9ha zH-|;Y%dtVn9;}GzqJK0ID-F52=F2BU3n@vj`eyz!mt8fTd9HkB4()ASb7agTJ-9Nji6CdcW?6dbzH=>DwUU8xp7bA2fqdIe2`^|0G|cRwll!%A0;{F+?6e=Y;(KRQNPH zgKYocayG+L=d*{g>Ja(dBa`=eQ7d9)UjHMf1<%k#i~eU3W$c8589dbfW97RH2WB6F z11p<)?RQ-MU!EX<{fkUzXuf%WsO00Z=BgNk=a3N%Zoz#yT*q6J-7y% zGKJ$P3A^oYN}F2$btqpGU@ccdh=3Ct94BF2`EjsmXbHcI(TlZo*S(kCO5za{cotUbNP2$`!ejW@c(3NV>94Voh>s%9!7_Sf9u;sBej8{ZGgDLb?(*S zT(XQB90r43$yI7CCsROEY>VH~{x614=abGe<(AWgJpbNiuaP~pFCd8dVV(rnkM6l- XuakWahZG(@KmgQ~v=uAlt-}5fkACKh literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/wpgetapi-sm.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/plugin-logos/wpgetapi-sm.png new file mode 100755 index 0000000000000000000000000000000000000000..75bbee3c25133476f8b6ed88feaa7031c5cac85f GIT binary patch literal 13620 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 literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/images/shield-security-icon-36.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/images/shield-security-icon-36.png new file mode 100755 index 0000000000000000000000000000000000000000..1b81dc21cd0be89468625fc110047f06c1a6982c GIT binary patch literal 5196 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'); + if (title) $m.append('

'+title+'

'); + if (message) $m.append('

'+message+'

'); + if (timeout === undefined) timeout = 3000; + + // Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications + var callBlock = function(opts) { + opts = opts || {}; + + $.blockUI({ + message: $m, + fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700, + fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000, + timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout, + centerY: false, + showOverlay: false, + onUnblock: onClose, + css: $.blockUI.defaults.growlCSS + }); + }; + + callBlock(); + var nonmousedOpacity = $m.css('opacity'); + $m.mouseover(function() { + callBlock({ + fadeIn: 0, + timeout: 30000 + }); + + var displayBlock = $('.blockMsg'); + displayBlock.stop(); // cancel fadeout if it has started + displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency + }).mouseout(function() { + $('.blockMsg').fadeOut(1000); + }); + // End konapun additions + }; + + // plugin method for blocking element content + $.fn.block = function(opts) { + if ( this[0] === window ) { + $.blockUI( opts ); + return this; + } + var fullOpts = $.extend({}, $.blockUI.defaults, opts || {}); + this.each(function() { + var $el = $(this); + if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked')) + return; + $el.unblock({ fadeOut: 0 }); + }); + + return this.each(function() { + if ($.css(this,'position') == 'static') { + this.style.position = 'relative'; + $(this).data('blockUI.static', true); + } + this.style.zoom = 1; // force 'hasLayout' in ie + install(this, opts); + }); + }; + + // plugin method for unblocking element content + $.fn.unblock = function(opts) { + if ( this[0] === window ) { + $.unblockUI( opts ); + return this; + } + return this.each(function() { + remove(this, opts); + }); + }; + + $.blockUI.version = 2.70; // 2nd generation blocking at no extra cost! + + // override these in your code to change the default behavior and style + $.blockUI.defaults = { + // message displayed when blocking (use null for no message) + message: '

Please wait...

', + + title: null, // title string; only used when theme == true + draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded) + + theme: false, // set to true to use with jQuery UI themes + + // styles for the message when blocking; if you wish to disable + // these and use an external stylesheet then do this in your code: + // $.blockUI.defaults.css = {}; + css: { + padding: 0, + margin: 0, + width: '30%', + top: '40%', + left: '35%', + textAlign: 'center', + color: '#000', + border: '3px solid #aaa', + backgroundColor:'#fff', + cursor: 'wait' + }, + + // minimal style set used when themes are used + themedCSS: { + width: '30%', + top: '40%', + left: '35%' + }, + + // styles for the overlay + overlayCSS: { + backgroundColor: '#000', + opacity: 0.6, + cursor: 'wait' + }, + + // style to replace wait cursor before unblocking to correct issue + // of lingering wait cursor + cursorReset: 'default', + + // styles applied when using $.growlUI + growlCSS: { + width: '350px', + top: '10px', + left: '', + right: '10px', + border: 'none', + padding: '5px', + opacity: 0.6, + cursor: 'default', + color: '#fff', + backgroundColor: '#000', + '-webkit-border-radius':'10px', + '-moz-border-radius': '10px', + 'border-radius': '10px' + }, + + // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w + // (hat tip to Jorge H. N. de Vasconcelos) + /*jshint scripturl:true */ + iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank', + + // force usage of iframe in non-IE browsers (handy for blocking applets) + forceIframe: false, + + // z-index for the blocking overlay + baseZ: 1000, + + // set these to true to have the message automatically centered + centerX: true, // <-- only effects element blocking (page block controlled via css above) + centerY: true, + + // allow body element to be stetched in ie6; this makes blocking look better + // on "short" pages. disable if you wish to prevent changes to the body height + allowBodyStretch: true, + + // enable if you want key and mouse events to be disabled for content that is blocked + bindEvents: true, + + // be default blockUI will supress tab navigation from leaving blocking content + // (if bindEvents is true) + constrainTabKey: true, + + // fadeIn time in millis; set to 0 to disable fadeIn on block + fadeIn: 200, + + // fadeOut time in millis; set to 0 to disable fadeOut on unblock + fadeOut: 400, + + // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock + timeout: 0, + + // disable if you don't want to show the overlay + showOverlay: true, + + // if true, focus will be placed in the first available input field when + // page blocking + focusInput: true, + + // elements that can receive focus + focusableElements: ':input:enabled:visible', + + // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity) + // no longer needed in 2012 + // applyPlatformOpacityRules: true, + + // callback method invoked when fadeIn has completed and blocking message is visible + onBlock: null, + + // callback method invoked when unblocking has completed; the callback is + // passed the element that has been unblocked (which is the window object for page + // blocks) and the options that were passed to the unblock call: + // onUnblock(element, options) + onUnblock: null, + + // callback method invoked when the overlay area is clicked. + // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used. + onOverlayClick: null, + + // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493 + quirksmodeOffsetHack: 4, + + // class name of the message block + blockMsgClass: 'blockMsg', + + // if it is already blocked, then ignore it (don't unblock and reblock) + ignoreIfBlocked: false + }; + + // private data and functions follow... + + var pageBlock = null; + var pageBlockEls = []; + + function install(el, opts) { + var css, themedCSS; + var full = (el == window); + var msg = (opts && opts.message !== undefined ? opts.message : undefined); + opts = $.extend({}, $.blockUI.defaults, opts || {}); + + if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked')) + return; + + opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {}); + css = $.extend({}, $.blockUI.defaults.css, opts.css || {}); + if (opts.onOverlayClick) + opts.overlayCSS.cursor = 'pointer'; + + themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {}); + msg = msg === undefined ? opts.message : msg; + + // remove the current block (if there is one) + if (full && pageBlock) + remove(window, {fadeOut:0}); + + // if an existing element is being used as the blocking content then we capture + // its current place in the DOM (and current display style) so we can restore + // it when we unblock + if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) { + var node = msg.jquery ? msg[0] : msg; + var data = {}; + $(el).data('blockUI.history', data); + data.el = node; + data.parent = node.parentNode; + data.display = node.style.display; + data.position = node.style.position; + if (data.parent) + data.parent.removeChild(node); + } + + $(el).data('blockUI.onUnblock', opts.onUnblock); + var z = opts.baseZ; + + // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform; + // layer1 is the iframe layer which is used to supress bleed through of underlying content + // layer2 is the overlay layer which has opacity and a wait cursor (by default) + // layer3 is the message content that is displayed while blocking + var lyr1, lyr2, lyr3, s; + if (msie || opts.forceIframe) + lyr1 = $(''); + else + lyr1 = $(''); + + if (opts.theme) + lyr2 = $(''); + else + lyr2 = $(''); + + if (opts.theme && full) { + s = ''; + } + else if (opts.theme) { + s = ''; + } + else if (full) { + s = ''; + } + else { + s = ''; + } + lyr3 = $(s); + + // if we have a message, style it + if (msg) { + if (opts.theme) { + lyr3.css(themedCSS); + lyr3.addClass('ui-widget-content'); + } + else + lyr3.css(css); + } + + // style the overlay + if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/) + lyr2.css(opts.overlayCSS); + lyr2.css('position', full ? 'fixed' : 'absolute'); + + // make iframe layer transparent in IE + if (msie || opts.forceIframe) + lyr1.css('opacity',0.0); + + //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el); + var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el); + $.each(layers, function() { + this.appendTo($par); + }); + + if (opts.theme && opts.draggable && $.fn.draggable) { + lyr3.draggable({ + handle: '.ui-dialog-titlebar', + cancel: 'li' + }); + } + + // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling) + var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0); + if (ie6 || expr) { + // give body 100% height + if (full && opts.allowBodyStretch && $.support.boxModel) + $('html,body').css('height','100%'); + + // fix ie6 issue when blocked element has a border width + if ((ie6 || !$.support.boxModel) && !full) { + var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth'); + var fixT = t ? '(0 - '+t+')' : 0; + var fixL = l ? '(0 - '+l+')' : 0; + } + + // simulate fixed position + $.each(layers, function(i,o) { + var s = o[0].style; + s.position = 'absolute'; + if (i < 2) { + if (full) + s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"'); + else + s.setExpression('height','this.parentNode.offsetHeight + "px"'); + if (full) + s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"'); + else + s.setExpression('width','this.parentNode.offsetWidth + "px"'); + if (fixL) s.setExpression('left', fixL); + if (fixT) s.setExpression('top', fixT); + } + else if (opts.centerY) { + if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"'); + s.marginTop = 0; + } + else if (!opts.centerY && full) { + var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0; + var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"'; + s.setExpression('top',expression); + } + }); + } + + // show the message + if (msg) { + if (opts.theme) + lyr3.find('.ui-widget-content').append(msg); + else + lyr3.append(msg); + if (msg.jquery || msg.nodeType) + $(msg).show(); + } + + if ((msie || opts.forceIframe) && opts.showOverlay) + lyr1.show(); // opacity is zero + if (opts.fadeIn) { + var cb = opts.onBlock ? opts.onBlock : noOp; + var cb1 = (opts.showOverlay && !msg) ? cb : noOp; + var cb2 = msg ? cb : noOp; + if (opts.showOverlay) + lyr2._fadeIn(opts.fadeIn, cb1); + if (msg) + lyr3._fadeIn(opts.fadeIn, cb2); + } + else { + if (opts.showOverlay) + lyr2.show(); + if (msg) + lyr3.show(); + if (opts.onBlock) + opts.onBlock.bind(lyr3)(); + } + + // bind key and mouse events + bind(1, el, opts); + + if (full) { + pageBlock = lyr3[0]; + pageBlockEls = $(opts.focusableElements,pageBlock); + if (opts.focusInput) + setTimeout(focus, 20); + } + else + center(lyr3[0], opts.centerX, opts.centerY); + + if (opts.timeout) { + // auto-unblock + var to = setTimeout(function() { + if (full) + $.unblockUI(opts); + else + $(el).unblock(opts); + }, opts.timeout); + $(el).data('blockUI.timeout', to); + } + } + + // remove the block + function remove(el, opts) { + var count; + var full = (el == window); + var $el = $(el); + var data = $el.data('blockUI.history'); + var to = $el.data('blockUI.timeout'); + if (to) { + clearTimeout(to); + $el.removeData('blockUI.timeout'); + } + opts = $.extend({}, $.blockUI.defaults, opts || {}); + bind(0, el, opts); // unbind events + + if (opts.onUnblock === null) { + opts.onUnblock = $el.data('blockUI.onUnblock'); + $el.removeData('blockUI.onUnblock'); + } + + var els; + if (full) // crazy selector to handle odd field errors in ie6/7 + els = $('body').children().filter('.blockUI').add('body > .blockUI'); + else + els = $el.find('>.blockUI'); + + // fix cursor issue + if ( opts.cursorReset ) { + if ( els.length > 1 ) + els[1].style.cursor = opts.cursorReset; + if ( els.length > 2 ) + els[2].style.cursor = opts.cursorReset; + } + + if (full) + pageBlock = pageBlockEls = null; + + if (opts.fadeOut) { + count = els.length; + els.stop().fadeOut(opts.fadeOut, function() { + if ( --count === 0) + reset(els,data,opts,el); + }); + } + else + reset(els, data, opts, el); + } + + // move blocking element back into the DOM where it started + function reset(els,data,opts,el) { + var $el = $(el); + if ( $el.data('blockUI.isBlocked') ) + return; + + els.each(function(i,o) { + // remove via DOM calls so we don't lose event handlers + if (this.parentNode) + this.parentNode.removeChild(this); + }); + + if (data && data.el) { + data.el.style.display = data.display; + data.el.style.position = data.position; + data.el.style.cursor = 'default'; // #59 + if (data.parent) + data.parent.appendChild(data.el); + $el.removeData('blockUI.history'); + } + + if ($el.data('blockUI.static')) { + $el.css('position', 'static'); // #22 + } + + if (typeof opts.onUnblock == 'function') + opts.onUnblock(el,opts); + + // fix issue in Safari 6 where block artifacts remain until reflow + var body = $(document.body), w = body.width(), cssW = body[0].style.width; + body.width(w-1).width(w); + body[0].style.width = cssW; + } + + // bind/unbind the handler + function bind(b, el, opts) { + var full = el == window, $el = $(el); + + // don't bother unbinding if there is nothing to unbind + if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked'))) + return; + + $el.data('blockUI.isBlocked', b); + + // don't bind events when overlay is not in use or if bindEvents is false + if (!full || !opts.bindEvents || (b && !opts.showOverlay)) + return; + + // bind anchors and inputs for mouse and key events + var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove'; + if (b) + $(document).bind(events, opts, handler); + else + $(document).unbind(events, handler); + + // former impl... + // var $e = $('a,:input'); + // b ? $e.bind(events, opts, handler) : $e.unbind(events, handler); + } + + // event handler to suppress keyboard/mouse events when blocking + function handler(e) { + // allow tab navigation (conditionally) + if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) { + if (pageBlock && e.data.constrainTabKey) { + var els = pageBlockEls; + var fwd = !e.shiftKey && e.target === els[els.length-1]; + var back = e.shiftKey && e.target === els[0]; + if (fwd || back) { + setTimeout(function(){focus(back);},10); + return false; + } + } + } + var opts = e.data; + var target = $(e.target); + if (target.hasClass('blockOverlay') && opts.onOverlayClick) + opts.onOverlayClick(e); + + // allow events within the message content + if (target.parents('div.' + opts.blockMsgClass).length > 0) + return true; + + // allow events for content that is not being blocked + return target.parents().children().filter('div.blockUI').length === 0; + } + + function focus(back) { + if (!pageBlockEls) + return; + var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0]; + if (e) + e.focus(); + } + + function center(el, x, y) { + var p = el.parentNode, s = el.style; + var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth'); + var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth'); + if (x) s.left = l > 0 ? (l+'px') : '0'; + if (y) s.top = t > 0 ? (t+'px') : '0'; + } + + function sz(el, p) { + return parseInt($.css(el,p),10)||0; + } + + } + + + /*global define:true */ + if (typeof define === 'function' && define.amd && define.amd.jQuery) { + define(['jquery'], setup); + } else { + setup(jQuery); + } + +})(); diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/chartjs/Chart.bundle.min.js b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/chartjs/Chart.bundle.min.js new file mode 100755 index 00000000..7134d267 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/chartjs/Chart.bundle.min.js @@ -0,0 +1,7 @@ +/*! + * Chart.js v2.9.4 + * https://www.chartjs.org + * (c) 2020 Chart.js Contributors + * Released under the MIT License + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Chart=e()}(this,(function(){"use strict";"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;function t(){throw new Error("Dynamic requires are not currently supported by rollup-plugin-commonjs")}function e(t,e){return t(e={exports:{}},e.exports),e.exports}var n={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},i=e((function(t){var e={};for(var i in n)n.hasOwnProperty(i)&&(e[n[i]]=i);var a=t.exports={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};for(var r in a)if(a.hasOwnProperty(r)){if(!("channels"in a[r]))throw new Error("missing channels property: "+r);if(!("labels"in a[r]))throw new Error("missing channel labels property: "+r);if(a[r].labels.length!==a[r].channels)throw new Error("channel and label counts mismatch: "+r);var o=a[r].channels,s=a[r].labels;delete a[r].channels,delete a[r].labels,Object.defineProperty(a[r],"channels",{value:o}),Object.defineProperty(a[r],"labels",{value:s})}a.rgb.hsl=function(t){var e,n,i=t[0]/255,a=t[1]/255,r=t[2]/255,o=Math.min(i,a,r),s=Math.max(i,a,r),l=s-o;return s===o?e=0:i===s?e=(a-r)/l:a===s?e=2+(r-i)/l:r===s&&(e=4+(i-a)/l),(e=Math.min(60*e,360))<0&&(e+=360),n=(o+s)/2,[e,100*(s===o?0:n<=.5?l/(s+o):l/(2-s-o)),100*n]},a.rgb.hsv=function(t){var e,n,i,a,r,o=t[0]/255,s=t[1]/255,l=t[2]/255,u=Math.max(o,s,l),d=u-Math.min(o,s,l),h=function(t){return(u-t)/6/d+.5};return 0===d?a=r=0:(r=d/u,e=h(o),n=h(s),i=h(l),o===u?a=i-n:s===u?a=1/3+e-i:l===u&&(a=2/3+n-e),a<0?a+=1:a>1&&(a-=1)),[360*a,100*r,100*u]},a.rgb.hwb=function(t){var e=t[0],n=t[1],i=t[2];return[a.rgb.hsl(t)[0],100*(1/255*Math.min(e,Math.min(n,i))),100*(i=1-1/255*Math.max(e,Math.max(n,i)))]},a.rgb.cmyk=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255;return[100*((1-n-(e=Math.min(1-n,1-i,1-a)))/(1-e)||0),100*((1-i-e)/(1-e)||0),100*((1-a-e)/(1-e)||0),100*e]},a.rgb.keyword=function(t){var i=e[t];if(i)return i;var a,r,o,s=1/0;for(var l in n)if(n.hasOwnProperty(l)){var u=n[l],d=(r=t,o=u,Math.pow(r[0]-o[0],2)+Math.pow(r[1]-o[1],2)+Math.pow(r[2]-o[2],2));d.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)+.1805*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)),100*(.2126*e+.7152*n+.0722*i),100*(.0193*e+.1192*n+.9505*i)]},a.rgb.lab=function(t){var e=a.rgb.xyz(t),n=e[0],i=e[1],r=e[2];return i/=100,r/=108.883,n=(n/=95.047)>.008856?Math.pow(n,1/3):7.787*n+16/116,[116*(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116)-16,500*(n-i),200*(i-(r=r>.008856?Math.pow(r,1/3):7.787*r+16/116))]},a.hsl.rgb=function(t){var e,n,i,a,r,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0===s)return[r=255*l,r,r];e=2*l-(n=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var u=0;u<3;u++)(i=o+1/3*-(u-1))<0&&i++,i>1&&i--,r=6*i<1?e+6*(n-e)*i:2*i<1?n:3*i<2?e+(n-e)*(2/3-i)*6:e,a[u]=255*r;return a},a.hsl.hsv=function(t){var e=t[0],n=t[1]/100,i=t[2]/100,a=n,r=Math.max(i,.01);return n*=(i*=2)<=1?i:2-i,a*=r<=1?r:2-r,[e,100*(0===i?2*a/(r+a):2*n/(i+n)),100*((i+n)/2)]},a.hsv.rgb=function(t){var e=t[0]/60,n=t[1]/100,i=t[2]/100,a=Math.floor(e)%6,r=e-Math.floor(e),o=255*i*(1-n),s=255*i*(1-n*r),l=255*i*(1-n*(1-r));switch(i*=255,a){case 0:return[i,l,o];case 1:return[s,i,o];case 2:return[o,i,l];case 3:return[o,s,i];case 4:return[l,o,i];case 5:return[i,o,s]}},a.hsv.hsl=function(t){var e,n,i,a=t[0],r=t[1]/100,o=t[2]/100,s=Math.max(o,.01);return i=(2-r)*o,n=r*s,[a,100*(n=(n/=(e=(2-r)*s)<=1?e:2-e)||0),100*(i/=2)]},a.hwb.rgb=function(t){var e,n,i,a,r,o,s,l=t[0]/360,u=t[1]/100,d=t[2]/100,h=u+d;switch(h>1&&(u/=h,d/=h),i=6*l-(e=Math.floor(6*l)),0!=(1&e)&&(i=1-i),a=u+i*((n=1-d)-u),e){default:case 6:case 0:r=n,o=a,s=u;break;case 1:r=a,o=n,s=u;break;case 2:r=u,o=n,s=a;break;case 3:r=u,o=a,s=n;break;case 4:r=a,o=u,s=n;break;case 5:r=n,o=u,s=a}return[255*r,255*o,255*s]},a.cmyk.rgb=function(t){var e=t[0]/100,n=t[1]/100,i=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a)),255*(1-Math.min(1,i*(1-a)+a))]},a.xyz.rgb=function(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100;return n=-.9689*a+1.8758*r+.0415*o,i=.0557*a+-.204*r+1.057*o,e=(e=3.2406*a+-1.5372*r+-.4986*o)>.0031308?1.055*Math.pow(e,1/2.4)-.055:12.92*e,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:12.92*n,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:12.92*i,[255*(e=Math.min(Math.max(0,e),1)),255*(n=Math.min(Math.max(0,n),1)),255*(i=Math.min(Math.max(0,i),1))]},a.xyz.lab=function(t){var e=t[0],n=t[1],i=t[2];return n/=100,i/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(e-n),200*(n-(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116))]},a.lab.xyz=function(t){var e,n,i,a=t[0];e=t[1]/500+(n=(a+16)/116),i=n-t[2]/200;var r=Math.pow(n,3),o=Math.pow(e,3),s=Math.pow(i,3);return n=r>.008856?r:(n-16/116)/7.787,e=o>.008856?o:(e-16/116)/7.787,i=s>.008856?s:(i-16/116)/7.787,[e*=95.047,n*=100,i*=108.883]},a.lab.lch=function(t){var e,n=t[0],i=t[1],a=t[2];return(e=360*Math.atan2(a,i)/2/Math.PI)<0&&(e+=360),[n,Math.sqrt(i*i+a*a),e]},a.lch.lab=function(t){var e,n=t[0],i=t[1];return e=t[2]/360*2*Math.PI,[n,i*Math.cos(e),i*Math.sin(e)]},a.rgb.ansi16=function(t){var e=t[0],n=t[1],i=t[2],r=1 in arguments?arguments[1]:a.rgb.hsv(t)[2];if(0===(r=Math.round(r/50)))return 30;var o=30+(Math.round(i/255)<<2|Math.round(n/255)<<1|Math.round(e/255));return 2===r&&(o+=60),o},a.hsv.ansi16=function(t){return a.rgb.ansi16(a.hsv.rgb(t),t[2])},a.rgb.ansi256=function(t){var e=t[0],n=t[1],i=t[2];return e===n&&n===i?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(n/255*5)+Math.round(i/255*5)},a.ansi16.rgb=function(t){var e=t%10;if(0===e||7===e)return t>50&&(e+=3.5),[e=e/10.5*255,e,e];var n=.5*(1+~~(t>50));return[(1&e)*n*255,(e>>1&1)*n*255,(e>>2&1)*n*255]},a.ansi256.rgb=function(t){if(t>=232){var e=10*(t-232)+8;return[e,e,e]}var n;return t-=16,[Math.floor(t/36)/5*255,Math.floor((n=t%36)/6)/5*255,n%6/5*255]},a.rgb.hex=function(t){var e=(((255&Math.round(t[0]))<<16)+((255&Math.round(t[1]))<<8)+(255&Math.round(t[2]))).toString(16).toUpperCase();return"000000".substring(e.length)+e},a.hex.rgb=function(t){var e=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];var n=e[0];3===e[0].length&&(n=n.split("").map((function(t){return t+t})).join(""));var i=parseInt(n,16);return[i>>16&255,i>>8&255,255&i]},a.rgb.hcg=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255,r=Math.max(Math.max(n,i),a),o=Math.min(Math.min(n,i),a),s=r-o;return e=s<=0?0:r===n?(i-a)/s%6:r===i?2+(a-n)/s:4+(n-i)/s+4,e/=6,[360*(e%=1),100*s,100*(s<1?o/(1-s):0)]},a.hsl.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=1,a=0;return(i=n<.5?2*e*n:2*e*(1-n))<1&&(a=(n-.5*i)/(1-i)),[t[0],100*i,100*a]},a.hsv.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=e*n,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.hcg.rgb=function(t){var e=t[0]/360,n=t[1]/100,i=t[2]/100;if(0===n)return[255*i,255*i,255*i];var a,r=[0,0,0],o=e%1*6,s=o%1,l=1-s;switch(Math.floor(o)){case 0:r[0]=1,r[1]=s,r[2]=0;break;case 1:r[0]=l,r[1]=1,r[2]=0;break;case 2:r[0]=0,r[1]=1,r[2]=s;break;case 3:r[0]=0,r[1]=l,r[2]=1;break;case 4:r[0]=s,r[1]=0,r[2]=1;break;default:r[0]=1,r[1]=0,r[2]=l}return a=(1-n)*i,[255*(n*r[0]+a),255*(n*r[1]+a),255*(n*r[2]+a)]},a.hcg.hsv=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e),i=0;return n>0&&(i=e/n),[t[0],100*i,100*n]},a.hcg.hsl=function(t){var e=t[1]/100,n=t[2]/100*(1-e)+.5*e,i=0;return n>0&&n<.5?i=e/(2*n):n>=.5&&n<1&&(i=e/(2*(1-n))),[t[0],100*i,100*n]},a.hcg.hwb=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e);return[t[0],100*(n-e),100*(1-n)]},a.hwb.hcg=function(t){var e=t[1]/100,n=1-t[2]/100,i=n-e,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]},a.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]},a.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]},a.gray.hsl=a.gray.hsv=function(t){return[0,0,t[0]]},a.gray.hwb=function(t){return[0,100,t[0]]},a.gray.cmyk=function(t){return[0,0,0,t[0]]},a.gray.lab=function(t){return[t[0],0,0]},a.gray.hex=function(t){var e=255&Math.round(t[0]/100*255),n=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(n.length)+n},a.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]}}));i.rgb,i.hsl,i.hsv,i.hwb,i.cmyk,i.xyz,i.lab,i.lch,i.hex,i.keyword,i.ansi16,i.ansi256,i.hcg,i.apple,i.gray;function a(t){var e=function(){for(var t={},e=Object.keys(i),n=e.length,a=0;a1&&(e=Array.prototype.slice.call(arguments));var n=t(e);if("object"==typeof n)for(var i=n.length,a=0;a1&&(e=Array.prototype.slice.call(arguments)),t(e))};return"conversion"in t&&(e.conversion=t.conversion),e}(i)}))}));var l=s,u={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},d={getRgba:h,getHsla:c,getRgb:function(t){var e=h(t);return e&&e.slice(0,3)},getHsl:function(t){var e=c(t);return e&&e.slice(0,3)},getHwb:f,getAlpha:function(t){var e=h(t);if(e)return e[3];if(e=c(t))return e[3];if(e=f(t))return e[3]},hexString:function(t,e){e=void 0!==e&&3===t.length?e:t[3];return"#"+b(t[0])+b(t[1])+b(t[2])+(e>=0&&e<1?b(Math.round(255*e)):"")},rgbString:function(t,e){if(e<1||t[3]&&t[3]<1)return g(t,e);return"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:g,percentString:function(t,e){if(e<1||t[3]&&t[3]<1)return m(t,e);var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+n+"%, "+i+"%, "+a+"%)"},percentaString:m,hslString:function(t,e){if(e<1||t[3]&&t[3]<1)return p(t,e);return"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:p,hwbString:function(t,e){void 0===e&&(e=void 0!==t[3]?t[3]:1);return"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"},keyword:function(t){return y[t.slice(0,3)]}};function h(t){if(t){var e=[0,0,0],n=1,i=t.match(/^#([a-fA-F0-9]{3,4})$/i),a="";if(i){a=(i=i[1])[3];for(var r=0;rn?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,n=(e[0]+t)%360;return e[0]=n<0?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=t,i=void 0===e?.5:e,a=2*i-1,r=this.alpha()-n.alpha(),o=((a*r==-1?a:(a+r)/(1+a*r))+1)/2,s=1-o;return this.rgb(o*this.red()+s*n.red(),o*this.green()+s*n.green(),o*this.blue()+s*n.blue()).alpha(this.alpha()*i+n.alpha()*(1-i))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new _,i=this.values,a=n.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],"[object Array]"===(e={}.toString.call(t))?a[r]=t.slice(0):"[object Number]"===e?a[r]=t:console.error("unexpected color value:",t));return n}},_.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},_.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},_.prototype.getValues=function(t){for(var e=this.values,n={},i=0;i=0;a--)e.call(n,t[a],a);else for(a=0;a=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),-i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n))},easeOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/n)+1)},easeInOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:2==(t/=.5)?1:(n||(n=.45),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),t<1?i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*-.5:i*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){var e=1.70158;return t*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-C.easeOutBounce(1-t)},easeOutBounce:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*C.easeInBounce(2*t):.5*C.easeOutBounce(2*t-1)+.5}},P={effects:C};D.easingEffects=C;var T=Math.PI,O=T/180,A=2*T,F=T/2,I=T/4,L=2*T/3,R={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,n,i,a,r){if(r){var o=Math.min(r,a/2,i/2),s=e+o,l=n+o,u=e+i-o,d=n+a-o;t.moveTo(e,l),se.left-1e-6&&t.xe.top-1e-6&&t.y0&&this.requestAnimationFrame()},advance:function(){for(var t,e,n,i,a=this.animations,r=0;r=n?(B.callback(t.onAnimationComplete,[t],e),e.animating=!1,a.splice(r,1)):++r}},tt=B.options.resolve,et=["push","pop","shift","splice","unshift"];function nt(t,e){var n=t._chartjs;if(n){var i=n.listeners,a=i.indexOf(e);-1!==a&&i.splice(a,1),i.length>0||(et.forEach((function(e){delete t[e]})),delete t._chartjs)}}var it=function(t,e){this.initialize(t,e)};B.extend(it.prototype,{datasetElementType:null,dataElementType:null,_datasetElementOptions:["backgroundColor","borderCapStyle","borderColor","borderDash","borderDashOffset","borderJoinStyle","borderWidth"],_dataElementOptions:["backgroundColor","borderColor","borderWidth","pointStyle"],initialize:function(t,e){var n=this;n.chart=t,n.index=e,n.linkScales(),n.addElements(),n._type=n.getMeta().type},updateIndex:function(t){this.index=t},linkScales:function(){var t=this.getMeta(),e=this.chart,n=e.scales,i=this.getDataset(),a=e.options.scales;null!==t.xAxisID&&t.xAxisID in n&&!i.xAxisID||(t.xAxisID=i.xAxisID||a.xAxes[0].id),null!==t.yAxisID&&t.yAxisID in n&&!i.yAxisID||(t.yAxisID=i.yAxisID||a.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},_getValueScaleId:function(){return this.getMeta().yAxisID},_getIndexScaleId:function(){return this.getMeta().xAxisID},_getValueScale:function(){return this.getScaleForId(this._getValueScaleId())},_getIndexScale:function(){return this.getScaleForId(this._getIndexScaleId())},reset:function(){this._update(!0)},destroy:function(){this._data&&nt(this._data,this)},createMetaDataset:function(){var t=this.datasetElementType;return t&&new t({_chart:this.chart,_datasetIndex:this.index})},createMetaData:function(t){var e=this.dataElementType;return e&&new e({_chart:this.chart,_datasetIndex:this.index,_index:t})},addElements:function(){var t,e,n=this.getMeta(),i=this.getDataset().data||[],a=n.data;for(t=0,e=i.length;tn&&this.insertElements(n,i-n)},insertElements:function(t,e){for(var n=0;na?(r=a/e.innerRadius,t.arc(o,s,e.innerRadius-a,i+r,n-r,!0)):t.arc(o,s,a,i+Math.PI/2,n-Math.PI/2),t.closePath(),t.clip()}function st(t,e,n){var i="inner"===e.borderAlign;i?(t.lineWidth=2*e.borderWidth,t.lineJoin="round"):(t.lineWidth=e.borderWidth,t.lineJoin="bevel"),n.fullCircles&&function(t,e,n,i){var a,r=n.endAngle;for(i&&(n.endAngle=n.startAngle+rt,ot(t,n),n.endAngle=r,n.endAngle===n.startAngle&&n.fullCircles&&(n.endAngle+=rt,n.fullCircles--)),t.beginPath(),t.arc(n.x,n.y,n.innerRadius,n.startAngle+rt,n.startAngle,!0),a=0;as;)a-=rt;for(;a=o&&a<=s,u=r>=n.innerRadius&&r<=n.outerRadius;return l&&u}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,n=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,n=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},draw:function(){var t,e=this._chart.ctx,n=this._view,i="inner"===n.borderAlign?.33:0,a={x:n.x,y:n.y,innerRadius:n.innerRadius,outerRadius:Math.max(n.outerRadius-i,0),pixelMargin:i,startAngle:n.startAngle,endAngle:n.endAngle,fullCircles:Math.floor(n.circumference/rt)};if(e.save(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,a.fullCircles){for(a.endAngle=a.startAngle+rt,e.beginPath(),e.arc(a.x,a.y,a.outerRadius,a.startAngle,a.endAngle),e.arc(a.x,a.y,a.innerRadius,a.endAngle,a.startAngle,!0),e.closePath(),t=0;tt.x&&(e=yt(e,"left","right")):t.basen?n:i,r:l.right||a<0?0:a>e?e:a,b:l.bottom||r<0?0:r>n?n:r,l:l.left||o<0?0:o>e?e:o}}function _t(t,e,n){var i=null===e,a=null===n,r=!(!t||i&&a)&&bt(t);return r&&(i||e>=r.left&&e<=r.right)&&(a||n>=r.top&&n<=r.bottom)}Y._set("global",{elements:{rectangle:{backgroundColor:pt,borderColor:pt,borderSkipped:"bottom",borderWidth:0}}});var wt=X.extend({_type:"rectangle",draw:function(){var t=this._chart.ctx,e=this._view,n=function(t){var e=bt(t),n=e.right-e.left,i=e.bottom-e.top,a=xt(t,n/2,i/2);return{outer:{x:e.left,y:e.top,w:n,h:i},inner:{x:e.left+a.l,y:e.top+a.t,w:n-a.l-a.r,h:i-a.t-a.b}}}(e),i=n.outer,a=n.inner;t.fillStyle=e.backgroundColor,t.fillRect(i.x,i.y,i.w,i.h),i.w===a.w&&i.h===a.h||(t.save(),t.beginPath(),t.rect(i.x,i.y,i.w,i.h),t.clip(),t.fillStyle=e.borderColor,t.rect(a.x,a.y,a.w,a.h),t.fill("evenodd"),t.restore())},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){return _t(this._view,t,e)},inLabelRange:function(t,e){var n=this._view;return vt(n)?_t(n,t,null):_t(n,null,e)},inXRange:function(t){return _t(this._view,t,null)},inYRange:function(t){return _t(this._view,null,t)},getCenterPoint:function(){var t,e,n=this._view;return vt(n)?(t=n.x,e=(n.y+n.base)/2):(t=(n.x+n.base)/2,e=n.y),{x:t,y:e}},getArea:function(){var t=this._view;return vt(t)?t.width*Math.abs(t.y-t.base):t.height*Math.abs(t.x-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}}),kt={},Mt=lt,St=ht,Dt=mt,Ct=wt;kt.Arc=Mt,kt.Line=St,kt.Point=Dt,kt.Rectangle=Ct;var Pt=B._deprecated,Tt=B.valueOrDefault;function Ot(t,e,n){var i,a,r=n.barThickness,o=e.stackCount,s=e.pixels[t],l=B.isNullOrUndef(r)?function(t,e){var n,i,a,r,o=t._length;for(a=1,r=e.length;a0?Math.min(o,Math.abs(i-n)):o,n=i;return o}(e.scale,e.pixels):-1;return B.isNullOrUndef(r)?(i=l*n.categoryPercentage,a=n.barPercentage):(i=r*o,a=1),{chunk:i/o,ratio:a,start:s-i/2}}Y._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),Y._set("global",{datasets:{bar:{categoryPercentage:.8,barPercentage:.9}}});var At=at.extend({dataElementType:kt.Rectangle,_dataElementOptions:["backgroundColor","borderColor","borderSkipped","borderWidth","barPercentage","barThickness","categoryPercentage","maxBarThickness","minBarLength"],initialize:function(){var t,e,n=this;at.prototype.initialize.apply(n,arguments),(t=n.getMeta()).stack=n.getDataset().stack,t.bar=!0,e=n._getIndexScale().options,Pt("bar chart",e.barPercentage,"scales.[x/y]Axes.barPercentage","dataset.barPercentage"),Pt("bar chart",e.barThickness,"scales.[x/y]Axes.barThickness","dataset.barThickness"),Pt("bar chart",e.categoryPercentage,"scales.[x/y]Axes.categoryPercentage","dataset.categoryPercentage"),Pt("bar chart",n._getValueScale().options.minBarLength,"scales.[x/y]Axes.minBarLength","dataset.minBarLength"),Pt("bar chart",e.maxBarThickness,"scales.[x/y]Axes.maxBarThickness","dataset.maxBarThickness")},update:function(t){var e,n,i=this.getMeta().data;for(this._ruler=this.getRuler(),e=0,n=i.length;e=0&&m.min>=0?m.min:m.max,x=void 0===m.start?m.end:m.max>=0&&m.min>=0?m.max-m.min:m.min-m.max,_=g.length;if(v||void 0===v&&void 0!==b)for(i=0;i<_&&(a=g[i]).index!==t;++i)a.stack===b&&(r=void 0===(u=h._parseValue(f[a.index].data[e])).start?u.end:u.min>=0&&u.max>=0?u.max:u.min,(m.min<0&&r<0||m.max>=0&&r>0)&&(y+=r));return o=h.getPixelForValue(y),l=(s=h.getPixelForValue(y+x))-o,void 0!==p&&Math.abs(l)=0&&!c||x<0&&c?o-p:o+p),{size:l,base:o,head:s,center:s+l/2}},calculateBarIndexPixels:function(t,e,n,i){var a="flex"===i.barThickness?function(t,e,n){var i,a=e.pixels,r=a[t],o=t>0?a[t-1]:null,s=t=Nt?-Wt:b<-Nt?Wt:0)+p,x=Math.cos(b),_=Math.sin(b),w=Math.cos(y),k=Math.sin(y),M=b<=0&&y>=0||y>=Wt,S=b<=Yt&&y>=Yt||y>=Wt+Yt,D=b<=-Yt&&y>=-Yt||y>=Nt+Yt,C=b===-Nt||y>=Nt?-1:Math.min(x,x*m,w,w*m),P=D?-1:Math.min(_,_*m,k,k*m),T=M?1:Math.max(x,x*m,w,w*m),O=S?1:Math.max(_,_*m,k,k*m);u=(T-C)/2,d=(O-P)/2,h=-(T+C)/2,c=-(O+P)/2}for(i=0,a=g.length;i0&&!isNaN(t)?Wt*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){var e,n,i,a,r,o,s,l,u=0,d=this.chart;if(!t)for(e=0,n=d.data.datasets.length;e(u=s>u?s:u)?l:u);return u},setHoverStyle:function(t){var e=t._model,n=t._options,i=B.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=Rt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Rt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Rt(n.hoverBorderWidth,n.borderWidth)},_getRingWeightOffset:function(t){for(var e=0,n=0;n0&&Bt(l[t-1]._model,s)&&(n.controlPointPreviousX=u(n.controlPointPreviousX,s.left,s.right),n.controlPointPreviousY=u(n.controlPointPreviousY,s.top,s.bottom)),t0&&(r=t.getDatasetMeta(r[0]._datasetIndex).data),r},"x-axis":function(t,e){return re(t,e,{intersect:!1})},point:function(t,e){return ne(t,te(e,t))},nearest:function(t,e,n){var i=te(e,t);n.axis=n.axis||"xy";var a=ae(n.axis);return ie(t,i,n.intersect,a)},x:function(t,e,n){var i=te(e,t),a=[],r=!1;return ee(t,(function(t){t.inXRange(i.x)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a},y:function(t,e,n){var i=te(e,t),a=[],r=!1;return ee(t,(function(t){t.inYRange(i.y)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a}}},se=B.extend;function le(t,e){return B.where(t,(function(t){return t.pos===e}))}function ue(t,e){return t.sort((function(t,n){var i=e?n:t,a=e?t:n;return i.weight===a.weight?i.index-a.index:i.weight-a.weight}))}function de(t,e,n,i){return Math.max(t[n],e[n])+Math.max(t[i],e[i])}function he(t,e,n){var i,a,r=n.box,o=t.maxPadding;if(n.size&&(t[n.pos]-=n.size),n.size=n.horizontal?r.height:r.width,t[n.pos]+=n.size,r.getPadding){var s=r.getPadding();o.top=Math.max(o.top,s.top),o.left=Math.max(o.left,s.left),o.bottom=Math.max(o.bottom,s.bottom),o.right=Math.max(o.right,s.right)}if(i=e.outerWidth-de(o,t,"left","right"),a=e.outerHeight-de(o,t,"top","bottom"),i!==t.w||a!==t.h){t.w=i,t.h=a;var l=n.horizontal?[i,t.w]:[a,t.h];return!(l[0]===l[1]||isNaN(l[0])&&isNaN(l[1]))}}function ce(t,e){var n=e.maxPadding;function i(t){var i={left:0,top:0,right:0,bottom:0};return t.forEach((function(t){i[t]=Math.max(e[t],n[t])})),i}return i(t?["left","right"]:["top","bottom"])}function fe(t,e,n){var i,a,r,o,s,l,u=[];for(i=0,a=t.length;idiv{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0}"}))&&me.default||me,be="$chartjs",ye="chartjs-size-monitor",xe="chartjs-render-monitor",_e="chartjs-render-animation",we=["animationstart","webkitAnimationStart"],ke={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};function Me(t,e){var n=B.getStyle(t,e),i=n&&n.match(/^(\d+)(\.\d+)?px$/);return i?Number(i[1]):void 0}var Se=!!function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("e",null,e)}catch(t){}return t}()&&{passive:!0};function De(t,e,n){t.addEventListener(e,n,Se)}function Ce(t,e,n){t.removeEventListener(e,n,Se)}function Pe(t,e,n,i,a){return{type:t,chart:e,native:a||null,x:void 0!==n?n:null,y:void 0!==i?i:null}}function Te(t){var e=document.createElement("div");return e.className=t||"",e}function Oe(t,e,n){var i,a,r,o,s=t[be]||(t[be]={}),l=s.resizer=function(t){var e=Te(ye),n=Te(ye+"-expand"),i=Te(ye+"-shrink");n.appendChild(Te()),i.appendChild(Te()),e.appendChild(n),e.appendChild(i),e._reset=function(){n.scrollLeft=1e6,n.scrollTop=1e6,i.scrollLeft=1e6,i.scrollTop=1e6};var a=function(){e._reset(),t()};return De(n,"scroll",a.bind(n,"expand")),De(i,"scroll",a.bind(i,"shrink")),e}((i=function(){if(s.resizer){var i=n.options.maintainAspectRatio&&t.parentNode,a=i?i.clientWidth:0;e(Pe("resize",n)),i&&i.clientWidth0){var r=t[0];r.label?n=r.label:r.xLabel?n=r.xLabel:a>0&&r.index-1?t.split("\n"):t}function He(t){var e=Y.global;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,rtl:t.rtl,textDirection:t.textDirection,bodyFontColor:t.bodyFontColor,_bodyFontFamily:We(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:We(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:We(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:We(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:We(t.titleFontStyle,e.defaultFontStyle),titleFontSize:We(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:We(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:We(t.footerFontStyle,e.defaultFontStyle),footerFontSize:We(t.footerFontSize,e.defaultFontSize),_footerAlign:t.footerAlign,footerSpacing:t.footerSpacing,footerMarginTop:t.footerMarginTop,caretSize:t.caretSize,cornerRadius:t.cornerRadius,backgroundColor:t.backgroundColor,opacity:0,legendColorBackground:t.multiKeyBackground,displayColors:t.displayColors,borderColor:t.borderColor,borderWidth:t.borderWidth}}function Be(t,e){return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-t.xPadding:t.x+t.xPadding}function je(t){return Ee([],Ve(t))}var Ue=X.extend({initialize:function(){this._model=He(this._options),this._lastActive=[]},getTitle:function(){var t=this,e=t._options,n=e.callbacks,i=n.beforeTitle.apply(t,arguments),a=n.title.apply(t,arguments),r=n.afterTitle.apply(t,arguments),o=[];return o=Ee(o,Ve(i)),o=Ee(o,Ve(a)),o=Ee(o,Ve(r))},getBeforeBody:function(){return je(this._options.callbacks.beforeBody.apply(this,arguments))},getBody:function(t,e){var n=this,i=n._options.callbacks,a=[];return B.each(t,(function(t){var r={before:[],lines:[],after:[]};Ee(r.before,Ve(i.beforeLabel.call(n,t,e))),Ee(r.lines,i.label.call(n,t,e)),Ee(r.after,Ve(i.afterLabel.call(n,t,e))),a.push(r)})),a},getAfterBody:function(){return je(this._options.callbacks.afterBody.apply(this,arguments))},getFooter:function(){var t=this,e=t._options.callbacks,n=e.beforeFooter.apply(t,arguments),i=e.footer.apply(t,arguments),a=e.afterFooter.apply(t,arguments),r=[];return r=Ee(r,Ve(n)),r=Ee(r,Ve(i)),r=Ee(r,Ve(a))},update:function(t){var e,n,i,a,r,o,s,l,u,d,h=this,c=h._options,f=h._model,g=h._model=He(c),m=h._active,p=h._data,v={xAlign:f.xAlign,yAlign:f.yAlign},b={x:f.x,y:f.y},y={width:f.width,height:f.height},x={x:f.caretX,y:f.caretY};if(m.length){g.opacity=1;var _=[],w=[];x=ze[c.position].call(h,m,h._eventPosition);var k=[];for(e=0,n=m.length;ei.width&&(a=i.width-e.width),a<0&&(a=0)),"top"===d?r+=h:r-="bottom"===d?e.height+h:e.height/2,"center"===d?"left"===u?a+=h:"right"===u&&(a-=h):"left"===u?a-=c:"right"===u&&(a+=c),{x:a,y:r}}(g,y,v=function(t,e){var n,i,a,r,o,s=t._model,l=t._chart,u=t._chart.chartArea,d="center",h="center";s.yl.height-e.height&&(h="bottom");var c=(u.left+u.right)/2,f=(u.top+u.bottom)/2;"center"===h?(n=function(t){return t<=c},i=function(t){return t>c}):(n=function(t){return t<=e.width/2},i=function(t){return t>=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},r=function(t){return t-e.width-s.caretSize-s.caretPadding<0},o=function(t){return t<=f?"top":"bottom"},n(s.x)?(d="left",a(s.x)&&(d="center",h=o(s.y))):i(s.x)&&(d="right",r(s.x)&&(d="center",h=o(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:d,yAlign:g.yAlign?g.yAlign:h}}(this,y),h._chart)}else g.opacity=0;return g.xAlign=v.xAlign,g.yAlign=v.yAlign,g.x=b.x,g.y=b.y,g.width=y.width,g.height=y.height,g.caretX=x.x,g.caretY=x.y,h._model=g,t&&c.custom&&c.custom.call(h,g),h},drawCaret:function(t,e){var n=this._chart.ctx,i=this._view,a=this.getCaretPosition(t,e,i);n.lineTo(a.x1,a.y1),n.lineTo(a.x2,a.y2),n.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,n){var i,a,r,o,s,l,u=n.caretSize,d=n.cornerRadius,h=n.xAlign,c=n.yAlign,f=t.x,g=t.y,m=e.width,p=e.height;if("center"===c)s=g+p/2,"left"===h?(a=(i=f)-u,r=i,o=s+u,l=s-u):(a=(i=f+m)+u,r=i,o=s-u,l=s+u);else if("left"===h?(i=(a=f+d+u)-u,r=a+u):"right"===h?(i=(a=f+m-d-u)-u,r=a+u):(i=(a=n.caretX)-u,r=a+u),"top"===c)s=(o=g)-u,l=o;else{s=(o=g+p)+u,l=o;var v=r;r=i,i=v}return{x1:i,x2:a,x3:r,y1:o,y2:s,y3:l}},drawTitle:function(t,e,n){var i,a,r,o=e.title,s=o.length;if(s){var l=Ye(e.rtl,e.x,e.width);for(t.x=Be(e,e._titleAlign),n.textAlign=l.textAlign(e._titleAlign),n.textBaseline="middle",i=e.titleFontSize,a=e.titleSpacing,n.fillStyle=e.titleFontColor,n.font=B.fontString(i,e._titleFontStyle,e._titleFontFamily),r=0;r0&&n.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n={width:e.width,height:e.height},i={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,r=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&r&&(t.save(),t.globalAlpha=a,this.drawBackground(i,e,t,n),i.y+=e.yPadding,B.rtl.overrideTextDirection(t,e.textDirection),this.drawTitle(i,e,t),this.drawBody(i,e,t),this.drawFooter(i,e,t),B.rtl.restoreTextDirection(t,e.textDirection),t.restore())}},handleEvent:function(t){var e,n=this,i=n._options;return n._lastActive=n._lastActive||[],"mouseout"===t.type?n._active=[]:(n._active=n._chart.getElementsAtEventForMode(t,i.mode,i),i.reverse&&n._active.reverse()),(e=!B.arrayEquals(n._active,n._lastActive))&&(n._lastActive=n._active,(i.enabled||i.custom)&&(n._eventPosition={x:t.x,y:t.y},n.update(!0),n.pivot())),e}}),Ge=ze,qe=Ue;qe.positioners=Ge;var Ze=B.valueOrDefault;function $e(){return B.merge(Object.create(null),[].slice.call(arguments),{merger:function(t,e,n,i){if("xAxes"===t||"yAxes"===t){var a,r,o,s=n[t].length;for(e[t]||(e[t]=[]),a=0;a=e[t].length&&e[t].push({}),!e[t][a].type||o.type&&o.type!==e[t][a].type?B.merge(e[t][a],[Ne.getScaleDefaults(r),o]):B.merge(e[t][a],o)}else B._merger(t,e,n,i)}})}function Xe(){return B.merge(Object.create(null),[].slice.call(arguments),{merger:function(t,e,n,i){var a=e[t]||Object.create(null),r=n[t];"scales"===t?e[t]=$e(a,r):"scale"===t?e[t]=B.merge(a,[Ne.getScaleDefaults(r.type),r]):B._merger(t,e,n,i)}})}function Ke(t){var e=t.options;B.each(t.scales,(function(e){pe.removeBox(t,e)})),e=Xe(Y.global,Y[t.config.type],e),t.options=t.config.options=e,t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.tooltip._options=e.tooltips,t.tooltip.initialize()}function Je(t,e,n){var i,a=function(t){return t.id===i};do{i=e+n++}while(B.findIndex(t,a)>=0);return i}function Qe(t){return"top"===t||"bottom"===t}function tn(t,e){return function(n,i){return n[t]===i[t]?n[e]-i[e]:n[t]-i[t]}}Y._set("global",{elements:{},events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,maintainAspectRatio:!0,responsive:!0,responsiveAnimationDuration:0});var en=function(t,e){return this.construct(t,e),this};B.extend(en.prototype,{construct:function(t,e){var n=this;e=function(t){var e=(t=t||Object.create(null)).data=t.data||{};return e.datasets=e.datasets||[],e.labels=e.labels||[],t.options=Xe(Y.global,Y[t.type],t.options||{}),t}(e);var i=Le.acquireContext(t,e),a=i&&i.canvas,r=a&&a.height,o=a&&a.width;n.id=B.uid(),n.ctx=i,n.canvas=a,n.config=e,n.width=o,n.height=r,n.aspectRatio=r?o/r:null,n.options=e.options,n._bufferedRender=!1,n._layers=[],n.chart=n,n.controller=n,en.instances[n.id]=n,Object.defineProperty(n,"data",{get:function(){return n.config.data},set:function(t){n.config.data=t}}),i&&a?(n.initialize(),n.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return Re.notify(t,"beforeInit"),B.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.initToolTip(),Re.notify(t,"afterInit"),t},clear:function(){return B.canvas.clear(this),this},stop:function(){return Q.cancelAnimation(this),this},resize:function(t){var e=this,n=e.options,i=e.canvas,a=n.maintainAspectRatio&&e.aspectRatio||null,r=Math.max(0,Math.floor(B.getMaximumWidth(i))),o=Math.max(0,Math.floor(a?r/a:B.getMaximumHeight(i)));if((e.width!==r||e.height!==o)&&(i.width=e.width=r,i.height=e.height=o,i.style.width=r+"px",i.style.height=o+"px",B.retinaScale(e,n.devicePixelRatio),!t)){var s={width:r,height:o};Re.notify(e,"resize",[s]),n.onResize&&n.onResize(e,s),e.stop(),e.update({duration:n.responsiveAnimationDuration})}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},n=t.scale;B.each(e.xAxes,(function(t,n){t.id||(t.id=Je(e.xAxes,"x-axis-",n))})),B.each(e.yAxes,(function(t,n){t.id||(t.id=Je(e.yAxes,"y-axis-",n))})),n&&(n.id=n.id||"scale")},buildOrUpdateScales:function(){var t=this,e=t.options,n=t.scales||{},i=[],a=Object.keys(n).reduce((function(t,e){return t[e]=!1,t}),{});e.scales&&(i=i.concat((e.scales.xAxes||[]).map((function(t){return{options:t,dtype:"category",dposition:"bottom"}})),(e.scales.yAxes||[]).map((function(t){return{options:t,dtype:"linear",dposition:"left"}})))),e.scale&&i.push({options:e.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),B.each(i,(function(e){var i=e.options,r=i.id,o=Ze(i.type,e.dtype);Qe(i.position)!==Qe(e.dposition)&&(i.position=e.dposition),a[r]=!0;var s=null;if(r in n&&n[r].type===o)(s=n[r]).options=i,s.ctx=t.ctx,s.chart=t;else{var l=Ne.getScaleConstructor(o);if(!l)return;s=new l({id:r,type:o,options:i,ctx:t.ctx,chart:t}),n[s.id]=s}s.mergeTicksOptions(),e.isDefault&&(t.scale=s)})),B.each(a,(function(t,e){t||delete n[e]})),t.scales=n,Ne.addScalesToLayout(this)},buildOrUpdateControllers:function(){var t,e,n=this,i=[],a=n.data.datasets;for(t=0,e=a.length;t=0;--n)this.drawDataset(e[n],t);Re.notify(this,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n={meta:t,index:t.index,easingValue:e};!1!==Re.notify(this,"beforeDatasetDraw",[n])&&(t.controller.draw(e),Re.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this.tooltip,n={tooltip:e,easingValue:t};!1!==Re.notify(this,"beforeTooltipDraw",[n])&&(e.draw(),Re.notify(this,"afterTooltipDraw",[n]))},getElementAtEvent:function(t){return oe.modes.single(this,t)},getElementsAtEvent:function(t){return oe.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return oe.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,n){var i=oe.modes[e];return"function"==typeof i?i(this,t,n):[]},getDatasetAtEvent:function(t){return oe.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];e._meta||(e._meta={});var n=e._meta[this.id];return n||(n=e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e.order||0,index:t}),n},getVisibleDatasetCount:function(){for(var t=0,e=0,n=this.data.datasets.length;e3?n[2]-n[1]:n[1]-n[0];Math.abs(i)>1&&t!==Math.floor(t)&&(i=t-Math.floor(t));var a=B.log10(Math.abs(i)),r="";if(0!==t)if(Math.max(Math.abs(n[0]),Math.abs(n[n.length-1]))<1e-4){var o=B.log10(Math.abs(t)),s=Math.floor(o)-Math.floor(a);s=Math.max(Math.min(s,20),0),r=t.toExponential(s)}else{var l=-1*Math.floor(a);l=Math.max(Math.min(l,20),0),r=t.toFixed(l)}else r="0";return r},logarithmic:function(t,e,n){var i=t/Math.pow(10,Math.floor(B.log10(t)));return 0===t?"0":1===i||2===i||5===i||0===e||e===n.length-1?t.toExponential():""}}},ln=B.isArray,un=B.isNullOrUndef,dn=B.valueOrDefault,hn=B.valueAtIndexOrDefault;function cn(t,e,n){var i,a=t.getTicks().length,r=Math.min(e,a-1),o=t.getPixelForTick(r),s=t._startPixel,l=t._endPixel;if(!(n&&(i=1===a?Math.max(o-s,l-o):0===e?(t.getPixelForTick(1)-o)/2:(o-t.getPixelForTick(r-1))/2,(o+=rl+1e-6)))return o}function fn(t,e,n,i){var a,r,o,s,l,u,d,h,c,f,g,m,p,v=n.length,b=[],y=[],x=[],_=0,w=0;for(a=0;ae){for(n=0;n=c||d<=1||!s.isHorizontal()?s.labelRotation=h:(e=(t=s._getLabelSizes()).widest.width,n=t.highest.height-t.highest.offset,i=Math.min(s.maxWidth,s.chart.width-e),e+6>(a=l.offset?s.maxWidth/d:i/(d-1))&&(a=i/(d-(l.offset?.5:1)),r=s.maxHeight-gn(l.gridLines)-u.padding-mn(l.scaleLabel),o=Math.sqrt(e*e+n*n),f=B.toDegrees(Math.min(Math.asin(Math.min((t.highest.height+6)/a,1)),Math.asin(Math.min(r/o,1))-Math.asin(n/o))),f=Math.max(h,Math.min(c,f))),s.labelRotation=f)},afterCalculateTickRotation:function(){B.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){B.callback(this.options.beforeFit,[this])},fit:function(){var t=this,e=t.minSize={width:0,height:0},n=t.chart,i=t.options,a=i.ticks,r=i.scaleLabel,o=i.gridLines,s=t._isVisible(),l="bottom"===i.position,u=t.isHorizontal();if(u?e.width=t.maxWidth:s&&(e.width=gn(o)+mn(r)),u?s&&(e.height=gn(o)+mn(r)):e.height=t.maxHeight,a.display&&s){var d=vn(a),h=t._getLabelSizes(),c=h.first,f=h.last,g=h.widest,m=h.highest,p=.4*d.minor.lineHeight,v=a.padding;if(u){var b=0!==t.labelRotation,y=B.toRadians(t.labelRotation),x=Math.cos(y),_=Math.sin(y),w=_*g.width+x*(m.height-(b?m.offset:0))+(b?0:p);e.height=Math.min(t.maxHeight,e.height+w+v);var k,M,S=t.getPixelForTick(0)-t.left,D=t.right-t.getPixelForTick(t.getTicks().length-1);b?(k=l?x*c.width+_*c.offset:_*(c.height-c.offset),M=l?_*(f.height-f.offset):x*f.width+_*f.offset):(k=c.width/2,M=f.width/2),t.paddingLeft=Math.max((k-S)*t.width/(t.width-S),0)+3,t.paddingRight=Math.max((M-D)*t.width/(t.width-D),0)+3}else{var C=a.mirror?0:g.width+v+p;e.width=Math.min(t.maxWidth,e.width+C),t.paddingTop=c.height/2,t.paddingBottom=f.height/2}}t.handleMargins(),u?(t.width=t._length=n.width-t.margins.left-t.margins.right,t.height=e.height):(t.width=e.width,t.height=t._length=n.height-t.margins.top-t.margins.bottom)},handleMargins:function(){var t=this;t.margins&&(t.margins.left=Math.max(t.paddingLeft,t.margins.left),t.margins.top=Math.max(t.paddingTop,t.margins.top),t.margins.right=Math.max(t.paddingRight,t.margins.right),t.margins.bottom=Math.max(t.paddingBottom,t.margins.bottom))},afterFit:function(){B.callback(this.options.afterFit,[this])},isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(un(t))return NaN;if(("number"==typeof t||t instanceof Number)&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},_convertTicksToLabels:function(t){var e,n,i,a=this;for(a.ticks=t.map((function(t){return t.value})),a.beforeTickToLabelConversion(),e=a.convertTicksToLabels(t)||a.ticks,a.afterTickToLabelConversion(),n=0,i=t.length;nn-1?null:this.getPixelForDecimal(t*i+(e?i/2:0))},getPixelForDecimal:function(t){return this._reversePixels&&(t=1-t),this._startPixel+t*this._length},getDecimalForPixel:function(t){var e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0},_autoSkip:function(t){var e,n,i,a,r=this.options.ticks,o=this._length,s=r.maxTicksLimit||o/this._tickSize()+1,l=r.major.enabled?function(t){var e,n,i=[];for(e=0,n=t.length;es)return function(t,e,n){var i,a,r=0,o=e[0];for(n=Math.ceil(n),i=0;iu)return r;return Math.max(u,1)}(l,t,0,s),u>0){for(e=0,n=u-1;e1?(h-d)/(u-1):null,yn(t,i,B.isNullOrUndef(a)?0:d-a,d),yn(t,i,h,B.isNullOrUndef(a)?t.length:h+a),bn(t)}return yn(t,i),bn(t)},_tickSize:function(){var t=this.options.ticks,e=B.toRadians(this.labelRotation),n=Math.abs(Math.cos(e)),i=Math.abs(Math.sin(e)),a=this._getLabelSizes(),r=t.autoSkipPadding||0,o=a?a.widest.width+r:0,s=a?a.highest.height+r:0;return this.isHorizontal()?s*n>o*i?o/n:s/i:s*i=0&&(o=t),void 0!==r&&(t=n.indexOf(r))>=0&&(s=t),e.minIndex=o,e.maxIndex=s,e.min=n[o],e.max=n[s]},buildTicks:function(){var t=this._getLabels(),e=this.minIndex,n=this.maxIndex;this.ticks=0===e&&n===t.length-1?t:t.slice(e,n+1)},getLabelForIndex:function(t,e){var n=this.chart;return n.getDatasetMeta(e).controller._getValueScaleId()===this.id?this.getRightValue(n.data.datasets[e].data[t]):this._getLabels()[t]},_configure:function(){var t=this,e=t.options.offset,n=t.ticks;_n.prototype._configure.call(t),t.isHorizontal()||(t._reversePixels=!t._reversePixels),n&&(t._startValue=t.minIndex-(e?.5:0),t._valueRange=Math.max(n.length-(e?0:1),1))},getPixelForValue:function(t,e,n){var i,a,r,o=this;return wn(e)||wn(n)||(t=o.chart.data.datasets[n].data[e]),wn(t)||(i=o.isHorizontal()?t.x:t.y),(void 0!==i||void 0!==t&&isNaN(e))&&(a=o._getLabels(),t=B.valueOrDefault(i,t),e=-1!==(r=a.indexOf(t))?r:e,isNaN(e)&&(e=t)),o.getPixelForDecimal((e-o._startValue)/o._valueRange)},getPixelForTick:function(t){var e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t],t+this.minIndex)},getValueForPixel:function(t){var e=Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange);return Math.min(Math.max(e,0),this.ticks.length-1)},getBasePixel:function(){return this.bottom}}),Mn={position:"bottom"};kn._defaults=Mn;var Sn=B.noop,Dn=B.isNullOrUndef;var Cn=_n.extend({getRightValue:function(t){return"string"==typeof t?+t:_n.prototype.getRightValue.call(this,t)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var n=B.sign(t.min),i=B.sign(t.max);n<0&&i<0?t.max=0:n>0&&i>0&&(t.min=0)}var a=void 0!==e.min||void 0!==e.suggestedMin,r=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(null===t.min?t.min=e.suggestedMin:t.min=Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(null===t.max?t.max=e.suggestedMax:t.max=Math.max(t.max,e.suggestedMax)),a!==r&&t.min>=t.max&&(a?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:function(){var t,e=this.options.ticks,n=e.stepSize,i=e.maxTicksLimit;return n?t=Math.ceil(this.max/n)-Math.floor(this.min/n)+1:(t=this._computeTickLimit(),i=i||11),i&&(t=Math.min(i,t)),t},_computeTickLimit:function(){return Number.POSITIVE_INFINITY},handleDirectionalChanges:Sn,buildTicks:function(){var t=this,e=t.options.ticks,n=t.getTickLimit(),i={maxTicks:n=Math.max(2,n),min:e.min,max:e.max,precision:e.precision,stepSize:B.valueOrDefault(e.fixedStepSize,e.stepSize)},a=t.ticks=function(t,e){var n,i,a,r,o=[],s=t.stepSize,l=s||1,u=t.maxTicks-1,d=t.min,h=t.max,c=t.precision,f=e.min,g=e.max,m=B.niceNum((g-f)/u/l)*l;if(m<1e-14&&Dn(d)&&Dn(h))return[f,g];(r=Math.ceil(g/m)-Math.floor(f/m))>u&&(m=B.niceNum(r*m/u/l)*l),s||Dn(c)?n=Math.pow(10,B._decimalPlaces(m)):(n=Math.pow(10,c),m=Math.ceil(m*n)/n),i=Math.floor(f/m)*m,a=Math.ceil(g/m)*m,s&&(!Dn(d)&&B.almostWhole(d/m,m/1e3)&&(i=d),!Dn(h)&&B.almostWhole(h/m,m/1e3)&&(a=h)),r=(a-i)/m,r=B.almostEquals(r,Math.round(r),m/1e3)?Math.round(r):Math.ceil(r),i=Math.round(i*n)/n,a=Math.round(a*n)/n,o.push(Dn(d)?i:d);for(var p=1;pe.length-1?null:this.getPixelForValue(e[t])}}),Fn=Pn;An._defaults=Fn;var In=B.valueOrDefault,Ln=B.math.log10;var Rn={position:"left",ticks:{callback:sn.formatters.logarithmic}};function Nn(t,e){return B.isFinite(t)&&t>=0?t:e}var Wn=_n.extend({determineDataLimits:function(){var t,e,n,i,a,r,o=this,s=o.options,l=o.chart,u=l.data.datasets,d=o.isHorizontal();function h(t){return d?t.xAxisID===o.id:t.yAxisID===o.id}o.min=Number.POSITIVE_INFINITY,o.max=Number.NEGATIVE_INFINITY,o.minNotZero=Number.POSITIVE_INFINITY;var c=s.stacked;if(void 0===c)for(t=0;t0){var e=B.min(t),n=B.max(t);o.min=Math.min(o.min,e),o.max=Math.max(o.max,n)}}))}else for(t=0;t0?t.minNotZero=t.min:t.max<1?t.minNotZero=Math.pow(10,Math.floor(Ln(t.max))):t.minNotZero=1)},buildTicks:function(){var t=this,e=t.options.ticks,n=!t.isHorizontal(),i={min:Nn(e.min),max:Nn(e.max)},a=t.ticks=function(t,e){var n,i,a=[],r=In(t.min,Math.pow(10,Math.floor(Ln(e.min)))),o=Math.floor(Ln(e.max)),s=Math.ceil(e.max/Math.pow(10,o));0===r?(n=Math.floor(Ln(e.minNotZero)),i=Math.floor(e.minNotZero/Math.pow(10,n)),a.push(r),r=i*Math.pow(10,n)):(n=Math.floor(Ln(r)),i=Math.floor(r/Math.pow(10,n)));var l=n<0?Math.pow(10,Math.abs(n)):1;do{a.push(r),10===++i&&(i=1,l=++n>=0?1:l),r=Math.round(i*Math.pow(10,n)*l)/l}while(ne.length-1?null:this.getPixelForValue(e[t])},_getFirstTickValue:function(t){var e=Math.floor(Ln(t));return Math.floor(t/Math.pow(10,e))*Math.pow(10,e)},_configure:function(){var t=this,e=t.min,n=0;_n.prototype._configure.call(t),0===e&&(e=t._getFirstTickValue(t.minNotZero),n=In(t.options.ticks.fontSize,Y.global.defaultFontSize)/t._length),t._startValue=Ln(e),t._valueOffset=n,t._valueRange=(Ln(t.max)-Ln(e))/(1-n)},getPixelForValue:function(t){var e=this,n=0;return(t=+e.getRightValue(t))>e.min&&t>0&&(n=(Ln(t)-e._startValue)/e._valueRange+e._valueOffset),e.getPixelForDecimal(n)},getValueForPixel:function(t){var e=this,n=e.getDecimalForPixel(t);return 0===n&&0===e.min?0:Math.pow(10,e._startValue+(n-e._valueOffset)*e._valueRange)}}),Yn=Rn;Wn._defaults=Yn;var zn=B.valueOrDefault,En=B.valueAtIndexOrDefault,Vn=B.options.resolve,Hn={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0,0,0,0.1)",lineWidth:1,borderDash:[],borderDashOffset:0},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:sn.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}};function Bn(t){var e=t.ticks;return e.display&&t.display?zn(e.fontSize,Y.global.defaultFontSize)+2*e.backdropPaddingY:0}function jn(t,e,n,i,a){return t===i||t===a?{start:e-n/2,end:e+n/2}:ta?{start:e-n,end:e}:{start:e,end:e+n}}function Un(t){return 0===t||180===t?"center":t<180?"left":"right"}function Gn(t,e,n,i){var a,r,o=n.y+i/2;if(B.isArray(e))for(a=0,r=e.length;a270||t<90)&&(n.y-=e.h)}function Zn(t){return B.isNumber(t)?t:0}var $n=Cn.extend({setDimensions:function(){var t=this;t.width=t.maxWidth,t.height=t.maxHeight,t.paddingTop=Bn(t.options)/2,t.xCenter=Math.floor(t.width/2),t.yCenter=Math.floor((t.height-t.paddingTop)/2),t.drawingArea=Math.min(t.height-t.paddingTop,t.width)/2},determineDataLimits:function(){var t=this,e=t.chart,n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;B.each(e.data.datasets,(function(a,r){if(e.isDatasetVisible(r)){var o=e.getDatasetMeta(r);B.each(a.data,(function(e,a){var r=+t.getRightValue(e);isNaN(r)||o.data[a].hidden||(n=Math.min(r,n),i=Math.max(r,i))}))}})),t.min=n===Number.POSITIVE_INFINITY?0:n,t.max=i===Number.NEGATIVE_INFINITY?0:i,t.handleTickRangeOptions()},_computeTickLimit:function(){return Math.ceil(this.drawingArea/Bn(this.options))},convertTicksToLabels:function(){var t=this;Cn.prototype.convertTicksToLabels.call(t),t.pointLabels=t.chart.data.labels.map((function(){var e=B.callback(t.options.pointLabels.callback,arguments,t);return e||0===e?e:""}))},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t=this.options;t.display&&t.pointLabels.display?function(t){var e,n,i,a=B.options._parseFont(t.options.pointLabels),r={l:0,r:t.width,t:0,b:t.height-t.paddingTop},o={};t.ctx.font=a.string,t._pointLabelSizes=[];var s,l,u,d=t.chart.data.labels.length;for(e=0;er.r&&(r.r=f.end,o.r=h),g.startr.b&&(r.b=g.end,o.b=h)}t.setReductions(t.drawingArea,r,o)}(this):this.setCenterPoint(0,0,0,0)},setReductions:function(t,e,n){var i=this,a=e.l/Math.sin(n.l),r=Math.max(e.r-i.width,0)/Math.sin(n.r),o=-e.t/Math.cos(n.t),s=-Math.max(e.b-(i.height-i.paddingTop),0)/Math.cos(n.b);a=Zn(a),r=Zn(r),o=Zn(o),s=Zn(s),i.drawingArea=Math.min(Math.floor(t-(a+r)/2),Math.floor(t-(o+s)/2)),i.setCenterPoint(a,r,o,s)},setCenterPoint:function(t,e,n,i){var a=this,r=a.width-e-a.drawingArea,o=t+a.drawingArea,s=n+a.drawingArea,l=a.height-a.paddingTop-i-a.drawingArea;a.xCenter=Math.floor((o+r)/2+a.left),a.yCenter=Math.floor((s+l)/2+a.top+a.paddingTop)},getIndexAngle:function(t){var e=this.chart,n=(t*(360/e.data.labels.length)+((e.options||{}).startAngle||0))%360;return(n<0?n+360:n)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(B.isNullOrUndef(t))return NaN;var n=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*n:(t-e.min)*n},getPointPosition:function(t,e){var n=this.getIndexAngle(t)-Math.PI/2;return{x:Math.cos(n)*e+this.xCenter,y:Math.sin(n)*e+this.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(t){var e=this.min,n=this.max;return this.getPointPositionForValue(t||0,this.beginAtZero?0:e<0&&n<0?n:e>0&&n>0?e:0)},_drawGrid:function(){var t,e,n,i=this,a=i.ctx,r=i.options,o=r.gridLines,s=r.angleLines,l=zn(s.lineWidth,o.lineWidth),u=zn(s.color,o.color);if(r.pointLabels.display&&function(t){var e=t.ctx,n=t.options,i=n.pointLabels,a=Bn(n),r=t.getDistanceFromCenterForValue(n.ticks.reverse?t.min:t.max),o=B.options._parseFont(i);e.save(),e.font=o.string,e.textBaseline="middle";for(var s=t.chart.data.labels.length-1;s>=0;s--){var l=0===s?a/2:0,u=t.getPointPosition(s,r+l+5),d=En(i.fontColor,s,Y.global.defaultFontColor);e.fillStyle=d;var h=t.getIndexAngle(s),c=B.toDegrees(h);e.textAlign=Un(c),qn(c,t._pointLabelSizes[s],u),Gn(e,t.pointLabels[s],u,o.lineHeight)}e.restore()}(i),o.display&&B.each(i.ticks,(function(t,n){0!==n&&(e=i.getDistanceFromCenterForValue(i.ticksAsNumbers[n]),function(t,e,n,i){var a,r=t.ctx,o=e.circular,s=t.chart.data.labels.length,l=En(e.color,i-1),u=En(e.lineWidth,i-1);if((o||s)&&l&&u){if(r.save(),r.strokeStyle=l,r.lineWidth=u,r.setLineDash&&(r.setLineDash(e.borderDash||[]),r.lineDashOffset=e.borderDashOffset||0),r.beginPath(),o)r.arc(t.xCenter,t.yCenter,n,0,2*Math.PI);else{a=t.getPointPosition(0,n),r.moveTo(a.x,a.y);for(var d=1;d=0;t--)e=i.getDistanceFromCenterForValue(r.ticks.reverse?i.min:i.max),n=i.getPointPosition(t,e),a.beginPath(),a.moveTo(i.xCenter,i.yCenter),a.lineTo(n.x,n.y),a.stroke();a.restore()}},_drawLabels:function(){var t=this,e=t.ctx,n=t.options.ticks;if(n.display){var i,a,r=t.getIndexAngle(0),o=B.options._parseFont(n),s=zn(n.fontColor,Y.global.defaultFontColor);e.save(),e.font=o.string,e.translate(t.xCenter,t.yCenter),e.rotate(r),e.textAlign="center",e.textBaseline="middle",B.each(t.ticks,(function(r,l){(0!==l||n.reverse)&&(i=t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]),n.showLabelBackdrop&&(a=e.measureText(r).width,e.fillStyle=n.backdropColor,e.fillRect(-a/2-n.backdropPaddingX,-i-o.size/2-n.backdropPaddingY,a+2*n.backdropPaddingX,o.size+2*n.backdropPaddingY)),e.fillStyle=s,e.fillText(r,0,-i))})),e.restore()}},_drawTitle:B.noop}),Xn=Hn;$n._defaults=Xn;var Kn=B._deprecated,Jn=B.options.resolve,Qn=B.valueOrDefault,ti=Number.MIN_SAFE_INTEGER||-9007199254740991,ei=Number.MAX_SAFE_INTEGER||9007199254740991,ni={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},ii=Object.keys(ni);function ai(t,e){return t-e}function ri(t){return B.valueOrDefault(t.time.min,t.ticks.min)}function oi(t){return B.valueOrDefault(t.time.max,t.ticks.max)}function si(t,e,n,i){var a=function(t,e,n){for(var i,a,r,o=0,s=t.length-1;o>=0&&o<=s;){if(a=t[(i=o+s>>1)-1]||null,r=t[i],!a)return{lo:null,hi:r};if(r[e]n))return{lo:a,hi:r};s=i-1}}return{lo:r,hi:null}}(t,e,n),r=a.lo?a.hi?a.lo:t[t.length-2]:t[0],o=a.lo?a.hi?a.hi:t[t.length-1]:t[1],s=o[e]-r[e],l=s?(n-r[e])/s:0,u=(o[i]-r[i])*l;return r[i]+u}function li(t,e){var n=t._adapter,i=t.options.time,a=i.parser,r=a||i.format,o=e;return"function"==typeof a&&(o=a(o)),B.isFinite(o)||(o="string"==typeof r?n.parse(o,r):n.parse(o)),null!==o?+o:(a||"function"!=typeof r||(o=r(e),B.isFinite(o)||(o=n.parse(o))),o)}function ui(t,e){if(B.isNullOrUndef(e))return null;var n=t.options.time,i=li(t,t.getRightValue(e));return null===i?i:(n.round&&(i=+t._adapter.startOf(i,n.round)),i)}function di(t,e,n,i){var a,r,o,s=ii.length;for(a=ii.indexOf(t);a=0&&(e[r].major=!0);return e}(t,r,o,n):r}var ci=_n.extend({initialize:function(){this.mergeTicksOptions(),_n.prototype.initialize.call(this)},update:function(){var t=this,e=t.options,n=e.time||(e.time={}),i=t._adapter=new on._date(e.adapters.date);return Kn("time scale",n.format,"time.format","time.parser"),Kn("time scale",n.min,"time.min","ticks.min"),Kn("time scale",n.max,"time.max","ticks.max"),B.mergeIf(n.displayFormats,i.formats()),_n.prototype.update.apply(t,arguments)},getRightValue:function(t){return t&&void 0!==t.t&&(t=t.t),_n.prototype.getRightValue.call(this,t)},determineDataLimits:function(){var t,e,n,i,a,r,o,s=this,l=s.chart,u=s._adapter,d=s.options,h=d.time.unit||"day",c=ei,f=ti,g=[],m=[],p=[],v=s._getLabels();for(t=0,n=v.length;t1?function(t){var e,n,i,a={},r=[];for(e=0,n=t.length;e1e5*u)throw e+" and "+n+" are too far apart with stepSize of "+u+" "+l;for(a=h;a=a&&n<=r&&d.push(n);return i.min=a,i.max=r,i._unit=l.unit||(s.autoSkip?di(l.minUnit,i.min,i.max,h):function(t,e,n,i,a){var r,o;for(r=ii.length-1;r>=ii.indexOf(n);r--)if(o=ii[r],ni[o].common&&t._adapter.diff(a,i,o)>=e-1)return o;return ii[n?ii.indexOf(n):0]}(i,d.length,l.minUnit,i.min,i.max)),i._majorUnit=s.major.enabled&&"year"!==i._unit?function(t){for(var e=ii.indexOf(t)+1,n=ii.length;ee&&s=0&&t0?s:1}}),fi={position:"bottom",distribution:"linear",bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}};ci._defaults=fi;var gi={category:kn,linear:An,logarithmic:Wn,radialLinear:$n,time:ci},mi=e((function(e,n){e.exports=function(){var n,i;function a(){return n.apply(null,arguments)}function r(t){return t instanceof Array||"[object Array]"===Object.prototype.toString.call(t)}function o(t){return null!=t&&"[object Object]"===Object.prototype.toString.call(t)}function s(t){return void 0===t}function l(t){return"number"==typeof t||"[object Number]"===Object.prototype.toString.call(t)}function u(t){return t instanceof Date||"[object Date]"===Object.prototype.toString.call(t)}function d(t,e){var n,i=[];for(n=0;n>>0,i=0;i0)for(n=0;n=0?n?"+":"":"-")+Math.pow(10,Math.max(0,a)).toString().substr(1)+i}var E=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,V=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,H={},B={};function j(t,e,n,i){var a=i;"string"==typeof i&&(a=function(){return this[i]()}),t&&(B[t]=a),e&&(B[e[0]]=function(){return z(a.apply(this,arguments),e[1],e[2])}),n&&(B[n]=function(){return this.localeData().ordinal(a.apply(this,arguments),t)})}function U(t,e){return t.isValid()?(e=G(e,t.localeData()),H[e]=H[e]||function(t){var e,n,i,a=t.match(E);for(e=0,n=a.length;e=0&&V.test(t);)t=t.replace(V,i),V.lastIndex=0,n-=1;return t}var q=/\d/,Z=/\d\d/,$=/\d{3}/,X=/\d{4}/,K=/[+-]?\d{6}/,J=/\d\d?/,Q=/\d\d\d\d?/,tt=/\d\d\d\d\d\d?/,et=/\d{1,3}/,nt=/\d{1,4}/,it=/[+-]?\d{1,6}/,at=/\d+/,rt=/[+-]?\d+/,ot=/Z|[+-]\d\d:?\d\d/gi,st=/Z|[+-]\d\d(?::?\d\d)?/gi,lt=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,ut={};function dt(t,e,n){ut[t]=O(e)?e:function(t,i){return t&&n?n:e}}function ht(t,e){return h(ut,t)?ut[t](e._strict,e._locale):new RegExp(ct(t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,(function(t,e,n,i,a){return e||n||i||a}))))}function ct(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var ft={};function gt(t,e){var n,i=e;for("string"==typeof t&&(t=[t]),l(e)&&(i=function(t,n){n[e]=k(t)}),n=0;n68?1900:2e3)};var Pt,Tt=Ot("FullYear",!0);function Ot(t,e){return function(n){return null!=n?(Ft(this,t,n),a.updateOffset(this,e),this):At(this,t)}}function At(t,e){return t.isValid()?t._d["get"+(t._isUTC?"UTC":"")+e]():NaN}function Ft(t,e,n){t.isValid()&&!isNaN(n)&&("FullYear"===e&&Ct(t.year())&&1===t.month()&&29===t.date()?t._d["set"+(t._isUTC?"UTC":"")+e](n,t.month(),It(n,t.month())):t._d["set"+(t._isUTC?"UTC":"")+e](n))}function It(t,e){if(isNaN(t)||isNaN(e))return NaN;var n=function(t,e){return(t%e+e)%e}(e,12);return t+=(e-n)/12,1===n?Ct(t)?29:28:31-n%7%2}Pt=Array.prototype.indexOf?Array.prototype.indexOf:function(t){var e;for(e=0;e=0?(s=new Date(t+400,e,n,i,a,r,o),isFinite(s.getFullYear())&&s.setFullYear(t)):s=new Date(t,e,n,i,a,r,o),s}function jt(t){var e;if(t<100&&t>=0){var n=Array.prototype.slice.call(arguments);n[0]=t+400,e=new Date(Date.UTC.apply(null,n)),isFinite(e.getUTCFullYear())&&e.setUTCFullYear(t)}else e=new Date(Date.UTC.apply(null,arguments));return e}function Ut(t,e,n){var i=7+e-n;return-(7+jt(t,0,i).getUTCDay()-e)%7+i-1}function Gt(t,e,n,i,a){var r,o,s=1+7*(e-1)+(7+n-i)%7+Ut(t,i,a);return s<=0?o=Dt(r=t-1)+s:s>Dt(t)?(r=t+1,o=s-Dt(t)):(r=t,o=s),{year:r,dayOfYear:o}}function qt(t,e,n){var i,a,r=Ut(t.year(),e,n),o=Math.floor((t.dayOfYear()-r-1)/7)+1;return o<1?i=o+Zt(a=t.year()-1,e,n):o>Zt(t.year(),e,n)?(i=o-Zt(t.year(),e,n),a=t.year()+1):(a=t.year(),i=o),{week:i,year:a}}function Zt(t,e,n){var i=Ut(t,e,n),a=Ut(t+1,e,n);return(Dt(t)-i+a)/7}function $t(t,e){return t.slice(e,7).concat(t.slice(0,e))}j("w",["ww",2],"wo","week"),j("W",["WW",2],"Wo","isoWeek"),L("week","w"),L("isoWeek","W"),Y("week",5),Y("isoWeek",5),dt("w",J),dt("ww",J,Z),dt("W",J),dt("WW",J,Z),mt(["w","ww","W","WW"],(function(t,e,n,i){e[i.substr(0,1)]=k(t)})),j("d",0,"do","day"),j("dd",0,0,(function(t){return this.localeData().weekdaysMin(this,t)})),j("ddd",0,0,(function(t){return this.localeData().weekdaysShort(this,t)})),j("dddd",0,0,(function(t){return this.localeData().weekdays(this,t)})),j("e",0,0,"weekday"),j("E",0,0,"isoWeekday"),L("day","d"),L("weekday","e"),L("isoWeekday","E"),Y("day",11),Y("weekday",11),Y("isoWeekday",11),dt("d",J),dt("e",J),dt("E",J),dt("dd",(function(t,e){return e.weekdaysMinRegex(t)})),dt("ddd",(function(t,e){return e.weekdaysShortRegex(t)})),dt("dddd",(function(t,e){return e.weekdaysRegex(t)})),mt(["dd","ddd","dddd"],(function(t,e,n,i){var a=n._locale.weekdaysParse(t,i,n._strict);null!=a?e.d=a:g(n).invalidWeekday=t})),mt(["d","e","E"],(function(t,e,n,i){e[i]=k(t)}));var Xt="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Kt="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Jt="Su_Mo_Tu_We_Th_Fr_Sa".split("_");function Qt(t,e,n){var i,a,r,o=t.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],i=0;i<7;++i)r=f([2e3,1]).day(i),this._minWeekdaysParse[i]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[i]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[i]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===e?-1!==(a=Pt.call(this._weekdaysParse,o))?a:null:"ddd"===e?-1!==(a=Pt.call(this._shortWeekdaysParse,o))?a:null:-1!==(a=Pt.call(this._minWeekdaysParse,o))?a:null:"dddd"===e?-1!==(a=Pt.call(this._weekdaysParse,o))?a:-1!==(a=Pt.call(this._shortWeekdaysParse,o))?a:-1!==(a=Pt.call(this._minWeekdaysParse,o))?a:null:"ddd"===e?-1!==(a=Pt.call(this._shortWeekdaysParse,o))?a:-1!==(a=Pt.call(this._weekdaysParse,o))?a:-1!==(a=Pt.call(this._minWeekdaysParse,o))?a:null:-1!==(a=Pt.call(this._minWeekdaysParse,o))?a:-1!==(a=Pt.call(this._weekdaysParse,o))?a:-1!==(a=Pt.call(this._shortWeekdaysParse,o))?a:null}var te=lt,ee=lt,ne=lt;function ie(){function t(t,e){return e.length-t.length}var e,n,i,a,r,o=[],s=[],l=[],u=[];for(e=0;e<7;e++)n=f([2e3,1]).day(e),i=this.weekdaysMin(n,""),a=this.weekdaysShort(n,""),r=this.weekdays(n,""),o.push(i),s.push(a),l.push(r),u.push(i),u.push(a),u.push(r);for(o.sort(t),s.sort(t),l.sort(t),u.sort(t),e=0;e<7;e++)s[e]=ct(s[e]),l[e]=ct(l[e]),u[e]=ct(u[e]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function ae(){return this.hours()%12||12}function re(t,e){j(t,0,0,(function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)}))}function oe(t,e){return e._meridiemParse}j("H",["HH",2],0,"hour"),j("h",["hh",2],0,ae),j("k",["kk",2],0,(function(){return this.hours()||24})),j("hmm",0,0,(function(){return""+ae.apply(this)+z(this.minutes(),2)})),j("hmmss",0,0,(function(){return""+ae.apply(this)+z(this.minutes(),2)+z(this.seconds(),2)})),j("Hmm",0,0,(function(){return""+this.hours()+z(this.minutes(),2)})),j("Hmmss",0,0,(function(){return""+this.hours()+z(this.minutes(),2)+z(this.seconds(),2)})),re("a",!0),re("A",!1),L("hour","h"),Y("hour",13),dt("a",oe),dt("A",oe),dt("H",J),dt("h",J),dt("k",J),dt("HH",J,Z),dt("hh",J,Z),dt("kk",J,Z),dt("hmm",Q),dt("hmmss",tt),dt("Hmm",Q),dt("Hmmss",tt),gt(["H","HH"],xt),gt(["k","kk"],(function(t,e,n){var i=k(t);e[xt]=24===i?0:i})),gt(["a","A"],(function(t,e,n){n._isPm=n._locale.isPM(t),n._meridiem=t})),gt(["h","hh"],(function(t,e,n){e[xt]=k(t),g(n).bigHour=!0})),gt("hmm",(function(t,e,n){var i=t.length-2;e[xt]=k(t.substr(0,i)),e[_t]=k(t.substr(i)),g(n).bigHour=!0})),gt("hmmss",(function(t,e,n){var i=t.length-4,a=t.length-2;e[xt]=k(t.substr(0,i)),e[_t]=k(t.substr(i,2)),e[wt]=k(t.substr(a)),g(n).bigHour=!0})),gt("Hmm",(function(t,e,n){var i=t.length-2;e[xt]=k(t.substr(0,i)),e[_t]=k(t.substr(i))})),gt("Hmmss",(function(t,e,n){var i=t.length-4,a=t.length-2;e[xt]=k(t.substr(0,i)),e[_t]=k(t.substr(i,2)),e[wt]=k(t.substr(a))}));var se,le=Ot("Hours",!0),ue={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Rt,monthsShort:Nt,week:{dow:0,doy:6},weekdays:Xt,weekdaysMin:Jt,weekdaysShort:Kt,meridiemParse:/[ap]\.?m?\.?/i},de={},he={};function ce(t){return t?t.toLowerCase().replace("_","-"):t}function fe(n){var i=null;if(!de[n]&&e&&e.exports)try{i=se._abbr,t(),ge(i)}catch(t){}return de[n]}function ge(t,e){var n;return t&&((n=s(e)?pe(t):me(t,e))?se=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+t+" not found. Did you forget to load it?")),se._abbr}function me(t,e){if(null!==e){var n,i=ue;if(e.abbr=t,null!=de[t])T("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=de[t]._config;else if(null!=e.parentLocale)if(null!=de[e.parentLocale])i=de[e.parentLocale]._config;else{if(null==(n=fe(e.parentLocale)))return he[e.parentLocale]||(he[e.parentLocale]=[]),he[e.parentLocale].push({name:t,config:e}),null;i=n._config}return de[t]=new F(A(i,e)),he[t]&&he[t].forEach((function(t){me(t.name,t.config)})),ge(t),de[t]}return delete de[t],null}function pe(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return se;if(!r(t)){if(e=fe(t))return e;t=[t]}return function(t){for(var e,n,i,a,r=0;r0;){if(i=fe(a.slice(0,e).join("-")))return i;if(n&&n.length>=e&&M(a,n,!0)>=e-1)break;e--}r++}return se}(t)}function ve(t){var e,n=t._a;return n&&-2===g(t).overflow&&(e=n[bt]<0||n[bt]>11?bt:n[yt]<1||n[yt]>It(n[vt],n[bt])?yt:n[xt]<0||n[xt]>24||24===n[xt]&&(0!==n[_t]||0!==n[wt]||0!==n[kt])?xt:n[_t]<0||n[_t]>59?_t:n[wt]<0||n[wt]>59?wt:n[kt]<0||n[kt]>999?kt:-1,g(t)._overflowDayOfYear&&(eyt)&&(e=yt),g(t)._overflowWeeks&&-1===e&&(e=Mt),g(t)._overflowWeekday&&-1===e&&(e=St),g(t).overflow=e),t}function be(t,e,n){return null!=t?t:null!=e?e:n}function ye(t){var e,n,i,r,o,s=[];if(!t._d){for(i=function(t){var e=new Date(a.now());return t._useUTC?[e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()]:[e.getFullYear(),e.getMonth(),e.getDate()]}(t),t._w&&null==t._a[yt]&&null==t._a[bt]&&function(t){var e,n,i,a,r,o,s,l;if(null!=(e=t._w).GG||null!=e.W||null!=e.E)r=1,o=4,n=be(e.GG,t._a[vt],qt(Le(),1,4).year),i=be(e.W,1),((a=be(e.E,1))<1||a>7)&&(l=!0);else{r=t._locale._week.dow,o=t._locale._week.doy;var u=qt(Le(),r,o);n=be(e.gg,t._a[vt],u.year),i=be(e.w,u.week),null!=e.d?((a=e.d)<0||a>6)&&(l=!0):null!=e.e?(a=e.e+r,(e.e<0||e.e>6)&&(l=!0)):a=r}i<1||i>Zt(n,r,o)?g(t)._overflowWeeks=!0:null!=l?g(t)._overflowWeekday=!0:(s=Gt(n,i,a,r,o),t._a[vt]=s.year,t._dayOfYear=s.dayOfYear)}(t),null!=t._dayOfYear&&(o=be(t._a[vt],i[vt]),(t._dayOfYear>Dt(o)||0===t._dayOfYear)&&(g(t)._overflowDayOfYear=!0),n=jt(o,0,t._dayOfYear),t._a[bt]=n.getUTCMonth(),t._a[yt]=n.getUTCDate()),e=0;e<3&&null==t._a[e];++e)t._a[e]=s[e]=i[e];for(;e<7;e++)t._a[e]=s[e]=null==t._a[e]?2===e?1:0:t._a[e];24===t._a[xt]&&0===t._a[_t]&&0===t._a[wt]&&0===t._a[kt]&&(t._nextDay=!0,t._a[xt]=0),t._d=(t._useUTC?jt:Bt).apply(null,s),r=t._useUTC?t._d.getUTCDay():t._d.getDay(),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[xt]=24),t._w&&void 0!==t._w.d&&t._w.d!==r&&(g(t).weekdayMismatch=!0)}}var xe=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,_e=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,we=/Z|[+-]\d\d(?::?\d\d)?/,ke=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Me=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Se=/^\/?Date\((\-?\d+)/i;function De(t){var e,n,i,a,r,o,s=t._i,l=xe.exec(s)||_e.exec(s);if(l){for(g(t).iso=!0,e=0,n=ke.length;e0&&g(t).unusedInput.push(o),s=s.slice(s.indexOf(n)+n.length),u+=n.length),B[r]?(n?g(t).empty=!1:g(t).unusedTokens.push(r),pt(r,n,t)):t._strict&&!n&&g(t).unusedTokens.push(r);g(t).charsLeftOver=l-u,s.length>0&&g(t).unusedInput.push(s),t._a[xt]<=12&&!0===g(t).bigHour&&t._a[xt]>0&&(g(t).bigHour=void 0),g(t).parsedDateParts=t._a.slice(0),g(t).meridiem=t._meridiem,t._a[xt]=function(t,e,n){var i;return null==n?e:null!=t.meridiemHour?t.meridiemHour(e,n):null!=t.isPM?((i=t.isPM(n))&&e<12&&(e+=12),i||12!==e||(e=0),e):e}(t._locale,t._a[xt],t._meridiem),ye(t),ve(t)}else Oe(t);else De(t)}function Fe(t){var e=t._i,n=t._f;return t._locale=t._locale||pe(t._l),null===e||void 0===n&&""===e?p({nullInput:!0}):("string"==typeof e&&(t._i=e=t._locale.preparse(e)),_(e)?new x(ve(e)):(u(e)?t._d=e:r(n)?function(t){var e,n,i,a,r;if(0===t._f.length)return g(t).invalidFormat=!0,void(t._d=new Date(NaN));for(a=0;athis?this:t:p()}));function We(t,e){var n,i;if(1===e.length&&r(e[0])&&(e=e[0]),!e.length)return Le();for(n=e[0],i=1;i=0?new Date(t+400,e,n)-hn:new Date(t,e,n).valueOf()}function gn(t,e,n){return t<100&&t>=0?Date.UTC(t+400,e,n)-hn:Date.UTC(t,e,n)}function mn(t,e){j(0,[t,t.length],0,e)}function pn(t,e,n,i,a){var r;return null==t?qt(this,i,a).year:(e>(r=Zt(t,i,a))&&(e=r),vn.call(this,t,e,n,i,a))}function vn(t,e,n,i,a){var r=Gt(t,e,n,i,a),o=jt(r.year,0,r.dayOfYear);return this.year(o.getUTCFullYear()),this.month(o.getUTCMonth()),this.date(o.getUTCDate()),this}j(0,["gg",2],0,(function(){return this.weekYear()%100})),j(0,["GG",2],0,(function(){return this.isoWeekYear()%100})),mn("gggg","weekYear"),mn("ggggg","weekYear"),mn("GGGG","isoWeekYear"),mn("GGGGG","isoWeekYear"),L("weekYear","gg"),L("isoWeekYear","GG"),Y("weekYear",1),Y("isoWeekYear",1),dt("G",rt),dt("g",rt),dt("GG",J,Z),dt("gg",J,Z),dt("GGGG",nt,X),dt("gggg",nt,X),dt("GGGGG",it,K),dt("ggggg",it,K),mt(["gggg","ggggg","GGGG","GGGGG"],(function(t,e,n,i){e[i.substr(0,2)]=k(t)})),mt(["gg","GG"],(function(t,e,n,i){e[i]=a.parseTwoDigitYear(t)})),j("Q",0,"Qo","quarter"),L("quarter","Q"),Y("quarter",7),dt("Q",q),gt("Q",(function(t,e){e[bt]=3*(k(t)-1)})),j("D",["DD",2],"Do","date"),L("date","D"),Y("date",9),dt("D",J),dt("DD",J,Z),dt("Do",(function(t,e){return t?e._dayOfMonthOrdinalParse||e._ordinalParse:e._dayOfMonthOrdinalParseLenient})),gt(["D","DD"],yt),gt("Do",(function(t,e){e[yt]=k(t.match(J)[0])}));var bn=Ot("Date",!0);j("DDD",["DDDD",3],"DDDo","dayOfYear"),L("dayOfYear","DDD"),Y("dayOfYear",4),dt("DDD",et),dt("DDDD",$),gt(["DDD","DDDD"],(function(t,e,n){n._dayOfYear=k(t)})),j("m",["mm",2],0,"minute"),L("minute","m"),Y("minute",14),dt("m",J),dt("mm",J,Z),gt(["m","mm"],_t);var yn=Ot("Minutes",!1);j("s",["ss",2],0,"second"),L("second","s"),Y("second",15),dt("s",J),dt("ss",J,Z),gt(["s","ss"],wt);var xn,_n=Ot("Seconds",!1);for(j("S",0,0,(function(){return~~(this.millisecond()/100)})),j(0,["SS",2],0,(function(){return~~(this.millisecond()/10)})),j(0,["SSS",3],0,"millisecond"),j(0,["SSSS",4],0,(function(){return 10*this.millisecond()})),j(0,["SSSSS",5],0,(function(){return 100*this.millisecond()})),j(0,["SSSSSS",6],0,(function(){return 1e3*this.millisecond()})),j(0,["SSSSSSS",7],0,(function(){return 1e4*this.millisecond()})),j(0,["SSSSSSSS",8],0,(function(){return 1e5*this.millisecond()})),j(0,["SSSSSSSSS",9],0,(function(){return 1e6*this.millisecond()})),L("millisecond","ms"),Y("millisecond",16),dt("S",et,q),dt("SS",et,Z),dt("SSS",et,$),xn="SSSS";xn.length<=9;xn+="S")dt(xn,at);function wn(t,e){e[kt]=k(1e3*("0."+t))}for(xn="S";xn.length<=9;xn+="S")gt(xn,wn);var kn=Ot("Milliseconds",!1);j("z",0,0,"zoneAbbr"),j("zz",0,0,"zoneName");var Mn=x.prototype;function Sn(t){return t}Mn.add=en,Mn.calendar=function(t,e){var n=t||Le(),i=Ue(n,this).startOf("day"),r=a.calendarFormat(this,i)||"sameElse",o=e&&(O(e[r])?e[r].call(this,n):e[r]);return this.format(o||this.localeData().calendar(r,this,Le(n)))},Mn.clone=function(){return new x(this)},Mn.diff=function(t,e,n){var i,a,r;if(!this.isValid())return NaN;if(!(i=Ue(t,this)).isValid())return NaN;switch(a=6e4*(i.utcOffset()-this.utcOffset()),e=R(e)){case"year":r=an(this,i)/12;break;case"month":r=an(this,i);break;case"quarter":r=an(this,i)/3;break;case"second":r=(this-i)/1e3;break;case"minute":r=(this-i)/6e4;break;case"hour":r=(this-i)/36e5;break;case"day":r=(this-i-a)/864e5;break;case"week":r=(this-i-a)/6048e5;break;default:r=this-i}return n?r:w(r)},Mn.endOf=function(t){var e;if(void 0===(t=R(t))||"millisecond"===t||!this.isValid())return this;var n=this._isUTC?gn:fn;switch(t){case"year":e=n(this.year()+1,0,1)-1;break;case"quarter":e=n(this.year(),this.month()-this.month()%3+3,1)-1;break;case"month":e=n(this.year(),this.month()+1,1)-1;break;case"week":e=n(this.year(),this.month(),this.date()-this.weekday()+7)-1;break;case"isoWeek":e=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1)+7)-1;break;case"day":case"date":e=n(this.year(),this.month(),this.date()+1)-1;break;case"hour":e=this._d.valueOf(),e+=dn-cn(e+(this._isUTC?0:this.utcOffset()*un),dn)-1;break;case"minute":e=this._d.valueOf(),e+=un-cn(e,un)-1;break;case"second":e=this._d.valueOf(),e+=ln-cn(e,ln)-1}return this._d.setTime(e),a.updateOffset(this,!0),this},Mn.format=function(t){t||(t=this.isUtc()?a.defaultFormatUtc:a.defaultFormat);var e=U(this,t);return this.localeData().postformat(e)},Mn.from=function(t,e){return this.isValid()&&(_(t)&&t.isValid()||Le(t).isValid())?Xe({to:this,from:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()},Mn.fromNow=function(t){return this.from(Le(),t)},Mn.to=function(t,e){return this.isValid()&&(_(t)&&t.isValid()||Le(t).isValid())?Xe({from:this,to:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()},Mn.toNow=function(t){return this.to(Le(),t)},Mn.get=function(t){return O(this[t=R(t)])?this[t]():this},Mn.invalidAt=function(){return g(this).overflow},Mn.isAfter=function(t,e){var n=_(t)?t:Le(t);return!(!this.isValid()||!n.isValid())&&("millisecond"===(e=R(e)||"millisecond")?this.valueOf()>n.valueOf():n.valueOf()9999?U(n,e?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):O(Date.prototype.toISOString)?e?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",U(n,"Z")):U(n,e?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},Mn.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var t="moment",e="";this.isLocal()||(t=0===this.utcOffset()?"moment.utc":"moment.parseZone",e="Z");var n="["+t+'("]',i=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",a=e+'[")]';return this.format(n+i+"-MM-DD[T]HH:mm:ss.SSS"+a)},Mn.toJSON=function(){return this.isValid()?this.toISOString():null},Mn.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},Mn.unix=function(){return Math.floor(this.valueOf()/1e3)},Mn.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},Mn.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},Mn.year=Tt,Mn.isLeapYear=function(){return Ct(this.year())},Mn.weekYear=function(t){return pn.call(this,t,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},Mn.isoWeekYear=function(t){return pn.call(this,t,this.isoWeek(),this.isoWeekday(),1,4)},Mn.quarter=Mn.quarters=function(t){return null==t?Math.ceil((this.month()+1)/3):this.month(3*(t-1)+this.month()%3)},Mn.month=zt,Mn.daysInMonth=function(){return It(this.year(),this.month())},Mn.week=Mn.weeks=function(t){var e=this.localeData().week(this);return null==t?e:this.add(7*(t-e),"d")},Mn.isoWeek=Mn.isoWeeks=function(t){var e=qt(this,1,4).week;return null==t?e:this.add(7*(t-e),"d")},Mn.weeksInYear=function(){var t=this.localeData()._week;return Zt(this.year(),t.dow,t.doy)},Mn.isoWeeksInYear=function(){return Zt(this.year(),1,4)},Mn.date=bn,Mn.day=Mn.days=function(t){if(!this.isValid())return null!=t?this:NaN;var e=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=t?(t=function(t,e){return"string"!=typeof t?t:isNaN(t)?"number"==typeof(t=e.weekdaysParse(t))?t:null:parseInt(t,10)}(t,this.localeData()),this.add(t-e,"d")):e},Mn.weekday=function(t){if(!this.isValid())return null!=t?this:NaN;var e=(this.day()+7-this.localeData()._week.dow)%7;return null==t?e:this.add(t-e,"d")},Mn.isoWeekday=function(t){if(!this.isValid())return null!=t?this:NaN;if(null!=t){var e=function(t,e){return"string"==typeof t?e.weekdaysParse(t)%7||7:isNaN(t)?null:t}(t,this.localeData());return this.day(this.day()%7?e:e-7)}return this.day()||7},Mn.dayOfYear=function(t){var e=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==t?e:this.add(t-e,"d")},Mn.hour=Mn.hours=le,Mn.minute=Mn.minutes=yn,Mn.second=Mn.seconds=_n,Mn.millisecond=Mn.milliseconds=kn,Mn.utcOffset=function(t,e,n){var i,r=this._offset||0;if(!this.isValid())return null!=t?this:NaN;if(null!=t){if("string"==typeof t){if(null===(t=je(st,t)))return this}else Math.abs(t)<16&&!n&&(t*=60);return!this._isUTC&&e&&(i=Ge(this)),this._offset=t,this._isUTC=!0,null!=i&&this.add(i,"m"),r!==t&&(!e||this._changeInProgress?tn(this,Xe(t-r,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?r:Ge(this)},Mn.utc=function(t){return this.utcOffset(0,t)},Mn.local=function(t){return this._isUTC&&(this.utcOffset(0,t),this._isUTC=!1,t&&this.subtract(Ge(this),"m")),this},Mn.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var t=je(ot,this._i);null!=t?this.utcOffset(t):this.utcOffset(0,!0)}return this},Mn.hasAlignedHourOffset=function(t){return!!this.isValid()&&(t=t?Le(t).utcOffset():0,(this.utcOffset()-t)%60==0)},Mn.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},Mn.isLocal=function(){return!!this.isValid()&&!this._isUTC},Mn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},Mn.isUtc=qe,Mn.isUTC=qe,Mn.zoneAbbr=function(){return this._isUTC?"UTC":""},Mn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},Mn.dates=D("dates accessor is deprecated. Use date instead.",bn),Mn.months=D("months accessor is deprecated. Use month instead",zt),Mn.years=D("years accessor is deprecated. Use year instead",Tt),Mn.zone=D("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",(function(t,e){return null!=t?("string"!=typeof t&&(t=-t),this.utcOffset(t,e),this):-this.utcOffset()})),Mn.isDSTShifted=D("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",(function(){if(!s(this._isDSTShifted))return this._isDSTShifted;var t={};if(b(t,this),(t=Fe(t))._a){var e=t._isUTC?f(t._a):Le(t._a);this._isDSTShifted=this.isValid()&&M(t._a,e.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}));var Dn=F.prototype;function Cn(t,e,n,i){var a=pe(),r=f().set(i,e);return a[n](r,t)}function Pn(t,e,n){if(l(t)&&(e=t,t=void 0),t=t||"",null!=e)return Cn(t,e,n,"month");var i,a=[];for(i=0;i<12;i++)a[i]=Cn(t,i,n,"month");return a}function Tn(t,e,n,i){"boolean"==typeof t?(l(e)&&(n=e,e=void 0),e=e||""):(n=e=t,t=!1,l(e)&&(n=e,e=void 0),e=e||"");var a,r=pe(),o=t?r._week.dow:0;if(null!=n)return Cn(e,(n+o)%7,i,"day");var s=[];for(a=0;a<7;a++)s[a]=Cn(e,(a+o)%7,i,"day");return s}Dn.calendar=function(t,e,n){var i=this._calendar[t]||this._calendar.sameElse;return O(i)?i.call(e,n):i},Dn.longDateFormat=function(t){var e=this._longDateFormat[t],n=this._longDateFormat[t.toUpperCase()];return e||!n?e:(this._longDateFormat[t]=n.replace(/MMMM|MM|DD|dddd/g,(function(t){return t.slice(1)})),this._longDateFormat[t])},Dn.invalidDate=function(){return this._invalidDate},Dn.ordinal=function(t){return this._ordinal.replace("%d",t)},Dn.preparse=Sn,Dn.postformat=Sn,Dn.relativeTime=function(t,e,n,i){var a=this._relativeTime[n];return O(a)?a(t,e,n,i):a.replace(/%d/i,t)},Dn.pastFuture=function(t,e){var n=this._relativeTime[t>0?"future":"past"];return O(n)?n(e):n.replace(/%s/i,e)},Dn.set=function(t){var e,n;for(n in t)O(e=t[n])?this[n]=e:this["_"+n]=e;this._config=t,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},Dn.months=function(t,e){return t?r(this._months)?this._months[t.month()]:this._months[(this._months.isFormat||Lt).test(e)?"format":"standalone"][t.month()]:r(this._months)?this._months:this._months.standalone},Dn.monthsShort=function(t,e){return t?r(this._monthsShort)?this._monthsShort[t.month()]:this._monthsShort[Lt.test(e)?"format":"standalone"][t.month()]:r(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},Dn.monthsParse=function(t,e,n){var i,a,r;if(this._monthsParseExact)return Wt.call(this,t,e,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),i=0;i<12;i++){if(a=f([2e3,i]),n&&!this._longMonthsParse[i]&&(this._longMonthsParse[i]=new RegExp("^"+this.months(a,"").replace(".","")+"$","i"),this._shortMonthsParse[i]=new RegExp("^"+this.monthsShort(a,"").replace(".","")+"$","i")),n||this._monthsParse[i]||(r="^"+this.months(a,"")+"|^"+this.monthsShort(a,""),this._monthsParse[i]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===e&&this._longMonthsParse[i].test(t))return i;if(n&&"MMM"===e&&this._shortMonthsParse[i].test(t))return i;if(!n&&this._monthsParse[i].test(t))return i}},Dn.monthsRegex=function(t){return this._monthsParseExact?(h(this,"_monthsRegex")||Ht.call(this),t?this._monthsStrictRegex:this._monthsRegex):(h(this,"_monthsRegex")||(this._monthsRegex=Vt),this._monthsStrictRegex&&t?this._monthsStrictRegex:this._monthsRegex)},Dn.monthsShortRegex=function(t){return this._monthsParseExact?(h(this,"_monthsRegex")||Ht.call(this),t?this._monthsShortStrictRegex:this._monthsShortRegex):(h(this,"_monthsShortRegex")||(this._monthsShortRegex=Et),this._monthsShortStrictRegex&&t?this._monthsShortStrictRegex:this._monthsShortRegex)},Dn.week=function(t){return qt(t,this._week.dow,this._week.doy).week},Dn.firstDayOfYear=function(){return this._week.doy},Dn.firstDayOfWeek=function(){return this._week.dow},Dn.weekdays=function(t,e){var n=r(this._weekdays)?this._weekdays:this._weekdays[t&&!0!==t&&this._weekdays.isFormat.test(e)?"format":"standalone"];return!0===t?$t(n,this._week.dow):t?n[t.day()]:n},Dn.weekdaysMin=function(t){return!0===t?$t(this._weekdaysMin,this._week.dow):t?this._weekdaysMin[t.day()]:this._weekdaysMin},Dn.weekdaysShort=function(t){return!0===t?$t(this._weekdaysShort,this._week.dow):t?this._weekdaysShort[t.day()]:this._weekdaysShort},Dn.weekdaysParse=function(t,e,n){var i,a,r;if(this._weekdaysParseExact)return Qt.call(this,t,e,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),i=0;i<7;i++){if(a=f([2e3,1]).day(i),n&&!this._fullWeekdaysParse[i]&&(this._fullWeekdaysParse[i]=new RegExp("^"+this.weekdays(a,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[i]=new RegExp("^"+this.weekdaysShort(a,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[i]=new RegExp("^"+this.weekdaysMin(a,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[i]||(r="^"+this.weekdays(a,"")+"|^"+this.weekdaysShort(a,"")+"|^"+this.weekdaysMin(a,""),this._weekdaysParse[i]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===e&&this._fullWeekdaysParse[i].test(t))return i;if(n&&"ddd"===e&&this._shortWeekdaysParse[i].test(t))return i;if(n&&"dd"===e&&this._minWeekdaysParse[i].test(t))return i;if(!n&&this._weekdaysParse[i].test(t))return i}},Dn.weekdaysRegex=function(t){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||ie.call(this),t?this._weekdaysStrictRegex:this._weekdaysRegex):(h(this,"_weekdaysRegex")||(this._weekdaysRegex=te),this._weekdaysStrictRegex&&t?this._weekdaysStrictRegex:this._weekdaysRegex)},Dn.weekdaysShortRegex=function(t){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||ie.call(this),t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(h(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=ee),this._weekdaysShortStrictRegex&&t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},Dn.weekdaysMinRegex=function(t){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||ie.call(this),t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(h(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=ne),this._weekdaysMinStrictRegex&&t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},Dn.isPM=function(t){return"p"===(t+"").toLowerCase().charAt(0)},Dn.meridiem=function(t,e,n){return t>11?n?"pm":"PM":n?"am":"AM"},ge("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10;return t+(1===k(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")}}),a.lang=D("moment.lang is deprecated. Use moment.locale instead.",ge),a.langData=D("moment.langData is deprecated. Use moment.localeData instead.",pe);var On=Math.abs;function An(t,e,n,i){var a=Xe(e,n);return t._milliseconds+=i*a._milliseconds,t._days+=i*a._days,t._months+=i*a._months,t._bubble()}function Fn(t){return t<0?Math.floor(t):Math.ceil(t)}function In(t){return 4800*t/146097}function Ln(t){return 146097*t/4800}function Rn(t){return function(){return this.as(t)}}var Nn=Rn("ms"),Wn=Rn("s"),Yn=Rn("m"),zn=Rn("h"),En=Rn("d"),Vn=Rn("w"),Hn=Rn("M"),Bn=Rn("Q"),jn=Rn("y");function Un(t){return function(){return this.isValid()?this._data[t]:NaN}}var Gn=Un("milliseconds"),qn=Un("seconds"),Zn=Un("minutes"),$n=Un("hours"),Xn=Un("days"),Kn=Un("months"),Jn=Un("years"),Qn=Math.round,ti={ss:44,s:45,m:45,h:22,d:26,M:11};function ei(t,e,n,i,a){return a.relativeTime(e||1,!!n,t,i)}var ni=Math.abs;function ii(t){return(t>0)-(t<0)||+t}function ai(){if(!this.isValid())return this.localeData().invalidDate();var t,e,n=ni(this._milliseconds)/1e3,i=ni(this._days),a=ni(this._months);t=w(n/60),e=w(t/60),n%=60,t%=60;var r=w(a/12),o=a%=12,s=i,l=e,u=t,d=n?n.toFixed(3).replace(/\.?0+$/,""):"",h=this.asSeconds();if(!h)return"P0D";var c=h<0?"-":"",f=ii(this._months)!==ii(h)?"-":"",g=ii(this._days)!==ii(h)?"-":"",m=ii(this._milliseconds)!==ii(h)?"-":"";return c+"P"+(r?f+r+"Y":"")+(o?f+o+"M":"")+(s?g+s+"D":"")+(l||u||d?"T":"")+(l?m+l+"H":"")+(u?m+u+"M":"")+(d?m+d+"S":"")}var ri=ze.prototype;return ri.isValid=function(){return this._isValid},ri.abs=function(){var t=this._data;return this._milliseconds=On(this._milliseconds),this._days=On(this._days),this._months=On(this._months),t.milliseconds=On(t.milliseconds),t.seconds=On(t.seconds),t.minutes=On(t.minutes),t.hours=On(t.hours),t.months=On(t.months),t.years=On(t.years),this},ri.add=function(t,e){return An(this,t,e,1)},ri.subtract=function(t,e){return An(this,t,e,-1)},ri.as=function(t){if(!this.isValid())return NaN;var e,n,i=this._milliseconds;if("month"===(t=R(t))||"quarter"===t||"year"===t)switch(e=this._days+i/864e5,n=this._months+In(e),t){case"month":return n;case"quarter":return n/3;case"year":return n/12}else switch(e=this._days+Math.round(Ln(this._months)),t){case"week":return e/7+i/6048e5;case"day":return e+i/864e5;case"hour":return 24*e+i/36e5;case"minute":return 1440*e+i/6e4;case"second":return 86400*e+i/1e3;case"millisecond":return Math.floor(864e5*e)+i;default:throw new Error("Unknown unit "+t)}},ri.asMilliseconds=Nn,ri.asSeconds=Wn,ri.asMinutes=Yn,ri.asHours=zn,ri.asDays=En,ri.asWeeks=Vn,ri.asMonths=Hn,ri.asQuarters=Bn,ri.asYears=jn,ri.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*k(this._months/12):NaN},ri._bubble=function(){var t,e,n,i,a,r=this._milliseconds,o=this._days,s=this._months,l=this._data;return r>=0&&o>=0&&s>=0||r<=0&&o<=0&&s<=0||(r+=864e5*Fn(Ln(s)+o),o=0,s=0),l.milliseconds=r%1e3,t=w(r/1e3),l.seconds=t%60,e=w(t/60),l.minutes=e%60,n=w(e/60),l.hours=n%24,o+=w(n/24),a=w(In(o)),s+=a,o-=Fn(Ln(a)),i=w(s/12),s%=12,l.days=o,l.months=s,l.years=i,this},ri.clone=function(){return Xe(this)},ri.get=function(t){return t=R(t),this.isValid()?this[t+"s"]():NaN},ri.milliseconds=Gn,ri.seconds=qn,ri.minutes=Zn,ri.hours=$n,ri.days=Xn,ri.weeks=function(){return w(this.days()/7)},ri.months=Kn,ri.years=Jn,ri.humanize=function(t){if(!this.isValid())return this.localeData().invalidDate();var e=this.localeData(),n=function(t,e,n){var i=Xe(t).abs(),a=Qn(i.as("s")),r=Qn(i.as("m")),o=Qn(i.as("h")),s=Qn(i.as("d")),l=Qn(i.as("M")),u=Qn(i.as("y")),d=a<=ti.ss&&["s",a]||a0,d[4]=n,ei.apply(null,d)}(this,!t,e);return t&&(n=e.pastFuture(+this,n)),e.postformat(n)},ri.toISOString=ai,ri.toString=ai,ri.toJSON=ai,ri.locale=rn,ri.localeData=sn,ri.toIsoString=D("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",ai),ri.lang=on,j("X",0,0,"unix"),j("x",0,0,"valueOf"),dt("x",rt),dt("X",/[+-]?\d+(\.\d{1,3})?/),gt("X",(function(t,e,n){n._d=new Date(1e3*parseFloat(t,10))})),gt("x",(function(t,e,n){n._d=new Date(k(t))})),a.version="2.24.0",n=Le,a.fn=Mn,a.min=function(){return We("isBefore",[].slice.call(arguments,0))},a.max=function(){return We("isAfter",[].slice.call(arguments,0))},a.now=function(){return Date.now?Date.now():+new Date},a.utc=f,a.unix=function(t){return Le(1e3*t)},a.months=function(t,e){return Pn(t,e,"months")},a.isDate=u,a.locale=ge,a.invalid=p,a.duration=Xe,a.isMoment=_,a.weekdays=function(t,e,n){return Tn(t,e,n,"weekdays")},a.parseZone=function(){return Le.apply(null,arguments).parseZone()},a.localeData=pe,a.isDuration=Ee,a.monthsShort=function(t,e){return Pn(t,e,"monthsShort")},a.weekdaysMin=function(t,e,n){return Tn(t,e,n,"weekdaysMin")},a.defineLocale=me,a.updateLocale=function(t,e){if(null!=e){var n,i,a=ue;null!=(i=fe(t))&&(a=i._config),e=A(a,e),(n=new F(e)).parentLocale=de[t],de[t]=n,ge(t)}else null!=de[t]&&(null!=de[t].parentLocale?de[t]=de[t].parentLocale:null!=de[t]&&delete de[t]);return de[t]},a.locales=function(){return C(de)},a.weekdaysShort=function(t,e,n){return Tn(t,e,n,"weekdaysShort")},a.normalizeUnits=R,a.relativeTimeRounding=function(t){return void 0===t?Qn:"function"==typeof t&&(Qn=t,!0)},a.relativeTimeThreshold=function(t,e){return void 0!==ti[t]&&(void 0===e?ti[t]:(ti[t]=e,"s"===t&&(ti.ss=e-1),!0))},a.calendarFormat=function(t,e){var n=t.diff(e,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},a.prototype=Mn,a.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},a}()})),pi={datetime:"MMM D, YYYY, h:mm:ss a",millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"};on._date.override("function"==typeof mi?{_id:"moment",formats:function(){return pi},parse:function(t,e){return"string"==typeof t&&"string"==typeof e?t=mi(t,e):t instanceof mi||(t=mi(t)),t.isValid()?t.valueOf():null},format:function(t,e){return mi(t).format(e)},add:function(t,e,n){return mi(t).add(e,n).valueOf()},diff:function(t,e,n){return mi(t).diff(mi(e),n)},startOf:function(t,e,n){return t=mi(t),"isoWeek"===e?t.isoWeekday(n).valueOf():t.startOf(e).valueOf()},endOf:function(t,e){return mi(t).endOf(e).valueOf()},_create:function(t){return mi(t)}}:{}),Y._set("global",{plugins:{filler:{propagate:!0}}});var vi={dataset:function(t){var e=t.fill,n=t.chart,i=n.getDatasetMeta(e),a=i&&n.isDatasetVisible(e)&&i.dataset._children||[],r=a.length||0;return r?function(t,e){return e=n)&&i;switch(r){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return r;default:return!1}}function yi(t){return(t.el._scale||{}).getPointPositionForValue?function(t){var e,n,i,a,r,o=t.el._scale,s=o.options,l=o.chart.data.labels.length,u=t.fill,d=[];if(!l)return null;for(e=s.ticks.reverse?o.max:o.min,n=s.ticks.reverse?o.min:o.max,i=o.getPointPositionForValue(0,e),a=0;a0;--r)B.canvas.lineTo(t,n[r],n[r-1],!0);else for(o=n[0].cx,s=n[0].cy,l=Math.sqrt(Math.pow(n[0].x-o,2)+Math.pow(n[0].y-s,2)),r=a-1;r>0;--r)t.arc(o,s,l,n[r].angle,n[r-1].angle,!0)}}function Mi(t,e,n,i,a,r){var o,s,l,u,d,h,c,f,g=e.length,m=i.spanGaps,p=[],v=[],b=0,y=0;for(t.beginPath(),o=0,s=g;o=0;--n)(e=l[n].$filler)&&e.visible&&(a=(i=e.el)._view,r=i._children||[],o=e.mapper,s=a.backgroundColor||Y.global.defaultColor,o&&s&&r.length&&(B.canvas.clipArea(u,t.chartArea),Mi(u,r,o,a,s,i._loop),B.canvas.unclipArea(u)))}},Di=B.rtl.getRtlAdapter,Ci=B.noop,Pi=B.valueOrDefault;function Ti(t,e){return t.usePointStyle&&t.boxWidth>e?e:t.boxWidth}Y._set("global",{legend:{display:!0,position:"top",align:"center",fullWidth:!0,reverse:!1,weight:1e3,onClick:function(t,e){var n=e.datasetIndex,i=this.chart,a=i.getDatasetMeta(n);a.hidden=null===a.hidden?!i.data.datasets[n].hidden:null,i.update()},onHover:null,onLeave:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data.datasets,n=t.options.legend||{},i=n.labels&&n.labels.usePointStyle;return t._getSortedDatasetMetas().map((function(n){var a=n.controller.getStyle(i?0:void 0);return{text:e[n.index].label,fillStyle:a.backgroundColor,hidden:!t.isDatasetVisible(n.index),lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:a.borderWidth,strokeStyle:a.borderColor,pointStyle:a.pointStyle,rotation:a.rotation,datasetIndex:n.index}}),this)}}},legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data.datasets;for(a.setAttribute("class",t.id+"-legend"),e=0,n=r.length;el.width)&&(h+=o+n.padding,d[d.length-(e>0?0:1)]=0),s[e]={left:0,top:0,width:i,height:o},d[d.length-1]+=i+n.padding})),l.height+=h}else{var c=n.padding,f=t.columnWidths=[],g=t.columnHeights=[],m=n.padding,p=0,v=0;B.each(t.legendItems,(function(t,e){var i=Ti(n,o)+o/2+a.measureText(t.text).width;e>0&&v+o+2*c>l.height&&(m+=p+n.padding,f.push(p),g.push(v),p=0,v=0),p=Math.max(p,i),v+=o+c,s[e]={left:0,top:0,width:i,height:o}})),m+=p,f.push(p),g.push(v),l.width+=m}t.width=l.width,t.height=l.height}else t.width=l.width=t.height=l.height=0},afterFit:Ci,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,n=e.labels,i=Y.global,a=i.defaultColor,r=i.elements.line,o=t.height,s=t.columnHeights,l=t.width,u=t.lineWidths;if(e.display){var d,h=Di(e.rtl,t.left,t.minSize.width),c=t.ctx,f=Pi(n.fontColor,i.defaultFontColor),g=B.options._parseFont(n),m=g.size;c.textAlign=h.textAlign("left"),c.textBaseline="middle",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=g.string;var p=Ti(n,m),v=t.legendHitBoxes,b=function(t,i){switch(e.align){case"start":return n.padding;case"end":return t-i;default:return(t-i+n.padding)/2}},y=t.isHorizontal();d=y?{x:t.left+b(l,u[0]),y:t.top+n.padding,line:0}:{x:t.left+n.padding,y:t.top+b(o,s[0]),line:0},B.rtl.overrideTextDirection(t.ctx,e.textDirection);var x=m+n.padding;B.each(t.legendItems,(function(e,i){var f=c.measureText(e.text).width,g=p+m/2+f,_=d.x,w=d.y;h.setWidth(t.minSize.width),y?i>0&&_+g+n.padding>t.left+t.minSize.width&&(w=d.y+=x,d.line++,_=d.x=t.left+b(l,u[d.line])):i>0&&w+x>t.top+t.minSize.height&&(_=d.x=_+t.columnWidths[d.line]+n.padding,d.line++,w=d.y=t.top+b(o,s[d.line]));var k=h.x(_);!function(t,e,i){if(!(isNaN(p)||p<=0)){c.save();var o=Pi(i.lineWidth,r.borderWidth);if(c.fillStyle=Pi(i.fillStyle,a),c.lineCap=Pi(i.lineCap,r.borderCapStyle),c.lineDashOffset=Pi(i.lineDashOffset,r.borderDashOffset),c.lineJoin=Pi(i.lineJoin,r.borderJoinStyle),c.lineWidth=o,c.strokeStyle=Pi(i.strokeStyle,a),c.setLineDash&&c.setLineDash(Pi(i.lineDash,r.borderDash)),n&&n.usePointStyle){var s=p*Math.SQRT2/2,l=h.xPlus(t,p/2),u=e+m/2;B.canvas.drawPoint(c,i.pointStyle,s,l,u,i.rotation)}else c.fillRect(h.leftForLtr(t,p),e,p,m),0!==o&&c.strokeRect(h.leftForLtr(t,p),e,p,m);c.restore()}}(k,w,e),v[i].left=h.leftForLtr(k,v[i].width),v[i].top=w,function(t,e,n,i){var a=m/2,r=h.xPlus(t,p+a),o=e+a;c.fillText(n.text,r,o),n.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(r,o),c.lineTo(h.xPlus(r,i),o),c.stroke())}(k,w,e,f),y?d.x+=g+n.padding:d.y+=x})),B.rtl.restoreTextDirection(t.ctx,e.textDirection)}},_getLegendItemAt:function(t,e){var n,i,a,r=this;if(t>=r.left&&t<=r.right&&e>=r.top&&e<=r.bottom)for(a=r.legendHitBoxes,n=0;n=(i=a[n]).left&&t<=i.left+i.width&&e>=i.top&&e<=i.top+i.height)return r.legendItems[n];return null},handleEvent:function(t){var e,n=this,i=n.options,a="mouseup"===t.type?"click":t.type;if("mousemove"===a){if(!i.onHover&&!i.onLeave)return}else{if("click"!==a)return;if(!i.onClick)return}e=n._getLegendItemAt(t.x,t.y),"click"===a?e&&i.onClick&&i.onClick.call(n,t.native,e):(i.onLeave&&e!==n._hoveredItem&&(n._hoveredItem&&i.onLeave.call(n,t.native,n._hoveredItem),n._hoveredItem=e),i.onHover&&e&&i.onHover.call(n,t.native,e))}});function Ai(t,e){var n=new Oi({ctx:t.ctx,options:e,chart:t});pe.configure(t,n,e),pe.addBox(t,n),t.legend=n}var Fi={id:"legend",_element:Oi,beforeInit:function(t){var e=t.options.legend;e&&Ai(t,e)},beforeUpdate:function(t){var e=t.options.legend,n=t.legend;e?(B.mergeIf(e,Y.global.legend),n?(pe.configure(t,n,e),n.options=e):Ai(t,e)):n&&(pe.removeBox(t,n),delete t.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}},Ii=B.noop;Y._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,padding:10,position:"top",text:"",weight:2e3}});var Li=X.extend({initialize:function(t){B.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:Ii,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:Ii,beforeSetDimensions:Ii,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:Ii,beforeBuildLabels:Ii,buildLabels:Ii,afterBuildLabels:Ii,beforeFit:Ii,fit:function(){var t,e=this,n=e.options,i=e.minSize={},a=e.isHorizontal();n.display?(t=(B.isArray(n.text)?n.text.length:1)*B.options._parseFont(n).lineHeight+2*n.padding,e.width=i.width=a?e.maxWidth:t,e.height=i.height=a?t:e.maxHeight):e.width=i.width=e.height=i.height=0},afterFit:Ii,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,n=t.options;if(n.display){var i,a,r,o=B.options._parseFont(n),s=o.lineHeight,l=s/2+n.padding,u=0,d=t.top,h=t.left,c=t.bottom,f=t.right;e.fillStyle=B.valueOrDefault(n.fontColor,Y.global.defaultFontColor),e.font=o.string,t.isHorizontal()?(a=h+(f-h)/2,r=d+l,i=f-h):(a="left"===n.position?h+l:f-l,r=d+(c-d)/2,i=c-d,u=Math.PI*("left"===n.position?-.5:.5)),e.save(),e.translate(a,r),e.rotate(u),e.textAlign="center",e.textBaseline="middle";var g=n.text;if(B.isArray(g))for(var m=0,p=0;p=0;i--){var a=t[i];if(e(a))return a}},B.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},B.almostEquals=function(t,e,n){return Math.abs(t-e)=t},B.max=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.max(t,e)}),Number.NEGATIVE_INFINITY)},B.min=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.min(t,e)}),Number.POSITIVE_INFINITY)},B.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0===(t=+t)||isNaN(t)?t:t>0?1:-1},B.toRadians=function(t){return t*(Math.PI/180)},B.toDegrees=function(t){return t*(180/Math.PI)},B._decimalPlaces=function(t){if(B.isFinite(t)){for(var e=1,n=0;Math.round(t*e)/e!==t;)e*=10,n++;return n}},B.getAngleFromPoint=function(t,e){var n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),r=Math.atan2(i,n);return r<-.5*Math.PI&&(r+=2*Math.PI),{angle:r,distance:a}},B.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},B.aliasPixel=function(t){return t%2==0?0:.5},B._alignPixel=function(t,e,n){var i=t.currentDevicePixelRatio,a=n/2;return Math.round((e-a)*i)/i+a},B.splineCurve=function(t,e,n,i){var a=t.skip?e:t,r=e,o=n.skip?e:n,s=Math.sqrt(Math.pow(r.x-a.x,2)+Math.pow(r.y-a.y,2)),l=Math.sqrt(Math.pow(o.x-r.x,2)+Math.pow(o.y-r.y,2)),u=s/(s+l),d=l/(s+l),h=i*(u=isNaN(u)?0:u),c=i*(d=isNaN(d)?0:d);return{previous:{x:r.x-h*(o.x-a.x),y:r.y-h*(o.y-a.y)},next:{x:r.x+c*(o.x-a.x),y:r.y+c*(o.y-a.y)}}},B.EPSILON=Number.EPSILON||1e-14,B.splineCurveMonotone=function(t){var e,n,i,a,r,o,s,l,u,d=(t||[]).map((function(t){return{model:t._model,deltaK:0,mK:0}})),h=d.length;for(e=0;e0?d[e-1]:null,(a=e0?d[e-1]:null,a=e=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},B.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},B.niceNum=function(t,e){var n=Math.floor(B.log10(t)),i=t/Math.pow(10,n);return(e?i<1.5?1:i<3?2:i<7?5:10:i<=1?1:i<=2?2:i<=5?5:10)*Math.pow(10,n)},B.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},B.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,r=t.target||t.srcElement,o=r.getBoundingClientRect(),s=a.touches;s&&s.length>0?(n=s[0].clientX,i=s[0].clientY):(n=a.clientX,i=a.clientY);var l=parseFloat(B.getStyle(r,"padding-left")),u=parseFloat(B.getStyle(r,"padding-top")),d=parseFloat(B.getStyle(r,"padding-right")),h=parseFloat(B.getStyle(r,"padding-bottom")),c=o.right-o.left-l-d,f=o.bottom-o.top-u-h;return{x:n=Math.round((n-o.left-l)/c*r.width/e.currentDevicePixelRatio),y:i=Math.round((i-o.top-u)/f*r.height/e.currentDevicePixelRatio)}},B.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},B.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},B._calculatePadding=function(t,e,n){return(e=B.getStyle(t,e)).indexOf("%")>-1?n*parseInt(e,10)/100:parseInt(e,10)},B._getParentNode=function(t){var e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e},B.getMaximumWidth=function(t){var e=B._getParentNode(t);if(!e)return t.clientWidth;var n=e.clientWidth,i=n-B._calculatePadding(e,"padding-left",n)-B._calculatePadding(e,"padding-right",n),a=B.getConstraintWidth(t);return isNaN(a)?i:Math.min(i,a)},B.getMaximumHeight=function(t){var e=B._getParentNode(t);if(!e)return t.clientHeight;var n=e.clientHeight,i=n-B._calculatePadding(e,"padding-top",n)-B._calculatePadding(e,"padding-bottom",n),a=B.getConstraintHeight(t);return isNaN(a)?i:Math.min(i,a)},B.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},B.retinaScale=function(t,e){var n=t.currentDevicePixelRatio=e||"undefined"!=typeof window&&window.devicePixelRatio||1;if(1!==n){var i=t.canvas,a=t.height,r=t.width;i.height=a*n,i.width=r*n,t.ctx.scale(n,n),i.style.height||i.style.width||(i.style.height=a+"px",i.style.width=r+"px")}},B.fontString=function(t,e,n){return e+" "+t+"px "+n},B.longestText=function(t,e,n,i){var a=(i=i||{}).data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var o,s,l,u,d,h=0,c=n.length;for(o=0;on.length){for(o=0;oi&&(i=r),i},B.numberOfLabelLines=function(t){var e=1;return B.each(t,(function(t){B.isArray(t)&&t.length>e&&(e=t.length)})),e},B.color=w?function(t){return t instanceof CanvasGradient&&(t=Y.global.defaultColor),w(t)}:function(t){return console.error("Color.js not found!"),t},B.getHoverColor=function(t){return t instanceof CanvasPattern||t instanceof CanvasGradient?t:B.color(t).saturate(.5).darken(.1).rgbString()}}(),nn._adapters=on,nn.Animation=J,nn.animationService=Q,nn.controllers=Qt,nn.DatasetController=at,nn.defaults=Y,nn.Element=X,nn.elements=kt,nn.Interaction=oe,nn.layouts=pe,nn.platform=Le,nn.plugins=Re,nn.Scale=_n,nn.scaleService=Ne,nn.Ticks=sn,nn.Tooltip=qe,nn.helpers.each(gi,(function(t,e){nn.scaleService.registerScaleType(e,t,t._defaults)})),Ni)Ni.hasOwnProperty(Ei)&&nn.plugins.register(Ni[Ei]);nn.platform.initialize();var Vi=nn;return"undefined"!=typeof window&&(window.Chart=nn),nn.Chart=nn,nn.Legend=Ni.legend._element,nn.Title=Ni.title._element,nn.pluginService=nn.plugins,nn.PluginBase=nn.Element.extend({}),nn.canvasHelpers=nn.helpers.canvas,nn.layoutService=nn.layouts,nn.LinearScaleBase=Cn,nn.helpers.each(["Bar","Bubble","Doughnut","Line","PolarArea","Radar","Scatter"],(function(t){nn[t]=function(e,n){return new nn(e,nn.helpers.merge(n||{},{type:t.charAt(0).toLowerCase()+t.slice(1)}))}})),Vi})); diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/chartjs/chartjs-gauge.min.js b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/chartjs/chartjs-gauge.min.js new file mode 100755 index 00000000..96ccfd0c --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/chartjs/chartjs-gauge.min.js @@ -0,0 +1,7 @@ +/*! + * chartjs-gauge.js v0.3.0 + * https://github.com/haiiaaa/chartjs-gauge/ + * (c) 2021 chartjs-gauge.js Contributors + * Released under the MIT License + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("chart.js")):"function"==typeof define&&define.amd?define(["chart.js"],e):(t=t||self).Gauge=e(t.Chart)}(this,(function(t){"use strict";function e(t,e,r){return e in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}function r(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),r.push.apply(r,a)}return r}(t=t&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t).defaults._set("gauge",{needle:{radiusPercentage:2,widthPercentage:3.2,lengthPercentage:80,color:"rgba(0, 0, 0, 1)"},valueLabel:{display:!0,formatter:null,color:"rgba(255, 255, 255, 1)",backgroundColor:"rgba(0, 0, 0, 1)",borderRadius:5,padding:{top:5,right:5,bottom:5,left:5},bottomMarginPercentage:5},animation:{duration:1e3,animateRotate:!0,animateScale:!1},cutoutPercentage:50,rotation:-Math.PI,circumference:Math.PI,legend:{display:!1},tooltips:{enabled:!1}});var a=t.controllers.doughnut.extend({getValuePercent:function(t,e){var r=t.minValue,a=t.data,n=r||0;return(e-n)/((a[a.length-1]||1)-n)},getWidth:function(t){return t.chartArea.right-t.chartArea.left},getTranslation:function(t){var e=t.chartArea,r=t.offsetX,a=t.offsetY;return{dx:(e.left+e.right)/2+r,dy:(e.top+e.bottom)/2+a}},getAngle:function(t){var e=t.chart,r=t.valuePercent,a=e.options;return a.rotation+a.circumference*r},drawNeedle:function(t){this.chart.animating||(t=1);var e=this.chart,r=e.ctx,a=e.config,n=e.innerRadius,i=e.outerRadius,o=a.data.datasets[this.index],l=this.getMeta().previous,c=a.options.needle,s=c.radiusPercentage,u=c.widthPercentage,h=c.lengthPercentage,d=c.color,g=this.getWidth(this.chart),f=s/100*g,p=u/100*g,b=h/100*(i-n)+n,P=this.getTranslation(this.chart),v=P.dx,m=P.dy,y=this.getAngle({chart:this.chart,valuePercent:l.valuePercent}),x=y+(this.getAngle({chart:this.chart,valuePercent:this.getValuePercent(o,o.value)})-y)*t;r.save(),r.translate(v,m),r.rotate(x),r.fillStyle=d,r.beginPath(),r.ellipse(0,0,f,f,0,0,2*Math.PI),r.fill(),r.beginPath(),r.moveTo(0,p/2),r.lineTo(b,0),r.lineTo(0,-p/2),r.fill(),r.restore()},drawValueLabel:function(e){if(this.chart.config.options.valueLabel.display){var r=this.chart,a=r.ctx,n=r.config,i=n.options.defaultFontFamily,o=n.data.datasets[this.index],l=n.options.valueLabel,c=l.formatter,s=l.fontSize,u=l.color,h=l.backgroundColor,d=l.borderRadius,g=l.padding,f=l.bottomMarginPercentage/100*this.getWidth(this.chart),p=(c||function(t){return t})(o.value).toString();a.textBaseline="middle",a.textAlign="center",s&&(a.font="".concat(s,"px ").concat(i));var b=a.measureText(p).width,P=Math.max(a.measureText("m").width,a.measureText("W").width),v=-(g.left+b/2),m=-(g.top+P/2),y=g.left+b+g.right,x=g.top+P+g.bottom,w=this.getTranslation(this.chart),O=w.dx,j=w.dy,M=this.chart.options.rotation%(2*Math.PI);O+=f*Math.cos(M+Math.PI/2),j+=f*Math.sin(M+Math.PI/2),a.save(),a.translate(O,j),a.beginPath(),t.helpers.canvas.roundedRect(a,v,m,y,x,d),a.fillStyle=h,a.fill(),a.fillStyle=u||n.options.defaultFontColor;a.fillText(p,0,.075*P),a.restore()}},update:function(e){var r=this.chart.config.data.datasets[this.index];r.minValue=r.minValue||0;var a=this.getMeta(),n={valuePercent:0};e?(a.previous=null,a.current=n):(r.data.sort((function(t,e){return t-e})),a.previous=a.current||n,a.current={valuePercent:this.getValuePercent(r,r.value)}),t.controllers.doughnut.prototype.update.call(this,e)},updateElement:function(a,n,i){t.controllers.doughnut.prototype.updateElement.call(this,a,n,i);var o=this.getDataset(),l=o.data,c=0===n?o.minValue:l[n-1],s=l[n],u=this.getAngle({chart:this.chart,valuePercent:this.getValuePercent(o,c)}),h=this.getAngle({chart:this.chart,valuePercent:this.getValuePercent(o,s)}),d=h-u;a._model=function(t){for(var a=1;a'+simba_tfa_frontend.saving+'' }); + + // https://stackoverflow.com/questions/10147149/how-can-i-override-jquerys-serialize-to-include-unchecked-checkboxes + var form_data = $('.tfa_settings_form input, .tfa_settings_form textarea, .tfa_settings_form select').serialize(); + + // Include unchecked checkboxes. Use filter to only include unchecked boxes. + $.each($('.tfa_settings_form input[type=checkbox]') + .filter(function(idx) { + return $(this).prop('checked') === false + }), + function(idx, el){ + // attach matched element names to the form_data with a chosen value. + var emptyVal = '0'; + form_data += '&' + $(el).attr('name') + '=' + emptyVal; + } + ); + + $.post(simba_tfa_frontend.ajax_url, { + action: 'tfa_frontend', + subaction: 'savesettings', + settings: form_data, + nonce: simba_tfa_frontend.nonce + }, function(response) { + var settings_saved = false; + try { + var resp = JSON.parse(response); + if (resp.hasOwnProperty('result')) { + settings_saved = true; + tfa_query_leaving = false; + // Allow user code to respond + $(document).trigger('tfa_settings_saved', resp); + } + + if (resp.hasOwnProperty('message')) { + alert(resp.message); + } + + if (resp.hasOwnProperty('qr')) { + $('.simbaotp_qr_container').data('qrcode', resp['qr']).empty().qrcode({ + "render": "image", + "text": resp['qr'], + }); + } + + if (resp.hasOwnProperty('al_type_disp')) { + $("#al_type_name").html(resp['al_type_disp']['disp']); + $("#al_type_desc").html(resp['al_type_disp']['desc']); + } + + } catch(err) { + console.log(err); + console.log(response); + if ('' === simba_tfa_frontend.also_try) { + alert(simba_tfa_frontend.response+response); + } + } + if ('' != simba_tfa_frontend.also_try) { + if (!settings_saved) { + $.post(simba_tfa_frontend.also_try, { + action: 'tfa_frontend', + subaction: 'savesettings', + settings: form_data, + nonce: simba_tfa_frontend.nonce + }, function(response) { + + try { + var resp = JSON.parse(response); + if (resp.hasOwnProperty('result')) { + settings_saved = true; + tfa_query_leaving = false; + // Allow user code to respond + $(document).trigger('tfa_settings_saved', resp); + } + if (resp.hasOwnProperty('message')) { + alert(resp.message); + } + if (resp.hasOwnProperty('qr')) { + $('.simbaotp_qr_container').data('qrcode', resp['qr']).empty().qrcode({ + "render": "image", + "text": resp['qr'], + }); + } + if (resp.hasOwnProperty('al_type_disp')) { + $("#al_type_name").html(resp['al_type_disp']['disp']); + $("#al_type_desc").html(resp['al_type_disp']['desc']); + } + + } catch(err) { + console.log(err); + console.log(response); + alert(simba_tfa_frontend.response+response); + } + $.unblockUI(); + }); + } else { + $.unblockUI(); + } + } else { + $.unblockUI(); + } + }); + + }); +}); diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/gutenberg-blocks.js b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/gutenberg-blocks.js new file mode 100755 index 00000000..6fdf9843 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/gutenberg-blocks.js @@ -0,0 +1,19 @@ +var registerBlockType = wp.blocks.registerBlockType; +var createElement = wp.element.createElement; +var serverSideRender = wp.serverSideRender; + +registerBlockType('twofactor/user-settings', { + title: tfa_trans.block_title, + icon: 'lock', + category: 'widgets', + edit: function (props) { + return createElement( + 'div', + null, + createElement(serverSideRender, { + block: 'twofactor/user-settings', + attributes: props.attributes, + } ) + ); + }, +} ); \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery-qrcode/README.md b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery-qrcode/README.md new file mode 100755 index 00000000..e33c40e9 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery-qrcode/README.md @@ -0,0 +1,40 @@ +# jQuery.qrcode + +[![license][license-img]][github] [![web][web-img]][web] [![github][github-img]][github] [![bower][bower-img]][github] + +jQuery plugin to dynamically generate QR codes. Uses [QR Code Generator][qrcode] (MIT). + + +## License +The MIT License (MIT) + +Copyright (c) 2016 Lars Jung (https://larsjung.de) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +[web]: https://larsjung.de/qrcode/ +[github]: https://github.com/lrsjng/jquery-qrcode + +[license-img]: https://img.shields.io/badge/license-MIT-a0a060.svg?style=flat-square +[web-img]: https://img.shields.io/badge/web-larsjung.de/qrcode-a0a060.svg?style=flat-square +[github-img]: https://img.shields.io/badge/github-lrsjng/jquery--qrcode-a0a060.svg?style=flat-square +[bower-img]: https://img.shields.io/badge/bower-lrsjng/jquery--qrcode-a0a060.svg?style=flat-square + +[qrcode]: https://github.com/kazuhikoarase/qrcode-generator diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery-qrcode/jquery-qrcode.js b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery-qrcode/jquery-qrcode.js new file mode 100755 index 00000000..b87e884b --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery-qrcode/jquery-qrcode.js @@ -0,0 +1,2332 @@ +/*! jquery-qrcode v0.14.0 - https://larsjung.de/jquery-qrcode/ */ +(function (vendor_qrcode) { + 'use strict'; + + var jq = window.jQuery; + + // Check if canvas is available in the browser (as Modernizr does) + var hasCanvas = (function () { + var elem = document.createElement('canvas'); + return !!(elem.getContext && elem.getContext('2d')); + }()); + + // Wrapper for the original QR code generator. + function createQRCode(text, level, version, quiet) { + var qr = {}; + + var vqr = vendor_qrcode(version, level); + vqr.addData(text); + vqr.make(); + + quiet = quiet || 0; + + var qrModuleCount = vqr.getModuleCount(); + var quietModuleCount = vqr.getModuleCount() + 2 * quiet; + + function isDark(row, col) { + row -= quiet; + col -= quiet; + + if (row < 0 || row >= qrModuleCount || col < 0 || col >= qrModuleCount) { + return false; + } + return vqr.isDark(row, col); + } + + function addBlank(l, t, r, b) { + var prevIsDark = qr.isDark; + var moduleSize = 1 / quietModuleCount; + + qr.isDark = function (row, col) { + var ml = col * moduleSize; + var mt = row * moduleSize; + var mr = ml + moduleSize; + var mb = mt + moduleSize; + + return prevIsDark(row, col) && (l > mr || ml > r || t > mb || mt > b); + }; + } + + qr.text = text; + qr.level = level; + qr.version = version; + qr.moduleCount = quietModuleCount; + qr.isDark = isDark; + qr.addBlank = addBlank; + + return qr; + } + + // Returns a minimal QR code for the given text starting with version `minVersion`. + // Returns `undefined` if `text` is too long to be encoded in `maxVersion`. + function createMinQRCode(text, level, minVersion, maxVersion, quiet) { + minVersion = Math.max(1, minVersion || 1); + maxVersion = Math.min(40, maxVersion || 40); + for (var version = minVersion; version <= maxVersion; version += 1) { + try { + return createQRCode(text, level, version, quiet); + } catch (err) {/* empty */} + } + return undefined; + } + + function drawBackgroundLabel(qr, context, settings) { + var size = settings.size; + var font = 'bold ' + settings.mSize * size + 'px ' + settings.fontname; + var ctx = jq('')[0].getContext('2d'); + + ctx.font = font; + + var w = ctx.measureText(settings.label).width; + var sh = settings.mSize; + var sw = w / size; + var sl = (1 - sw) * settings.mPosX; + var st = (1 - sh) * settings.mPosY; + var sr = sl + sw; + var sb = st + sh; + var pad = 0.01; + + if (settings.mode === 1) { + // Strip + qr.addBlank(0, st - pad, size, sb + pad); + } else { + // Box + qr.addBlank(sl - pad, st - pad, sr + pad, sb + pad); + } + + context.fillStyle = settings.fontcolor; + context.font = font; + context.fillText(settings.label, sl * size, st * size + 0.75 * settings.mSize * size); + } + + function drawBackgroundImage(qr, context, settings) { + var size = settings.size; + var w = settings.image.naturalWidth || 1; + var h = settings.image.naturalHeight || 1; + var sh = settings.mSize; + var sw = sh * w / h; + var sl = (1 - sw) * settings.mPosX; + var st = (1 - sh) * settings.mPosY; + var sr = sl + sw; + var sb = st + sh; + var pad = 0.01; + + if (settings.mode === 3) { + // Strip + qr.addBlank(0, st - pad, size, sb + pad); + } else { + // Box + qr.addBlank(sl - pad, st - pad, sr + pad, sb + pad); + } + + context.drawImage(settings.image, sl * size, st * size, sw * size, sh * size); + } + + function drawBackground(qr, context, settings) { + if (jq(settings.background).is('img')) { + context.drawImage(settings.background, 0, 0, settings.size, settings.size); + } else if (settings.background) { + context.fillStyle = settings.background; + context.fillRect(settings.left, settings.top, settings.size, settings.size); + } + + var mode = settings.mode; + if (mode === 1 || mode === 2) { + drawBackgroundLabel(qr, context, settings); + } else if (mode === 3 || mode === 4) { + drawBackgroundImage(qr, context, settings); + } + } + + function drawModuleDefault(qr, context, settings, left, top, width, row, col) { + if (qr.isDark(row, col)) { + context.rect(left, top, width, width); + } + } + + function drawModuleRoundedDark(ctx, l, t, r, b, rad, nw, ne, se, sw) { + if (nw) { + ctx.moveTo(l + rad, t); + } else { + ctx.moveTo(l, t); + } + + if (ne) { + ctx.lineTo(r - rad, t); + ctx.arcTo(r, t, r, b, rad); + } else { + ctx.lineTo(r, t); + } + + if (se) { + ctx.lineTo(r, b - rad); + ctx.arcTo(r, b, l, b, rad); + } else { + ctx.lineTo(r, b); + } + + if (sw) { + ctx.lineTo(l + rad, b); + ctx.arcTo(l, b, l, t, rad); + } else { + ctx.lineTo(l, b); + } + + if (nw) { + ctx.lineTo(l, t + rad); + ctx.arcTo(l, t, r, t, rad); + } else { + ctx.lineTo(l, t); + } + } + + function drawModuleRoundendLight(ctx, l, t, r, b, rad, nw, ne, se, sw) { + if (nw) { + ctx.moveTo(l + rad, t); + ctx.lineTo(l, t); + ctx.lineTo(l, t + rad); + ctx.arcTo(l, t, l + rad, t, rad); + } + + if (ne) { + ctx.moveTo(r - rad, t); + ctx.lineTo(r, t); + ctx.lineTo(r, t + rad); + ctx.arcTo(r, t, r - rad, t, rad); + } + + if (se) { + ctx.moveTo(r - rad, b); + ctx.lineTo(r, b); + ctx.lineTo(r, b - rad); + ctx.arcTo(r, b, r - rad, b, rad); + } + + if (sw) { + ctx.moveTo(l + rad, b); + ctx.lineTo(l, b); + ctx.lineTo(l, b - rad); + ctx.arcTo(l, b, l + rad, b, rad); + } + } + + function drawModuleRounded(qr, context, settings, left, top, width, row, col) { + var isDark = qr.isDark; + var right = left + width; + var bottom = top + width; + var radius = settings.radius * width; + var rowT = row - 1; + var rowB = row + 1; + var colL = col - 1; + var colR = col + 1; + var center = isDark(row, col); + var northwest = isDark(rowT, colL); + var north = isDark(rowT, col); + var northeast = isDark(rowT, colR); + var east = isDark(row, colR); + var southeast = isDark(rowB, colR); + var south = isDark(rowB, col); + var southwest = isDark(rowB, colL); + var west = isDark(row, colL); + + if (center) { + drawModuleRoundedDark(context, left, top, right, bottom, radius, !north && !west, !north && !east, !south && !east, !south && !west); + } else { + drawModuleRoundendLight(context, left, top, right, bottom, radius, north && west && northwest, north && east && northeast, south && east && southeast, south && west && southwest); + } + } + + function drawModules(qr, context, settings) { + var moduleCount = qr.moduleCount; + var moduleSize = settings.size / moduleCount; + var fn = drawModuleDefault; + var row; + var col; + + if (settings.radius > 0 && settings.radius <= 0.5) { + fn = drawModuleRounded; + } + + context.beginPath(); + for (row = 0; row < moduleCount; row += 1) { + for (col = 0; col < moduleCount; col += 1) { + var l = settings.left + col * moduleSize; + var t = settings.top + row * moduleSize; + var w = moduleSize; + + fn(qr, context, settings, l, t, w, row, col); + } + } + if (jq(settings.fill).is('img')) { + context.strokeStyle = 'rgba(0,0,0,0.5)'; + context.lineWidth = 2; + context.stroke(); + var prev = context.globalCompositeOperation; + context.globalCompositeOperation = 'destination-out'; + context.fill(); + context.globalCompositeOperation = prev; + + context.clip(); + context.drawImage(settings.fill, 0, 0, settings.size, settings.size); + context.restore(); + } else { + context.fillStyle = settings.fill; + context.fill(); + } + } + + // Draws QR code to the given `canvas` and returns it. + function drawOnCanvas(canvas, settings) { + var qr = createMinQRCode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet); + if (!qr) { + return null; + } + + var $canvas = jq(canvas).data('qrcode', qr); + var context = $canvas[0].getContext('2d'); + + drawBackground(qr, context, settings); + drawModules(qr, context, settings); + + return $canvas; + } + + // Returns a `canvas` element representing the QR code for the given settings. + function createCanvas(settings) { + var $canvas = jq('').attr('width', settings.size).attr('height', settings.size); + return drawOnCanvas($canvas, settings); + } + + // Returns an `image` element representing the QR code for the given settings. + function createImage(settings) { + return jq('').attr('src', createCanvas(settings)[0].toDataURL('image/png')); + } + + // Returns a `div` element representing the QR code for the given settings. + function createDiv(settings) { + var qr = createMinQRCode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet); + if (!qr) { + return null; + } + + // some shortcuts to improve compression + var settings_size = settings.size; + var settings_bgColor = settings.background; + var math_floor = Math.floor; + + var moduleCount = qr.moduleCount; + var moduleSize = math_floor(settings_size / moduleCount); + var offset = math_floor(0.5 * (settings_size - moduleSize * moduleCount)); + + var row; + var col; + + var containerCSS = { + position: 'relative', + left: 0, + top: 0, + padding: 0, + margin: 0, + width: settings_size, + height: settings_size + }; + var darkCSS = { + position: 'absolute', + padding: 0, + margin: 0, + width: moduleSize, + height: moduleSize, + 'background-color': settings.fill + }; + + var $div = jq(' + + + + + exists() && $user->has_cap('manage_options')) { + $admin_email_lifespan = (int) get_option('admin_email_lifespan'); + + // If `0` (or anything "falsey" as it is cast to int) is returned, the user will not be redirected + // to the admin email confirmation screen. + // This filter is documented in wp-login.php + $admin_email_check_interval = (int) apply_filters('admin_email_check_interval', 6 * MONTH_IN_SECONDS); + + if ($admin_email_check_interval > 0 && time() > $admin_email_lifespan) { + $redirect_to = add_query_arg( + array( + 'action' => 'confirm_admin_email', + 'wp_lang' => get_user_locale($user), + ), + wp_login_url($redirect_to) + ); + } + } + + if ((empty($redirect_to) || 'wp-admin/' === $redirect_to || admin_url() === $redirect_to)) { + // If the user doesn't belong to a blog, send them to user admin. If the user can't edit posts, send them to their profile. + if (is_multisite() && ! get_active_blog_for_user($user->ID) && ! is_super_admin($user->ID)) { + $redirect_to = user_admin_url(); + } elseif (is_multisite() && ! $user->has_cap('read')) { + $redirect_to = get_dashboard_url($user->ID); + } elseif (! $user->has_cap('edit_posts')) { + $redirect_to = $user->has_cap('read') ? admin_url('profile.php') : home_url(); + } + + wp_redirect($redirect_to); + exit; + } + + wp_safe_redirect($redirect_to); + exit; + } + + $errors = $user; + // Clear errors if loggedout is set. + if (! empty($_GET['loggedout']) || $reauth) { + $errors = new WP_Error(); + } + + if (empty($_POST) && $errors->get_error_codes() === array('empty_username', 'empty_password')) { + $errors = new WP_Error('', ''); + } + + if ($interim_login) { + if (! $errors->has_errors()) { + $errors->add('expired', __('Your session has expired. Please log in to continue where you left off.'), 'message'); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- ignore this to use WordPress translation + } + } else { + // Some parts of this script use the main login form to display a message. + if (isset($_GET['loggedout']) && sanitize_text_field(wp_unslash($_GET['loggedout']))) { + $errors->add('loggedout', __('You are now logged out.'), 'message'); + } elseif (isset($_GET['registration']) && 'disabled' === $_GET['registration']) { + $errors->add('registerdisabled', __('Error: User registration is currently not allowed.')); + } elseif (strpos($redirect_to, 'about.php?updated')) { + $errors->add('updated', __('You have successfully updated WordPress! Please log back in to see what’s new.'), 'message'); + } elseif (WP_Recovery_Mode_Link_Service::LOGIN_ACTION_ENTERED === $action) { + $errors->add('enter_recovery_mode', __('Recovery Mode Initialized. Please log in to continue.'), 'message'); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- ignore this to use WordPress translation + } elseif (isset($_GET['redirect_to']) && false !== strpos(sanitize_url(wp_unslash($_GET['redirect_to'])), 'wp-admin/authorize-application.php')) { + $query_component = wp_parse_url(sanitize_url(wp_unslash($_GET['redirect_to'])), PHP_URL_QUERY); + parse_str($query_component, $query); + + if (! empty($query['app_name'])) { + /* translators: 1: Website name, 2: Application name. */ + $message = sprintf('Please log in to %1$s to authorize %2$s to connect to your account.', get_bloginfo('name', 'display'), '' . esc_html($query['app_name']) . ''); + } else { + /* translators: %s: Website name. */ + $message = sprintf('Please log in to %s to proceed with authorization.', get_bloginfo('name', 'display')); + } + + $errors->add('authorize_application', $message, 'message'); + } + } + + /** + * Filters the login page errors. + * + * @since 3.6.0 + * + * @param WP_Error $errors WP Error object. + * @param string $redirect_to Redirect destination URL. + */ + $errors = apply_filters('wp_login_errors', $errors, $redirect_to); + + // Clear any stale cookies. + if ($reauth) { + wp_clear_auth_cookie(); + } + + login_header(__('Log In'), '', $errors); + + if (isset($_POST['log'])) { + $user_login = ('incorrect_password' === $errors->get_error_code() || 'empty_password' === $errors->get_error_code()) ? esc_attr(sanitize_text_field(wp_unslash($_POST['log']))) : ''; + } + + $rememberme = ! empty($_POST['rememberme']); + + $aria_describedby = ''; + $has_errors = $errors->has_errors(); + + if ($has_errors) { + $aria_describedby = ' aria-describedby="login_error"'; + } + + if ($has_errors && 'message' === $errors->get_error_data()) { + $aria_describedby = ' aria-describedby="login-message"'; + } + + wp_enqueue_script('user-profile'); + + //aiowps - this check is necessary because otherwise if variables are undefined we get a warning! + if (empty($user_login)) { + $user_login = ''; + } + if (empty($error)) { + $error = ''; + } + ?> + +
+

+ + class="input" value="" size="20" autocapitalize="off" /> +

+ +
+ +
+ class="input password-input" value="" size="20" /> + +
+
+ +

/>

+

+ + + + + + + + + +

+
+ + + + get_error_code() === 'invalid_username') { + $login_script .= 'd.value = "";'; + } + } + + $login_script .= 'd.focus(); d.select();'; + $login_script .= '} catch(er) {}'; + $login_script .= '}, 200);'; + $login_script .= "}\n"; // End of wp_attempt_focus(). + + /** + * Filters whether to print the call to `wp_attempt_focus()` on the login screen. + * + * @since 4.8.0 + * + * @param bool $print Whether to print the function call. Default true. + */ + if (apply_filters('enable_login_autofocus', true) && ! $error) { + $login_script .= "wp_attempt_focus();\n"; + } + + // Run `wpOnload()` if defined. + $login_script .= "if (typeof wpOnload === 'function') { wpOnload() }"; + ?> + + + + configs->get_value('aiowps_login_page_slug'); +$custom_login_url = home_url('/' . ltrim($login_slug, '/') . '/'); + +// Redirect to HTTPS login if forced to use SSL. +if (force_ssl_admin() && !is_ssl()) { + $request_uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : ''; + if (0 === strpos($request_uri, 'http')) { + wp_safe_redirect(set_url_scheme($request_uri, 'https')); + exit; + } else { + wp_safe_redirect('https://' . isset($_SERVER['HTTP_HOST']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'])) : '' . $request_uri); + exit; + } +} + +/** + * Outputs the login page header. + * + * @since 2.1.0 + * + * @global string $error Login error message set by deprecated pluggable wp_login() function + * or plugins replacing it. + * @global bool|string $interim_login Whether interim login modal is being displayed. String 'success' + * upon successful login. + * @global string $action The action that brought the visitor to the login page. + * + * @param string|null $title Optional. WordPress login page title to display in the `` element. + * Defaults to 'Log In'. + * @param string $message Optional. Message to display in header. Default empty. + * @param WP_Error|null $wp_error Optional. The error to pass. Defaults to a WP_Error instance. + */ +function login_header($title = null, $message = '', $wp_error = null) { + global $error, $interim_login, $action; + + if (null === $title) { + $title = __('Log In'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. This is a default WordPress translation string + } + + // Don't index any of these forms. + add_filter('wp_robots', 'wp_robots_sensitive_page'); + add_action('login_head', 'wp_strict_cross_origin_referrer'); + + add_action('login_head', 'wp_login_viewport_meta'); + + if (!is_wp_error($wp_error)) { + $wp_error = new WP_Error(); + } + + // Shake it! + $shake_error_codes = array('empty_password', 'empty_email', 'invalid_email', 'invalidcombo', 'empty_username', 'invalid_username', 'incorrect_password', 'retrieve_password_email_failure'); + /** + * Filters the error codes array for shaking the login form. + * + * @since 3.0.0 + * + * @param string[] $shake_error_codes Error codes that shake the login form. + */ + $shake_error_codes = apply_filters('shake_error_codes', $shake_error_codes); + + if ($shake_error_codes && $wp_error->has_errors() && in_array($wp_error->get_error_code(), $shake_error_codes, true)) { + add_action('login_footer', 'wp_shake_js', 12); + } + + $login_title = get_bloginfo('name', 'display'); + + /* translators: Login screen title. 1: Login screen name, 2: Network or site name. */ + $login_title = sprintf(__('%1$s ‹ %2$s — WordPress'), $title, $login_title); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. This is a default WordPress translation string + + if (wp_is_recovery_mode()) { + /* translators: %s: Login screen title. */ + $login_title = sprintf(__('Recovery Mode — %s'), $login_title); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. This is a default WordPress translation string + } + + /** + * Filters the title tag content for login page. + * + * @since 4.9.0 + * + * @param string $login_title The page title, with extra context added. + * @param string $title The original page title. + */ + $login_title = apply_filters('login_title', $login_title, $title); + ?><!DOCTYPE html> + <html <?php language_attributes(); ?>> + <head> + <meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" /> + <title><?php echo esc_html($login_title); ?> + get_error_code()) { + ob_start(); + ?> + + + + + + + + + + +

+ +
+

+ add('error', $error); + unset($error); + } + + if ($wp_error->has_errors()) { + $error_list = array(); + $messages = ''; + + foreach ($wp_error->get_error_codes() as $code) { + $severity = $wp_error->get_error_data($code); + foreach ($wp_error->get_error_messages($code) as $error_message) { + if ('message' === $severity) { + $messages .= '

' . $error_message . '

'; + } else { + $error_list[] = $error_message; + } + } + } + + if (!empty($error_list)) { + $errors = ''; + + if (count($error_list) > 1) { + $errors .= ''; + } else { + $errors .= '

' . $error_list[0] . '

'; + } + + /** + * Filters the error messages displayed above the login form. + * + * @since 2.1.0 + * + * @param string $errors Login error messages. + */ + $errors = apply_filters('login_errors', $errors); + + wp_admin_notice( + $errors, + array( + 'type' => 'error', + 'id' => 'login_error', + 'paragraph_wrap' => false, + ) + ); + } + + if (!empty($messages)) { + /** + * Filters instructional messages displayed above the login form. + * + * @since 2.5.0 + * + * @param string $messages Login messages. + */ + $messages = apply_filters('login_messages', $messages); + + wp_admin_notice( + $messages, + array( + 'type' => 'info', + 'id' => 'login-message', + 'additional_classes' => array('message'), + 'paragraph_wrap' => false, + ) + ); + } + } +} // End of login_header(). + +/** + * Outputs the footer for the login page. + * + * @since 3.1.0 + * + * @global bool|string $interim_login Whether interim login modal is being displayed. String 'success' + * upon successful login. + * + * @param string $input_id Which input to auto-focus. + */ +function login_footer($input_id = '') { + global $interim_login, $aio_wp_security; + + // Don't allow interim logins to navigate away from the page. + if (!$interim_login) { + ?> +

+ %s', + esc_url(home_url('/')), + sprintf( + /* translators: %s: Site title. */ + _x('← Go to %s', 'site'), + get_bloginfo('title', 'display') + ) + ); + /** + * Filters the "Go to site" link displayed in the login page footer. + * + * @since 5.7.0 + * + * @param string $link HTML link to the home URL of the current site. + */ + echo apply_filters('login_site_html_link', $html_link); + ?> +

+ ', '
'); + } + ?> + . ?> + +
+
+ + + + 'language-switcher-locales', + 'name' => 'wp_lang', + 'selected' => determine_locale(), + 'show_available_translations' => false, + 'explicit_option_en_us' => true, + 'languages' => $languages, + ); + + /** + * Filters default arguments for the Languages select input on the login screen. + * + * The arguments get passed to the wp_dropdown_languages() function. + * + * @since 5.9.0 + * + * @param array $args Arguments for the Languages select input on the login screen. + */ + wp_dropdown_languages(apply_filters('login_language_dropdown_args', $args)); + ?> + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + 0) { + update_option('admin_email_lifespan', time() + $remind_interval); + } + + $redirect_to = add_query_arg('admin_email_remind_later', 1, $redirect_to); + wp_safe_redirect($redirect_to); + exit; + } + + if (!empty($_POST['correct-admin-email'])) { + if (!check_admin_referer('confirm_admin_email', 'confirm_admin_email_nonce')) { + wp_safe_redirect($custom_login_url); + exit; + } + + /** + * Filters the interval for redirecting the user to the admin email confirmation screen. + * + * If `0` (zero) is returned, the user will not be redirected. + * + * @since 5.3.0 + * + * @param int $interval Interval time (in seconds). Default is 6 months. + */ + $admin_email_check_interval = (int) apply_filters('admin_email_check_interval', 6 * MONTH_IN_SECONDS); + + if ($admin_email_check_interval > 0) { + update_option('admin_email_lifespan', time() + $admin_email_check_interval); + } + + wp_safe_redirect($redirect_to); + exit; + } + + login_header(__('Confirm your administration email'), '', $errors); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. This is a default WordPress translation string + + /** + * Fires before the admin email confirm form. + * + * @since 5.3.0 + * + * @param WP_Error $errors A `WP_Error` object containing any errors generated by using invalid + * credentials. Note that the error object may not contain any errors. + */ + do_action('admin_email_confirm', $errors); + ?> + +
+ + + +

+ +

+

+ administration email for this website is still correct.'); ?> + %s', + /* translators: Hidden accessibility text. */ + __('(opens in a new tab)') // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. This is a default WordPress translation string + ); + + printf( + '%s%s', + esc_url($admin_email_help_url), + __('Why is this important?'), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. This is a default WordPress translation string + wp_kses_post($accessibility_text) + ); + ?> +

+

+ ' . esc_html($admin_email) . '' + ); + ?> +

+

+ +

+ +
+
+ + + +
+ +
+ 'confirm_admin_email', + 'remind_me_later' => wp_create_nonce('remind_me_later_nonce'), + ), + $remind_me_link + ); + ?> + +
+ +
+
+ + HashPassword(wp_unslash($_POST['post_password'])), $expire, COOKIEPATH, COOKIE_DOMAIN, $secure); + + wp_safe_redirect(wp_get_referer()); + exit; + + case 'logout': + check_admin_referer('log-out'); + + $user = wp_get_current_user(); + + wp_logout(); + + if (!empty($_REQUEST['redirect_to']) && is_string($_REQUEST['redirect_to'])) { + $redirect_to = sanitize_url(wp_unslash($_REQUEST['redirect_to'])); + $requested_redirect_to = $redirect_to; + } else { + $redirect_to = add_query_arg( + array( + 'loggedout' => 'true', + 'wp_lang' => get_user_locale($user), + ), + $custom_login_url + ); + + $requested_redirect_to = ''; + } + + /** + * Filters the log out redirect URL. + * + * @since 4.2.0 + * + * @param string $redirect_to The redirect destination URL. + * @param string $requested_redirect_to The requested redirect destination URL passed as a parameter. + * @param WP_User $user The WP_User object for the user that's logging out. + */ + $redirect_to = apply_filters('logout_redirect', $redirect_to, $requested_redirect_to, $user); + + wp_safe_redirect($redirect_to); + exit; + + case 'lostpassword': + case 'retrievepassword': + if ($http_post) { + $errors = retrieve_password(); + + if (!is_wp_error($errors)) { + $redirect_to = !empty($_REQUEST['redirect_to']) ? sanitize_url(wp_unslash($_REQUEST['redirect_to'])) : 'wp-login.php?checkemail=confirm'; + wp_safe_redirect($redirect_to); + exit; + } + } + + if (isset($_GET['error'])) { + if ('invalidkey' === $_GET['error']) { + $errors->add('invalidkey', __('Your password reset link appears to be invalid. Please request a new link below.')); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + } elseif ('expiredkey' === $_GET['error']) { + $errors->add('expiredkey', __('Your password reset link has expired. Please request a new link below.')); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + } + } + + $lostpassword_redirect = !empty($_REQUEST['redirect_to']) ? sanitize_url(wp_unslash($_REQUEST['redirect_to'])) : ''; + /** + * Filters the URL redirected to after submitting the lostpassword/retrievepassword form. + * + * @since 3.0.0 + * + * @param string $lostpassword_redirect The redirect destination URL. + */ + $redirect_to = apply_filters('lostpassword_redirect', $lostpassword_redirect); + + /** + * Fires before the lost password form. + * + * @since 1.5.1 + * @since 5.1.0 Added the `$errors` parameter. + * + * @param WP_Error $errors A `WP_Error` object containing any errors generated by using invalid + * credentials. Note that the error object may not contain any errors. + */ + do_action('lost_password', $errors); + + login_header( + __('Lost Password'), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. This is a default WordPress translation string + wp_get_admin_notice( + __('Please enter your username or email address. You will receive an email message with instructions on how to reset your password.'), // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + array( + 'type' => 'info', + 'additional_classes' => array('message'), + ) + ), + $errors + ); + + $user_login = ''; + + if (isset($_POST['user_login']) && is_string($_POST['user_login'])) { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized below. + $user_login = wp_unslash($_POST['user_login']); // Remove slashes first + + if (is_email($user_login)) { + // Sanitize as an email address + $user_login = sanitize_email($user_login); + } else { + // Sanitize as a username + $user_login = sanitize_user($user_login, true); + } + } + + ?> + +
+

+ + +

+ + +

+ +

+
+ + + get_error_code() === 'expired_key') { + wp_redirect(site_url('wp-login.php?action=lostpassword&error=expiredkey')); + } else { + wp_redirect(site_url('wp-login.php?action=lostpassword&error=invalidkey')); + } + + exit; + } + + $errors = new WP_Error(); + + // Check if password is one or all empty spaces. + if (!empty($_POST['pass1'])) { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Not recommended to sanitize password. + $_POST['pass1'] = trim($_POST['pass1']); + + if (empty($_POST['pass1'])) { + $errors->add('password_reset_empty_space', __('The password cannot be a space or all spaces.')); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + } + } + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Not recommended to sanitize password. + // Check if password fields do not match. + if (!empty($_POST['pass1']) && trim($_POST['pass2']) !== $_POST['pass1']) { + $errors->add('password_reset_mismatch', __('Error: The passwords do not match.')); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + } + + /** + * Fires before the password reset procedure is validated. + * + * @since 3.5.0 + * + * @param WP_Error $errors WP Error object. + * @param WP_User|WP_Error $user WP_User object if the login and reset key match. WP_Error object otherwise. + */ + do_action('validate_password_reset', $errors, $user); + + if ((!$errors->has_errors()) && isset($_POST['pass1']) && !empty($_POST['pass1'])) { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Not recommended to sanitize password. + reset_password($user, $_POST['pass1']); + setcookie($rp_cookie, ' ', time() - YEAR_IN_SECONDS, $rp_path, COOKIE_DOMAIN, is_ssl(), true); + login_header( + __('Password Reset'), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. This is a default WordPress translation string + wp_get_admin_notice( + __('Your password has been reset.') . ' ' . __('Log in') . '', // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + array( + 'type' => 'info', + 'additional_classes' => array('message', 'reset-pass'), + ) + ) + ); + login_footer(); + exit; + } + + wp_enqueue_script('utils'); + wp_enqueue_script('user-profile'); + + login_header( + __('Reset Password'), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. This is a default WordPress translation string + wp_get_admin_notice( + __('Enter your new password below or generate one.'), // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + array( + 'type' => 'info', + 'additional_classes' => array('message', 'reset-pass'), + ) + ), + $errors + ); + ?> +
+ + +
+

+ +

+ +
+ + + +
+
+
+ + +
+
+ +

+ + +

+ +

+ + + +

+ + +

+
+ + + 'info', + 'additional_classes' => array('message', 'register'), + ) + ), + $errors + ); + ?> +
+

+ + +

+

+ + +

+ +

+ +

+ +

+ +

+
+ + + add( + 'confirm', + sprintf( + /* translators: %s: Link to the login page. */ + __('Check your email for the confirmation link, then visit the login page.'), // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + $custom_login_url + ), + 'message' + ); + } elseif ('registered' === $_GET['checkemail']) { + $errors->add( + 'registered', + sprintf( + /* translators: %s: Link to the login page. */ + __('Registration complete. Please check your email, then visit the login page.'), // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + $custom_login_url + ), + 'message' + ); + } + + /* This action is documented in wp-login.php */ + $errors = apply_filters('wp_login_errors', $errors, $redirect_to); + + login_header(__('Check your email'), '', $errors); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. This is a default WordPress translation string + login_footer(); + break; + + case 'confirmaction': + if (!isset($_GET['request_id'])) { + wp_die(__('Missing request ID.')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. This is a default WordPress translation string + } + + if (!isset($_GET['confirm_key'])) { + wp_die(__('Missing confirm key.')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. This is a default WordPress translation string + } + + $request_id = (int) $_GET['request_id']; + $key = sanitize_text_field(wp_unslash($_GET['confirm_key'])); + $result = wp_validate_user_request_key($request_id, $key); + + if (is_wp_error($result)) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- WP_Error is an object and cannot be escaped. + wp_die($result); + } + + /** + * Fires an action hook when the account action has been confirmed by the user. + * + * Using this you can assume the user has agreed to perform the action by + * clicking on the link in the confirmation email. + * + * After firing this action hook the page will redirect to wp-login a callback + * redirects or exits first. + * + * @since 4.9.6 + * + * @param int $request_id Request ID. + */ + do_action('user_request_action_confirmed', $request_id); + + $message = _wp_privacy_account_request_confirmed_message($request_id); + + login_header(__('User action confirmed.'), $message); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. This is a default WordPress translation string + login_footer(); + exit; + + case 'login': + default: + $secure_cookie = ''; + $customize_login = isset($_REQUEST['customize-login']); + + if ($customize_login) { + wp_enqueue_script('customize-base'); + } + + // If the user wants SSL but the session is not SSL, force a secure cookie. + if (!empty($_POST['log']) && !force_ssl_admin()) { + $user_name = sanitize_user(wp_unslash($_POST['log'])); + $user = get_user_by('login', $user_name); + + if (!$user && strpos($user_name, '@')) { + $user = get_user_by('email', $user_name); + } + + if ($user) { + if (get_user_option('use_ssl', $user->ID)) { + $secure_cookie = true; + force_ssl_admin(true); + } + } + } + + if (isset($_REQUEST['redirect_to']) && is_string($_REQUEST['redirect_to'])) { + $redirect_to = sanitize_url(wp_unslash($_REQUEST['redirect_to'])); + // Redirect to HTTPS if user wants SSL. + if ($secure_cookie && str_contains($redirect_to, 'wp-admin')) { + $redirect_to = preg_replace('|^http://|', 'https://', $redirect_to); + } + } else { + $redirect_to = admin_url(); + } + + $reauth = empty($_REQUEST['reauth']) ? false : true; + + $user = wp_signon(array(), $secure_cookie); + + if (empty($_COOKIE[LOGGED_IN_COOKIE])) { + if (headers_sent()) { + $user = new WP_Error( + 'test_cookie', + sprintf( + /* translators: 1: Browser cookie documentation URL, 2: Support forums URL. */ + __('Error: Cookies are blocked due to unexpected output. For help, please see this documentation or try the support forums.'), // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + esc_url(__('https://wordpress.org/support/article/cookies/')), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. This is a default WordPress translation string + esc_url(__('https://wordpress.org/support/forums/')) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. This is a default WordPress translation string + ) + ); + } elseif (isset($_POST['testcookie']) && empty($_COOKIE[TEST_COOKIE])) { + // If cookies are disabled, the user can't log in even with a valid username and password. + $user = new WP_Error( + 'test_cookie', + sprintf( + /* translators: %s: Browser cookie documentation URL. */ + __('%1$s: Cookies are blocked or not supported by your browser. You must %2$s to use WordPress.'), // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + '' . __('ERROR') . '', // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. This is a default WordPress translation string + '' . __('enable cookies') . '' // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. This is a default WordPress translation string + ) + ); + } + } + + $requested_redirect_to = isset($_REQUEST['redirect_to']) && is_string($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : ''; + + /** + * Filters the login redirect URL. + * + * @since 3.0.0 + * + * @param string $redirect_to The redirect destination URL. + * @param string $requested_redirect_to The requested redirect destination URL passed as a parameter. + * @param WP_User|WP_Error $user WP_User object if login was successful, WP_Error object otherwise. + */ + $redirect_to = apply_filters('login_redirect', $redirect_to, $requested_redirect_to, $user); + + if (!is_wp_error($user) && !$reauth) { + if ($interim_login) { + $message = '

' . __('You have logged in successfully.') . '

'; // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + $interim_login = 'success'; + login_header('', $message); + ?> + + + + + + exists() && $user->has_cap('manage_options')) { + $admin_email_lifespan = (int) get_option('admin_email_lifespan'); + + /* + * If `0` (or anything "falsey" as it is cast to int) is returned, the user will not be redirected + * to the admin email confirmation screen. + */ + /*This filter is documented in wp-login.php */ + $admin_email_check_interval = (int) apply_filters('admin_email_check_interval', 6 * MONTH_IN_SECONDS); + + if ($admin_email_check_interval > 0 && time() > $admin_email_lifespan) { + + $redirect_to = add_query_arg( + array( + 'action' => 'confirm_admin_email', + 'wp_lang' => get_user_locale($user), + ), + wp_login_url($redirect_to) + ); + } + } + + if ((empty($redirect_to) || 'wp-admin/' === $redirect_to || admin_url() === $redirect_to)) { + // If the user doesn't belong to a blog, send them to user admin. If the user can't edit posts, send them to their profile. + if (is_multisite() && !get_active_blog_for_user($user->ID) && !is_super_admin($user->ID)) { + $redirect_to = user_admin_url(); + } elseif (is_multisite() && !$user->has_cap('read')) { + $redirect_to = get_dashboard_url($user->ID); + } elseif (!$user->has_cap('edit_posts')) { + $redirect_to = $user->has_cap('read') ? admin_url('profile.php') : home_url(); + } + + wp_redirect($redirect_to); + exit; + } + + wp_safe_redirect($redirect_to); + exit; + } + + $errors = $user; + // Clear errors if loggedout is set. + if (!empty($_GET['loggedout']) || $reauth) { + $errors = new WP_Error(); + } + + if (empty($_POST) && $errors->get_error_codes() === array('empty_username', 'empty_password')) { + $errors = new WP_Error('', ''); + } + + if ($interim_login) { + if (!$errors->has_errors()) { + $errors->add('expired', __('Your session has expired. Please log in to continue where you left off.'), 'message'); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- ignore this to use WordPress translation + } + } else { + // Some parts of this script use the main login form to display a message. + if (isset($_GET['loggedout']) && $_GET['loggedout']) { + $errors->add('loggedout', __('You are now logged out.'), 'message'); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + } elseif (isset($_GET['registration']) && 'disabled' === $_GET['registration']) { + $errors->add('registerdisabled', __('Error: User registration is currently not allowed.')); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + } elseif (str_contains($redirect_to, 'about.php?updated')) { + $errors->add('updated', __('You have successfully updated WordPress! Please log back in to see what’s new.'), 'message'); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + } elseif (WP_Recovery_Mode_Link_Service::LOGIN_ACTION_ENTERED === $action) { + $errors->add('enter_recovery_mode', __('Recovery Mode Initialized.') . ' ' . __('Please log in to continue.'), 'message'); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + } elseif (isset($_GET['redirect_to']) && false !== strpos(sanitize_url(wp_unslash($_GET['redirect_to'])), 'wp-admin/authorize-application.php')) { + $query_component = wp_parse_url(sanitize_url(wp_unslash($_GET['redirect_to'])), PHP_URL_QUERY); + $query = array(); + if ($query_component) { + parse_str($query_component, $query); + } + + if (!empty($query['app_name'])) { + /* translators: 1: Website name, 2: Application name. */ + $message = sprintf('Please log in to %1$s to authorize %2$s to connect to your account.', get_bloginfo('name', 'display'), '' . esc_html($query['app_name']) . ''); + } else { + /* translators: %s: Website name. */ + $message = sprintf('Please log in to %s to proceed with authorization.', get_bloginfo('name', 'display')); + } + + $errors->add('authorize_application', $message, 'message'); + } + } + + /** + * Filters the login page errors. + * + * @since 3.6.0 + * + * @param WP_Error $errors WP Error object. + * @param string $redirect_to Redirect destination URL. + */ + $errors = apply_filters('wp_login_errors', $errors, $redirect_to); + + // Clear any stale cookies. + if ($reauth) { + wp_clear_auth_cookie(); + } + + login_header(__('Log In'), '', $errors); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. This is a default WordPress translation string + + if (isset($_POST['log'])) { + $user_login = ('incorrect_password' === $errors->get_error_code() || 'empty_password' === $errors->get_error_code()) ? esc_attr(sanitize_text_field(wp_unslash($_POST['log']))) : ''; + } + + $rememberme = !empty($_POST['rememberme']); + + $aria_describedby = ''; + $has_errors = $errors->has_errors(); + + if ($has_errors) { + $aria_describedby = ' aria-describedby="login_error"'; + } + + if ($has_errors && 'message' === $errors->get_error_data()) { + $aria_describedby = ' aria-describedby="login-message"'; + } + + wp_enqueue_script('user-profile'); + + //aiowps - this check is necessary because otherwise if variables are undefined we get a warning! + if (empty($user_login)) { + $user_login = ''; + } + if (empty($error)) { + $error = ''; + } + ?> + +
+

+ + class="input" value="" size="20" autocapitalize="off" autocomplete="username" required="required" /> +

+ +
+ +
+ class="input password-input" value="" size="20" autocomplete="current-password" spellcheck="false" required="required" /> + +
+
+ +

/>

+

+ + + + + + + + + +

+
+ + + + get_error_code() === 'invalid_username') { + $login_script .= 'd.value = "";'; + } + } + + $login_script .= 'd.focus(); d.select();'; + $login_script .= '} catch(er) {}'; + $login_script .= '}, 200);'; + $login_script .= "}\n"; // End of wp_attempt_focus(). + + /** + * Filters whether to print the call to `wp_attempt_focus()` on the login screen. + * + * @since 4.8.0 + * + * @param bool $print Whether to print the function call. Default true. + */ + if (apply_filters('enable_login_autofocus', true) && !$error) { + $login_script .= "wp_attempt_focus();\n"; + } + + // Run `wpOnload()` if defined. + $login_script .= "if (typeof wpOnload === 'function') { wpOnload() }"; + + wp_print_inline_script_tag($login_script); + + if ($interim_login) { + ob_start(); + ?> + + + + + +<?php bloginfo('name'); ?> + + + + +
+

+ +configs->get_value('aiowps_unlock_request_secret_key'); + $unlock_temp_string = isset($_POST['aiowps-unlock-temp-string']) ? strip_tags($_POST['aiowps-unlock-temp-string']) : ''; + $submitted_encoded_string = base64_encode($unlock_temp_string.$unlock_secret_string); + if ($submitted_encoded_string !== $unlock_encoded_info) { + //Someone somehow landed on this page directly without clicking the unlock button on login form + echo '
'.__('ERROR: Unable to process your request!', 'all-in-one-wp-security-and-firewall').'
'; + die(); + } elseif ($display_form) { + echo display_unlock_form(); + } +} //End if block + +if (isset($_POST['aiowps_wp_submit_unlock_request'])) { + //This catches the $_POST when someone submits the form from our special unlock request page where visitor enters email address + $errors = ''; + + $email = trim($_POST['aiowps_unlock_request_email']); + if (empty($email) || !is_email($email)) { + $errors .= '

'.__('Please enter a valid email address', 'all-in-one-wp-security-and-firewall').'

'; + } + + if ($errors) { + $display_form = true; + echo '
'.$errors.'
'; + $sanitized_email = sanitize_email($email); + echo display_unlock_form($sanitized_email); + } else { + $locked_user = get_user_by('email', $email); + if (!$locked_user) { + //user with this email does not exist in the system + $errors .= '

'.__('User account not found!', 'all-in-one-wp-security-and-firewall').'

'; + echo '
'.$errors.'
'; + } else { + //Process unlock request + //Generate a special code and unlock url + $ip = AIOWPSecurity_Utility_IP::get_user_ip_address(); //Get the IP address of user + if (empty($ip)) { + $unlock_url = false; + } else { + $unlock_url = AIOWPSecurity_User_Login::generate_unlock_request_link($ip); + } + + if (!$unlock_url) { + //No entry found in lockout table with this IP range + $error_msg = '

'.__('Error: No locked entry was found in the database with your IP address range.', 'all-in-one-wp-security-and-firewall').'

'; + echo '
'.$error_msg.'
'; + } else { + //Send an email to the user + AIOWPSecurity_User_Login::send_unlock_request_email($email, $unlock_url); + echo '

' . __('An email has been sent to you with the unlock instructions.', 'all-in-one-wp-security-and-firewall') . '

'; + } + } + $display_form = false; + } +} +?> +
+ + + +' . __('You are here because you have been locked out due to too many incorrect login attempts.', 'all-in-one-wp-security-and-firewall') . '

' + . '

' . __('Please enter your email address and you will receive an email with instructions on how to unlock yourself.', 'all-in-one-wp-security-and-firewall') . '

'; +?> +
+
+ '; + } + ?> +

+ +

+

+ +

+
+configs->get_value('aiowps_site_lockout_msg'); +if (empty($aiowps_site_lockout_msg_raw)) { + $aiowps_site_lockout_msg_raw = '

This site is currently not available. Please try again later.

'; +} +$maintenance_msg = html_entity_decode($aiowps_site_lockout_msg_raw, ENT_COMPAT, "UTF-8"); +$maintenance_msg = apply_filters('the_content', $maintenance_msg); +?> + + + + + <?php bloginfo('name'); ?> + + + + + + +
+
+
+
+ +
+
+
+
+ + \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/readme.txt b/wp-content/plugins/all-in-one-wp-security-and-firewall/readme.txt new file mode 100755 index 00000000..23064d9a --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/readme.txt @@ -0,0 +1,1649 @@ +=== All-In-One Security (AIOS) – Security and Firewall === +Contributors: DavidAnderson, pmbaldha, Tips and Tricks HQ, wpsolutions, Peter Petreski, Ruhul Amin, mbrsolution +Donate link: https://david.dw-perspective.org.uk/donate +Tags: security, malware scanning, two factor authentication, firewall, login security +Requires PHP: 5.6 +Requires at least: 5.0 +Tested up to: 6.9 +Stable tag: 5.4.4 +License: GPLv3 or later + +Protect your website investment with All-In-One Security (AIOS) – a comprehensive and easy to use security plugin designed especially for WordPress. Featuring login security tools, a cutting-edge firewall and much more. + +== Description == + +### THE TOP RATED WORDPRESS SECURITY AND FIREWALL PLUGIN + +[All-in-One Security (AIOS)](https://teamupdraft.com/all-in-one-security?utm_source=aios-wp-dir&utm_medium=referral&utm_campaign=plugin-dir&utm_content=aios&utm_creative_format=description) is a WordPress security plugin from the same, trusted team that brought you UpdraftPlus. + +It’s called 'All-In-One' because it’s packed full of ways to keep your WordPress website(s) safe and secure. + +It includes: + +**Login security features** keep bots at bay. Lock out users based on a configurable number of login attempts, get two-factor authentication and more. + +**File and database security.** Get notified of file changes that occur outside of normal operations. Block access to key files and scan files and folders to spot insecure permissions. + +**Firewall.** Get PHP, .htaccess and 6G firewall rules courtesy of Perishable Press. Spot and block fake Google Bots and more! + +**Spam prevention.** Prevent annoying spam comments and reduce unnecessary load on the server. Automatically and permanently block IP addresses that exceed a set number of spam comments. + +**Audit log.** View events happening on your WordPress website. Find out if a plugin or theme has been added, removed, updated and more. + +#### WHY ALL-IN-ONE SECURITY? + +AIOS has a near-perfect **4.7 / 5-star user rating** across more than 1 million installs. + +Great for beginners and experts alike. AIOS guides you logically and clearly through each of its features which are all clearly explained. Security features are marked as basic, intermediate and advanced. Each step increases your security score. Turn them on and watch your protection grow! + +We have a large support team of software developers. That means we have the availability and the skillset to help you with the trickiest of queries. + +We comb the WordPress plugin directory for support tickets daily - most queries are responded to within 24 hours. + +Excellent plugin with numerous well-thought-out options for making a website more secure. I have been using it for years and am very happy with it. I recently had a small problem setting up a website and – even as a non-premium user – I received support very quickly. Highly recommended! + +For even more ways to stay safe and secure, upgrade to [AIOS Premium](https://teamupdraft.com/all-in-one-security/pricing?utm_source=aios-wp-dir&utm_medium=referral&utm_campaign=plugin-dir&utm_content=aios_premium&utm_creative_format=description) - it packs a punch security-wise, whilst being **extremely cost-competitive**. + +#### LOGIN SECURITY + +**Two-factor authentication (TFA)** - Require TFA for specific user roles. Supports Google Authenticator, Microsoft Authenticator, Authy, and many more. + +**Detect and manage 'admin' usernames** - Identify default 'admin' usernames and guide users to change them to protect against brute force attacks. + +**Identify and correct identical login and display names** - Detect cases where the display name matches the username and provide guidance to improve login security. + +**Prevent user enumeration** - Block unauthorised access to URLs that can reveal sensitive information such as usernames or other details. + +**Control login attempts** - Prevent brute force attacks by limiting the number of failed login attempts. Choose how many login attempts are allowed, set lockout durations, and more. + +**Force user logout** - Automatically log out users after a specified period of time. Unattended sessions are closed, reducing the risk of unauthorised access. + +**Manually approve new registrations** - Review and approve new user registrations to prevent spam and fake sign-ups. + +**Enhance WordPress salt security** - Adds 64 extra characters to WordPress salts, rotating them weekly. Makes cracking passwords virtually impossible, even if your database is stolen. + +#### Plugin Support +* If you have a question or problem with the All-In-One Security plugin, post it on the support forum and we will help you. Premium customers can log queries directly with the team via https://teamupdraft.com/all-in-one-security/ +**Monitor and manage active sessions** - If a user is logged in who shouldn't be, log them out or add them to a blacklist. + +#### SPAM PREVENTION + +**Block spam coming from bots** - Reduce the load on your server and improve the user experience by automatically blocking spam comments from bots. + +**Monitor spam IP addresses** - Monitor the IP addresses of people or bots leaving spam comments. Choose which ones to block based on a configurable number of comments left. + +#### FILE / DATABASE Security + +**Scan and fix file permissions** - Scan for insecure file permissions. Click once to fix issues and safeguard critical files and folders. + +**Disable PHP file editing** - Disable editing of PHP files (such as plugins and themes) via the dashboard. It’s often the first tool that attackers use as it allows for code execution. + +**Protect sensitive files** - Prevent access to files like readme.html that might reveal information about your WordPress installation. + +**File change scanner** - Get notified of any file changes which occur on your system. Exclude files and folders which change as part of normal operations. + +**Prevent image hotlinking** - Prevent other websites from displaying your images via hotlinking and protect server bandwidth. + +**Secure database backups** - Perform a database backup via UpdraftPlus from AIOS. Change the default 'wp_' prefix to hide your WordPress database from hackers. + +#### FIREWALL + +**Get .htaccess firewall rules** - Deny access to the .htaccess and wp-config.php files. Disable the server signature and limit file uploads to a configurable size.** + +Block access to the debug.log file and prevent Apache servers from listing the contents of a directory when an index.php file is not present + +**Get PHP firewall rules** - PHP firewall rules prevent malicious users from exploiting well-known vulnerabilities in XML-RPC. Safeguard your content by disabling RSS and Atom feeds and avoid cross-site scripting (XSS) attacks. +Block fake Google bots and POST requests made by bots - Block fake Google bots and stop bots from making POST requests by blocking IP addresses where the user-agent and referrer fields are blank. + +**Utilise 6G firewall rules** - Employ flexible blacklist rules to reduce the number of malicious URL requests that hit your website (courtesy of Perishable Press). + +**And more** - Blacklist (and whitelist) IP ranges and user agents and block unauthorized access to data by disabling REST API access for non-logged-in requests. + +#### TWO-FACTOR AUTHENTICATION ENHANCED [Premium] + +**Two-factor authentication** is included in the free plugin. Upgrade to Premium if you’d like to: +Require TFA after a set time period - Mandate TFA for all admins or other roles after their accounts reach a specified age. + +**Control how often TFA is required** - Set TFA to be required after a certain number of days on trusted devices instead of every login. + +**Customise design layout** - Adjust the TFA design to match your website’s existing layout and branding. +Emergency codes - Generate one-time use emergency codes to regain access if you lose your TFA device. + +**WordPress Multisite Compatible** - Ensure compatibility with WordPress multisite networks and their sub-sites for consistent TFA application. + +**Integration with login forms** - Integrate TFA with various login forms, including WooCommerce, Affiliates-WP, Elementor Pro, bbPress, and 'Theme My Login' without additional coding. + +#### SMART 404 BLOCKING [Premium] + +**Block IPs based on 404 errors** - Detect hackers probing your URLs via script and bots by the 404 errors they leave behind. + +**Smart 404 Configuration** - Set a figure for the maximum number of 404 events allowed before an IP address is blocked. Choose a time period within which the 404 events must occur (e.g., 10 errors within 10 minutes). + +**Smart 404 block by URL string** - Instantly block an IP address if a 404 event includes a specific URL string. + +**Smart 404 whitelisting** - Prevent particular IP addresses from being permanently blocked due to 404 events. + +#### COUNTRY BLOCKING [Premium] + +**Block traffic to the entire site or to specific pages or posts** - Useful if you’re an e-commerce site and you want to block sales to some countries for shipping or tax reasons. + +**Whitelist some users from blocked countries** - Whitelist IP addresses or IP ranges even if they are part of a blocked country. + +#### MALWARE SCANNING [Premium] + +**Automatic malware scanning** - Detect and protect against the latest malware, trojans, and spyware. +Alerts you to blacklisting by search engines - Monitor your site for blacklisting by search engines due to malicious code. + +**Response time monitoring** - Keep track of your website’s response time to identify and address any performance issues. + +**Uptime monitoring** - Checks your website’s uptime every 5 minutes and alerts you immediately if your site or server goes down. + +**Advice and malware removal** - Need hands-on advice and support for malware removal? Our team of genuine cybersecurity experts is here to help. + +**Notification if something’s amiss** - Receive notifications about any issues with your site so you can address problems before they escalate. + += Plugin Support = + +If you have a question or problem with the All-In-One Security plugin, post it on the support forum and we will help you. Premium customers can log queries directly with the team via https://teamupdraft.com/all-in-one-security + += Developers = + +* If you are a developer and you need some extra hooks or filters for this plugin then let us know. + += Translations = + +* All-In-One Security plugin can be translated to any language. + +Currently available translations: + +- English +- German +- Spanish +- French +- Hungarian +- Italian +- Swedish +- Russian +- Chinese +- Portuguese (Brazil) +- Persian + += Privacy Policy = + +This plugin may collect IP addresses for security reasons such as mitigating brute force login threats and malicious activity. + +The collected information is stored on your server. No information is transmitted to third parties or remote server locations. + += Usage = + +Go to the settings menu after you activate the plugin and follow the instructions. + +== Frequently Asked Questions == + += How is All-In-One Security (AIOS) supported? = +Customers of ‘Free’ AIOS can get support from this very webpage. Select ‘Support’ from the tabs above and post a topic. We aim to respond to all support requests within 24 hours during the working week. + += Is All-In-One Security compatible with other plugins? = +Yes. AIOS works smoothly with most popular WordPress plugins. + += Is All-in-One-Security regularly updated? = +Yes. WordPress Security is something that evolves over time. We update AIOS with new security features (and fixes if required) on a regular basis so you can be assured that your site will keep benefitting from new security protection techniques for as long as you need them. + += Will All-In-One Security slow down my website? = +No. + += Should I install All-In-One Security for free or should I purchase AIOS Premium? = +The decision is yours to make. ‘Free’ AIOS incorporates a web application firewall, comprehensive login security tools including two-factor authentication and all the latest recommended WordPress security practices and techniques. +But if your WordPress site is a business website, if it showcases what you do, or who you are, we generally recommend AIOS Premium. Prices start from as little as $70 for the year. + += What are the additional features of All-In-One Security Premium? = +AIOS Premium scans your WordPress website for malware whilst also monitoring your site's response time and uptime, notifying you of any issues within 24 hours, AIOS Premium customers also benefit from hands-on ticketed support via email (rather than via WP Support forums). +Additional security tools include Country Blocking, Smart 404 Error Blocking and Advanced Two Factor Authentication. +More information is available from our [All-In-One Security website](https://teamupdraft.com/all-in-one-security/) +More information is available from our [All-In-One Security website]( https://teamupdraft.com/all-in-one-security/pricing?utm_source=aios-wp-dir&utm_medium=referral&utm_campaign=plugin-dir&utm_content=additional_features&utm_creative_format=faq) + += How do I get started with All-In-One Security Premium? = +In the web shop, purchase your preferred subscription. After completing the purchase, you will be emailed a link to download the plugin. You can also access the link through your "My Account" page. +After downloading the zip file, install and activate the plugin through WP Admin->Plugins->Add New->Upload Plugin. +The premium extends the free version. Therefore you should keep the free version installed and active. You will also be prompted to enter your AIOS username and password to connect your site to licenses. This will allow the plugin to receive updates. + += Do I need to have the free version before downloading Premium? = +Yes, you need to have the free version of the plugin installed and activated before installing Premium. Premium plugin is an add-on that requires the free version to be present. + += Does All-In-One Security work with multi-site network installations? = +Yes, AIOS Premium is compatible with WordPress multisites. For multisite networks, the protection will apply to the network as a whole, and the dashboard and options will be available on the main site of the WordPress multisite. + += Can a WordPress security plugin stop all attacks on my site? = +There is no 100% guarantee that a security plugin will be able to protect against all attacks, as there is always the possibility of unknown WordPress vulnerabilities or other unexpected factors, and attackers are always seeking to develop new ways around protections. However, All-In-One Security gives good protection against known attack methods, and is under continuous development to monitor and improve protections. + += Does All-In-One Security work on all servers and hosts? = +AIOS should be compatible with most hosts, unless the host has specifically restricted the use of security plugins. Similarly, certain features may not work on some servers, especially Windows/IIS platforms. Features that use the ‘.htaccess’ file will not apply on a Windows IIS server or NGINX server (but development is ongoing to port those protections to all servers). + += Can I cover my subdomains and test sites with a licence for AIOS Premium? = +Development and test sites require their own licence if updates to the plugin are needed. +However, these sites can be disconnected from the licence when they have served their purpose. You can disconnect the licence via the site's WP Admin->Plugins page, and it will be available to be reassigned to a different site. + += Is the All In One Security & Firewall Plugin GDPR and other privacy law compliant? = +Please read more about GDPR compliance here: https://teamupdraft.com/privacy/ . +Please read more about GDPR compliance here: https://www.teamupdraft.com/privacy?utm_source=aios-wp-dir&utm_medium=referral&utm_campaign=plugin-dir&utm_content=gdpr&utm_creative_format=faq. + +== Installation == + +To begin making your WordPress site more secure: + +1. Upload the 'all-in-one-wp-security.zip' file from the Plugins->Add New page in the WordPress administration panel. +2. Activate the plugin through the 'Plugins' menu in WordPress +3. Go to Settings menu under 'AIOS' and start activating the security features of the plugin. + +== Usage == + +Go to the settings menu after you activate the plugin and follow the instructions. + +== Screenshots == + +1. Features list. + +== Changelog == + += 5.4.4 - 5/Nov/2025 = + +* FEATURE: Added new and improved existing modules for UpdraftCentral. +* FIX: The theme's custom 404 page does not parse and instead displays the shortcodes for wp-login.php, due to the login page having been renamed. +* FIX: 404 detection was not working when using a custom 404 template page. +* FIX: PHP Strict Standards warning for AIOWPSecurity_Base_Tasks::run_for_a_site() +* FIX: Changed slider control class name from `slider` to `aiowps_slider` and updated CSS to prevent conflict with other plugins. +* FIX: Resolved deprecated error in fputcsv() by providing the required $escape parameter when exporting CSV files. + += 5.4.3 - 8/Sep/2025 = + +* FEATURE: Added a feature to enforce the use of strong passwords by users +* FIX: Bypass Cookie based brute force prevention using AJAX request. +* FIX: PHP notice - the translation load text domain was called incorrectly. +* FIX: Resolved call to undefined function disk_total_space in wp-security-debug.php when the hosting provider has disabled this PHP function. +* FIX: Fatal error when accessing an array query parameter when the login page has been renamed. +* FIX: Chrome console error where the maths captcha
').data('qrcode', qr).css(containerCSS); + + if (settings_bgColor) { + $div.css('background-color', settings_bgColor); + } + + for (row = 0; row < moduleCount; row += 1) { + for (col = 0; col < moduleCount; col += 1) { + if (qr.isDark(row, col)) { + jq('
') + .css(darkCSS) + .css({ + left: offset + col * moduleSize, + top: offset + row * moduleSize + }) + .appendTo($div); + } + } + } + + return $div; + } + + function createHTML(settings) { + if (hasCanvas && settings.render === 'canvas') { + return createCanvas(settings); + } else if (hasCanvas && settings.render === 'image') { + return createImage(settings); + } + + return createDiv(settings); + } + + // Plugin + // ====== + + // Default settings + // ---------------- + var defaults = { + // render method: `'canvas'`, `'image'` or `'div'` + render: 'canvas', + + // version range somewhere in 1 .. 40 + minVersion: 1, + maxVersion: 40, + + // error correction level: `'L'`, `'M'`, `'Q'` or `'H'` + ecLevel: 'L', + + // offset in pixel if drawn onto existing canvas + left: 0, + top: 0, + + // size in pixel + size: 200, + + // code color or image element + fill: '#000', + + // background color or image element, `null` for transparent background + background: null, + + // content + text: 'no text', + + // corner radius relative to module width: 0.0 .. 0.5 + radius: 0, + + // quiet zone in modules + quiet: 0, + + // modes + // 0: normal + // 1: label strip + // 2: label box + // 3: image strip + // 4: image box + mode: 0, + + mSize: 0.1, + mPosX: 0.5, + mPosY: 0.5, + + label: 'no label', + fontname: 'sans', + fontcolor: '#000', + + image: null + }; + + // Register the plugin + // ------------------- + jq.fn.qrcode = function (options) { + var settings = jq.extend({}, defaults, options); + + return this.each(function (idx, el) { + if (el.nodeName.toLowerCase() === 'canvas') { + drawOnCanvas(el, settings); + } else { + jq(el).append(createHTML(settings)); + } + }); + }; +}(function () { + // `qrcode` is the single public function defined by the `QR Code Generator` + //--------------------------------------------------------------------- + // + // QR Code Generator for JavaScript + // + // Copyright (c) 2009 Kazuhiko Arase + // + // URL: http://www.d-project.com/ + // + // Licensed under the MIT license: + // http://www.opensource.org/licenses/mit-license.php + // + // The word 'QR Code' is registered trademark of + // DENSO WAVE INCORPORATED + // http://www.denso-wave.com/qrcode/faqpatent-e.html + // + //--------------------------------------------------------------------- + + var qrcode = function() { + + //--------------------------------------------------------------------- + // qrcode + //--------------------------------------------------------------------- + + /** + * qrcode + * @param typeNumber 1 to 40 + * @param errorCorrectLevel 'L','M','Q','H' + */ + var qrcode = function(typeNumber, errorCorrectLevel) { + + var PAD0 = 0xEC; + var PAD1 = 0x11; + + var _typeNumber = typeNumber; + var _errorCorrectLevel = QRErrorCorrectLevel[errorCorrectLevel]; + var _modules = null; + var _moduleCount = 0; + var _dataCache = null; + var _dataList = new Array(); + + var _this = {}; + + var makeImpl = function(test, maskPattern) { + + _moduleCount = _typeNumber * 4 + 17; + _modules = function(moduleCount) { + var modules = new Array(moduleCount); + for (var row = 0; row < moduleCount; row += 1) { + modules[row] = new Array(moduleCount); + for (var col = 0; col < moduleCount; col += 1) { + modules[row][col] = null; + } + } + return modules; + }(_moduleCount); + + setupPositionProbePattern(0, 0); + setupPositionProbePattern(_moduleCount - 7, 0); + setupPositionProbePattern(0, _moduleCount - 7); + setupPositionAdjustPattern(); + setupTimingPattern(); + setupTypeInfo(test, maskPattern); + + if (_typeNumber >= 7) { + setupTypeNumber(test); + } + + if (_dataCache == null) { + _dataCache = createData(_typeNumber, _errorCorrectLevel, _dataList); + } + + mapData(_dataCache, maskPattern); + }; + + var setupPositionProbePattern = function(row, col) { + + for (var r = -1; r <= 7; r += 1) { + + if (row + r <= -1 || _moduleCount <= row + r) continue; + + for (var c = -1; c <= 7; c += 1) { + + if (col + c <= -1 || _moduleCount <= col + c) continue; + + if ( (0 <= r && r <= 6 && (c == 0 || c == 6) ) + || (0 <= c && c <= 6 && (r == 0 || r == 6) ) + || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) { + _modules[row + r][col + c] = true; + } else { + _modules[row + r][col + c] = false; + } + } + } + }; + + var getBestMaskPattern = function() { + + var minLostPoint = 0; + var pattern = 0; + + for (var i = 0; i < 8; i += 1) { + + makeImpl(true, i); + + var lostPoint = QRUtil.getLostPoint(_this); + + if (i == 0 || minLostPoint > lostPoint) { + minLostPoint = lostPoint; + pattern = i; + } + } + + return pattern; + }; + + var setupTimingPattern = function() { + + for (var r = 8; r < _moduleCount - 8; r += 1) { + if (_modules[r][6] != null) { + continue; + } + _modules[r][6] = (r % 2 == 0); + } + + for (var c = 8; c < _moduleCount - 8; c += 1) { + if (_modules[6][c] != null) { + continue; + } + _modules[6][c] = (c % 2 == 0); + } + }; + + var setupPositionAdjustPattern = function() { + + var pos = QRUtil.getPatternPosition(_typeNumber); + + for (var i = 0; i < pos.length; i += 1) { + + for (var j = 0; j < pos.length; j += 1) { + + var row = pos[i]; + var col = pos[j]; + + if (_modules[row][col] != null) { + continue; + } + + for (var r = -2; r <= 2; r += 1) { + + for (var c = -2; c <= 2; c += 1) { + + if (r == -2 || r == 2 || c == -2 || c == 2 + || (r == 0 && c == 0) ) { + _modules[row + r][col + c] = true; + } else { + _modules[row + r][col + c] = false; + } + } + } + } + } + }; + + var setupTypeNumber = function(test) { + + var bits = QRUtil.getBCHTypeNumber(_typeNumber); + + for (var i = 0; i < 18; i += 1) { + var mod = (!test && ( (bits >> i) & 1) == 1); + _modules[Math.floor(i / 3)][i % 3 + _moduleCount - 8 - 3] = mod; + } + + for (var i = 0; i < 18; i += 1) { + var mod = (!test && ( (bits >> i) & 1) == 1); + _modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod; + } + }; + + var setupTypeInfo = function(test, maskPattern) { + + var data = (_errorCorrectLevel << 3) | maskPattern; + var bits = QRUtil.getBCHTypeInfo(data); + + // vertical + for (var i = 0; i < 15; i += 1) { + + var mod = (!test && ( (bits >> i) & 1) == 1); + + if (i < 6) { + _modules[i][8] = mod; + } else if (i < 8) { + _modules[i + 1][8] = mod; + } else { + _modules[_moduleCount - 15 + i][8] = mod; + } + } + + // horizontal + for (var i = 0; i < 15; i += 1) { + + var mod = (!test && ( (bits >> i) & 1) == 1); + + if (i < 8) { + _modules[8][_moduleCount - i - 1] = mod; + } else if (i < 9) { + _modules[8][15 - i - 1 + 1] = mod; + } else { + _modules[8][15 - i - 1] = mod; + } + } + + // fixed module + _modules[_moduleCount - 8][8] = (!test); + }; + + var mapData = function(data, maskPattern) { + + var inc = -1; + var row = _moduleCount - 1; + var bitIndex = 7; + var byteIndex = 0; + var maskFunc = QRUtil.getMaskFunction(maskPattern); + + for (var col = _moduleCount - 1; col > 0; col -= 2) { + + if (col == 6) col -= 1; + + while (true) { + + for (var c = 0; c < 2; c += 1) { + + if (_modules[row][col - c] == null) { + + var dark = false; + + if (byteIndex < data.length) { + dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1); + } + + var mask = maskFunc(row, col - c); + + if (mask) { + dark = !dark; + } + + _modules[row][col - c] = dark; + bitIndex -= 1; + + if (bitIndex == -1) { + byteIndex += 1; + bitIndex = 7; + } + } + } + + row += inc; + + if (row < 0 || _moduleCount <= row) { + row -= inc; + inc = -inc; + break; + } + } + } + }; + + var createBytes = function(buffer, rsBlocks) { + + var offset = 0; + + var maxDcCount = 0; + var maxEcCount = 0; + + var dcdata = new Array(rsBlocks.length); + var ecdata = new Array(rsBlocks.length); + + for (var r = 0; r < rsBlocks.length; r += 1) { + + var dcCount = rsBlocks[r].dataCount; + var ecCount = rsBlocks[r].totalCount - dcCount; + + maxDcCount = Math.max(maxDcCount, dcCount); + maxEcCount = Math.max(maxEcCount, ecCount); + + dcdata[r] = new Array(dcCount); + + for (var i = 0; i < dcdata[r].length; i += 1) { + dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset]; + } + offset += dcCount; + + var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount); + var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1); + + var modPoly = rawPoly.mod(rsPoly); + ecdata[r] = new Array(rsPoly.getLength() - 1); + for (var i = 0; i < ecdata[r].length; i += 1) { + var modIndex = i + modPoly.getLength() - ecdata[r].length; + ecdata[r][i] = (modIndex >= 0)? modPoly.getAt(modIndex) : 0; + } + } + + var totalCodeCount = 0; + for (var i = 0; i < rsBlocks.length; i += 1) { + totalCodeCount += rsBlocks[i].totalCount; + } + + var data = new Array(totalCodeCount); + var index = 0; + + for (var i = 0; i < maxDcCount; i += 1) { + for (var r = 0; r < rsBlocks.length; r += 1) { + if (i < dcdata[r].length) { + data[index] = dcdata[r][i]; + index += 1; + } + } + } + + for (var i = 0; i < maxEcCount; i += 1) { + for (var r = 0; r < rsBlocks.length; r += 1) { + if (i < ecdata[r].length) { + data[index] = ecdata[r][i]; + index += 1; + } + } + } + + return data; + }; + + var createData = function(typeNumber, errorCorrectLevel, dataList) { + + var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel); + + var buffer = qrBitBuffer(); + + for (var i = 0; i < dataList.length; i += 1) { + var data = dataList[i]; + buffer.put(data.getMode(), 4); + buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) ); + data.write(buffer); + } + + // calc num max data. + var totalDataCount = 0; + for (var i = 0; i < rsBlocks.length; i += 1) { + totalDataCount += rsBlocks[i].dataCount; + } + + if (buffer.getLengthInBits() > totalDataCount * 8) { + throw new Error('code length overflow. (' + + buffer.getLengthInBits() + + '>' + + totalDataCount * 8 + + ')'); + } + + // end code + if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) { + buffer.put(0, 4); + } + + // padding + while (buffer.getLengthInBits() % 8 != 0) { + buffer.putBit(false); + } + + // padding + while (true) { + + if (buffer.getLengthInBits() >= totalDataCount * 8) { + break; + } + buffer.put(PAD0, 8); + + if (buffer.getLengthInBits() >= totalDataCount * 8) { + break; + } + buffer.put(PAD1, 8); + } + + return createBytes(buffer, rsBlocks); + }; + + _this.addData = function(data) { + var newData = qr8BitByte(data); + _dataList.push(newData); + _dataCache = null; + }; + + _this.isDark = function(row, col) { + if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) { + throw new Error(row + ',' + col); + } + return _modules[row][col]; + }; + + _this.getModuleCount = function() { + return _moduleCount; + }; + + _this.make = function() { + makeImpl(false, getBestMaskPattern() ); + }; + + _this.createTableTag = function(cellSize, margin) { + + cellSize = cellSize || 2; + margin = (typeof margin == 'undefined')? cellSize * 4 : margin; + + var qrHtml = ''; + + qrHtml += ''; + qrHtml += ''; + + for (var r = 0; r < _this.getModuleCount(); r += 1) { + + qrHtml += ''; + + for (var c = 0; c < _this.getModuleCount(); c += 1) { + qrHtml += ''; + } + + qrHtml += ''; + qrHtml += '
'; + } + + qrHtml += '
'; + + return qrHtml; + }; + + _this.createImgTag = function(cellSize, margin) { + + cellSize = cellSize || 2; + margin = (typeof margin == 'undefined')? cellSize * 4 : margin; + + var size = _this.getModuleCount() * cellSize + margin * 2; + var min = margin; + var max = size - margin; + + return createImgTag(size, size, function(x, y) { + if (min <= x && x < max && min <= y && y < max) { + var c = Math.floor( (x - min) / cellSize); + var r = Math.floor( (y - min) / cellSize); + return _this.isDark(r, c)? 0 : 1; + } else { + return 1; + } + } ); + }; + + return _this; + }; + + //--------------------------------------------------------------------- + // qrcode.stringToBytes + //--------------------------------------------------------------------- + + qrcode.stringToBytes = function(s) { + var bytes = new Array(); + for (var i = 0; i < s.length; i += 1) { + var c = s.charCodeAt(i); + bytes.push(c & 0xff); + } + return bytes; + }; + + //--------------------------------------------------------------------- + // qrcode.createStringToBytes + //--------------------------------------------------------------------- + + /** + * @param unicodeData base64 string of byte array. + * [16bit Unicode],[16bit Bytes], ... + * @param numChars + */ + qrcode.createStringToBytes = function(unicodeData, numChars) { + + // create conversion map. + + var unicodeMap = function() { + + var bin = base64DecodeInputStream(unicodeData); + var read = function() { + var b = bin.read(); + if (b == -1) throw new Error(); + return b; + }; + + var count = 0; + var unicodeMap = {}; + while (true) { + var b0 = bin.read(); + if (b0 == -1) break; + var b1 = read(); + var b2 = read(); + var b3 = read(); + var k = String.fromCharCode( (b0 << 8) | b1); + var v = (b2 << 8) | b3; + unicodeMap[k] = v; + count += 1; + } + if (count != numChars) { + throw new Error(count + ' != ' + numChars); + } + + return unicodeMap; + }(); + + var unknownChar = '?'.charCodeAt(0); + + return function(s) { + var bytes = new Array(); + for (var i = 0; i < s.length; i += 1) { + var c = s.charCodeAt(i); + if (c < 128) { + bytes.push(c); + } else { + var b = unicodeMap[s.charAt(i)]; + if (typeof b == 'number') { + if ( (b & 0xff) == b) { + // 1byte + bytes.push(b); + } else { + // 2bytes + bytes.push(b >>> 8); + bytes.push(b & 0xff); + } + } else { + bytes.push(unknownChar); + } + } + } + return bytes; + }; + }; + + //--------------------------------------------------------------------- + // QRMode + //--------------------------------------------------------------------- + + var QRMode = { + MODE_NUMBER : 1 << 0, + MODE_ALPHA_NUM : 1 << 1, + MODE_8BIT_BYTE : 1 << 2, + MODE_KANJI : 1 << 3 + }; + + //--------------------------------------------------------------------- + // QRErrorCorrectLevel + //--------------------------------------------------------------------- + + var QRErrorCorrectLevel = { + L : 1, + M : 0, + Q : 3, + H : 2 + }; + + //--------------------------------------------------------------------- + // QRMaskPattern + //--------------------------------------------------------------------- + + var QRMaskPattern = { + PATTERN000 : 0, + PATTERN001 : 1, + PATTERN010 : 2, + PATTERN011 : 3, + PATTERN100 : 4, + PATTERN101 : 5, + PATTERN110 : 6, + PATTERN111 : 7 + }; + + //--------------------------------------------------------------------- + // QRUtil + //--------------------------------------------------------------------- + + var QRUtil = function() { + + var PATTERN_POSITION_TABLE = [ + [], + [6, 18], + [6, 22], + [6, 26], + [6, 30], + [6, 34], + [6, 22, 38], + [6, 24, 42], + [6, 26, 46], + [6, 28, 50], + [6, 30, 54], + [6, 32, 58], + [6, 34, 62], + [6, 26, 46, 66], + [6, 26, 48, 70], + [6, 26, 50, 74], + [6, 30, 54, 78], + [6, 30, 56, 82], + [6, 30, 58, 86], + [6, 34, 62, 90], + [6, 28, 50, 72, 94], + [6, 26, 50, 74, 98], + [6, 30, 54, 78, 102], + [6, 28, 54, 80, 106], + [6, 32, 58, 84, 110], + [6, 30, 58, 86, 114], + [6, 34, 62, 90, 118], + [6, 26, 50, 74, 98, 122], + [6, 30, 54, 78, 102, 126], + [6, 26, 52, 78, 104, 130], + [6, 30, 56, 82, 108, 134], + [6, 34, 60, 86, 112, 138], + [6, 30, 58, 86, 114, 142], + [6, 34, 62, 90, 118, 146], + [6, 30, 54, 78, 102, 126, 150], + [6, 24, 50, 76, 102, 128, 154], + [6, 28, 54, 80, 106, 132, 158], + [6, 32, 58, 84, 110, 136, 162], + [6, 26, 54, 82, 110, 138, 166], + [6, 30, 58, 86, 114, 142, 170] + ]; + var G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0); + var G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0); + var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1); + + var _this = {}; + + var getBCHDigit = function(data) { + var digit = 0; + while (data != 0) { + digit += 1; + data >>>= 1; + } + return digit; + }; + + _this.getBCHTypeInfo = function(data) { + var d = data << 10; + while (getBCHDigit(d) - getBCHDigit(G15) >= 0) { + d ^= (G15 << (getBCHDigit(d) - getBCHDigit(G15) ) ); + } + return ( (data << 10) | d) ^ G15_MASK; + }; + + _this.getBCHTypeNumber = function(data) { + var d = data << 12; + while (getBCHDigit(d) - getBCHDigit(G18) >= 0) { + d ^= (G18 << (getBCHDigit(d) - getBCHDigit(G18) ) ); + } + return (data << 12) | d; + }; + + _this.getPatternPosition = function(typeNumber) { + return PATTERN_POSITION_TABLE[typeNumber - 1]; + }; + + _this.getMaskFunction = function(maskPattern) { + + switch (maskPattern) { + + case QRMaskPattern.PATTERN000 : + return function(i, j) { return (i + j) % 2 == 0; }; + case QRMaskPattern.PATTERN001 : + return function(i, j) { return i % 2 == 0; }; + case QRMaskPattern.PATTERN010 : + return function(i, j) { return j % 3 == 0; }; + case QRMaskPattern.PATTERN011 : + return function(i, j) { return (i + j) % 3 == 0; }; + case QRMaskPattern.PATTERN100 : + return function(i, j) { return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; }; + case QRMaskPattern.PATTERN101 : + return function(i, j) { return (i * j) % 2 + (i * j) % 3 == 0; }; + case QRMaskPattern.PATTERN110 : + return function(i, j) { return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; }; + case QRMaskPattern.PATTERN111 : + return function(i, j) { return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; }; + + default : + throw new Error('bad maskPattern:' + maskPattern); + } + }; + + _this.getErrorCorrectPolynomial = function(errorCorrectLength) { + var a = qrPolynomial([1], 0); + for (var i = 0; i < errorCorrectLength; i += 1) { + a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0) ); + } + return a; + }; + + _this.getLengthInBits = function(mode, type) { + + if (1 <= type && type < 10) { + + // 1 - 9 + + switch(mode) { + case QRMode.MODE_NUMBER : return 10; + case QRMode.MODE_ALPHA_NUM : return 9; + case QRMode.MODE_8BIT_BYTE : return 8; + case QRMode.MODE_KANJI : return 8; + default : + throw new Error('mode:' + mode); + } + + } else if (type < 27) { + + // 10 - 26 + + switch(mode) { + case QRMode.MODE_NUMBER : return 12; + case QRMode.MODE_ALPHA_NUM : return 11; + case QRMode.MODE_8BIT_BYTE : return 16; + case QRMode.MODE_KANJI : return 10; + default : + throw new Error('mode:' + mode); + } + + } else if (type < 41) { + + // 27 - 40 + + switch(mode) { + case QRMode.MODE_NUMBER : return 14; + case QRMode.MODE_ALPHA_NUM : return 13; + case QRMode.MODE_8BIT_BYTE : return 16; + case QRMode.MODE_KANJI : return 12; + default : + throw new Error('mode:' + mode); + } + + } else { + throw new Error('type:' + type); + } + }; + + _this.getLostPoint = function(qrcode) { + + var moduleCount = qrcode.getModuleCount(); + + var lostPoint = 0; + + // LEVEL1 + + for (var row = 0; row < moduleCount; row += 1) { + for (var col = 0; col < moduleCount; col += 1) { + + var sameCount = 0; + var dark = qrcode.isDark(row, col); + + for (var r = -1; r <= 1; r += 1) { + + if (row + r < 0 || moduleCount <= row + r) { + continue; + } + + for (var c = -1; c <= 1; c += 1) { + + if (col + c < 0 || moduleCount <= col + c) { + continue; + } + + if (r == 0 && c == 0) { + continue; + } + + if (dark == qrcode.isDark(row + r, col + c) ) { + sameCount += 1; + } + } + } + + if (sameCount > 5) { + lostPoint += (3 + sameCount - 5); + } + } + }; + + // LEVEL2 + + for (var row = 0; row < moduleCount - 1; row += 1) { + for (var col = 0; col < moduleCount - 1; col += 1) { + var count = 0; + if (qrcode.isDark(row, col) ) count += 1; + if (qrcode.isDark(row + 1, col) ) count += 1; + if (qrcode.isDark(row, col + 1) ) count += 1; + if (qrcode.isDark(row + 1, col + 1) ) count += 1; + if (count == 0 || count == 4) { + lostPoint += 3; + } + } + } + + // LEVEL3 + + for (var row = 0; row < moduleCount; row += 1) { + for (var col = 0; col < moduleCount - 6; col += 1) { + if (qrcode.isDark(row, col) + && !qrcode.isDark(row, col + 1) + && qrcode.isDark(row, col + 2) + && qrcode.isDark(row, col + 3) + && qrcode.isDark(row, col + 4) + && !qrcode.isDark(row, col + 5) + && qrcode.isDark(row, col + 6) ) { + lostPoint += 40; + } + } + } + + for (var col = 0; col < moduleCount; col += 1) { + for (var row = 0; row < moduleCount - 6; row += 1) { + if (qrcode.isDark(row, col) + && !qrcode.isDark(row + 1, col) + && qrcode.isDark(row + 2, col) + && qrcode.isDark(row + 3, col) + && qrcode.isDark(row + 4, col) + && !qrcode.isDark(row + 5, col) + && qrcode.isDark(row + 6, col) ) { + lostPoint += 40; + } + } + } + + // LEVEL4 + + var darkCount = 0; + + for (var col = 0; col < moduleCount; col += 1) { + for (var row = 0; row < moduleCount; row += 1) { + if (qrcode.isDark(row, col) ) { + darkCount += 1; + } + } + } + + var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5; + lostPoint += ratio * 10; + + return lostPoint; + }; + + return _this; + }(); + + //--------------------------------------------------------------------- + // QRMath + //--------------------------------------------------------------------- + + var QRMath = function() { + + var EXP_TABLE = new Array(256); + var LOG_TABLE = new Array(256); + + // initialize tables + for (var i = 0; i < 8; i += 1) { + EXP_TABLE[i] = 1 << i; + } + for (var i = 8; i < 256; i += 1) { + EXP_TABLE[i] = EXP_TABLE[i - 4] + ^ EXP_TABLE[i - 5] + ^ EXP_TABLE[i - 6] + ^ EXP_TABLE[i - 8]; + } + for (var i = 0; i < 255; i += 1) { + LOG_TABLE[EXP_TABLE[i] ] = i; + } + + var _this = {}; + + _this.glog = function(n) { + + if (n < 1) { + throw new Error('glog(' + n + ')'); + } + + return LOG_TABLE[n]; + }; + + _this.gexp = function(n) { + + while (n < 0) { + n += 255; + } + + while (n >= 256) { + n -= 255; + } + + return EXP_TABLE[n]; + }; + + return _this; + }(); + + //--------------------------------------------------------------------- + // qrPolynomial + //--------------------------------------------------------------------- + + function qrPolynomial(num, shift) { + + if (typeof num.length == 'undefined') { + throw new Error(num.length + '/' + shift); + } + + var _num = function() { + var offset = 0; + while (offset < num.length && num[offset] == 0) { + offset += 1; + } + var _num = new Array(num.length - offset + shift); + for (var i = 0; i < num.length - offset; i += 1) { + _num[i] = num[i + offset]; + } + return _num; + }(); + + var _this = {}; + + _this.getAt = function(index) { + return _num[index]; + }; + + _this.getLength = function() { + return _num.length; + }; + + _this.multiply = function(e) { + + var num = new Array(_this.getLength() + e.getLength() - 1); + + for (var i = 0; i < _this.getLength(); i += 1) { + for (var j = 0; j < e.getLength(); j += 1) { + num[i + j] ^= QRMath.gexp(QRMath.glog(_this.getAt(i) ) + QRMath.glog(e.getAt(j) ) ); + } + } + + return qrPolynomial(num, 0); + }; + + _this.mod = function(e) { + + if (_this.getLength() - e.getLength() < 0) { + return _this; + } + + var ratio = QRMath.glog(_this.getAt(0) ) - QRMath.glog(e.getAt(0) ); + + var num = new Array(_this.getLength() ); + for (var i = 0; i < _this.getLength(); i += 1) { + num[i] = _this.getAt(i); + } + + for (var i = 0; i < e.getLength(); i += 1) { + num[i] ^= QRMath.gexp(QRMath.glog(e.getAt(i) ) + ratio); + } + + // recursive call + return qrPolynomial(num, 0).mod(e); + }; + + return _this; + }; + + //--------------------------------------------------------------------- + // QRRSBlock + //--------------------------------------------------------------------- + + var QRRSBlock = function() { + + var RS_BLOCK_TABLE = [ + + // L + // M + // Q + // H + + // 1 + [1, 26, 19], + [1, 26, 16], + [1, 26, 13], + [1, 26, 9], + + // 2 + [1, 44, 34], + [1, 44, 28], + [1, 44, 22], + [1, 44, 16], + + // 3 + [1, 70, 55], + [1, 70, 44], + [2, 35, 17], + [2, 35, 13], + + // 4 + [1, 100, 80], + [2, 50, 32], + [2, 50, 24], + [4, 25, 9], + + // 5 + [1, 134, 108], + [2, 67, 43], + [2, 33, 15, 2, 34, 16], + [2, 33, 11, 2, 34, 12], + + // 6 + [2, 86, 68], + [4, 43, 27], + [4, 43, 19], + [4, 43, 15], + + // 7 + [2, 98, 78], + [4, 49, 31], + [2, 32, 14, 4, 33, 15], + [4, 39, 13, 1, 40, 14], + + // 8 + [2, 121, 97], + [2, 60, 38, 2, 61, 39], + [4, 40, 18, 2, 41, 19], + [4, 40, 14, 2, 41, 15], + + // 9 + [2, 146, 116], + [3, 58, 36, 2, 59, 37], + [4, 36, 16, 4, 37, 17], + [4, 36, 12, 4, 37, 13], + + // 10 + [2, 86, 68, 2, 87, 69], + [4, 69, 43, 1, 70, 44], + [6, 43, 19, 2, 44, 20], + [6, 43, 15, 2, 44, 16], + + // 11 + [4, 101, 81], + [1, 80, 50, 4, 81, 51], + [4, 50, 22, 4, 51, 23], + [3, 36, 12, 8, 37, 13], + + // 12 + [2, 116, 92, 2, 117, 93], + [6, 58, 36, 2, 59, 37], + [4, 46, 20, 6, 47, 21], + [7, 42, 14, 4, 43, 15], + + // 13 + [4, 133, 107], + [8, 59, 37, 1, 60, 38], + [8, 44, 20, 4, 45, 21], + [12, 33, 11, 4, 34, 12], + + // 14 + [3, 145, 115, 1, 146, 116], + [4, 64, 40, 5, 65, 41], + [11, 36, 16, 5, 37, 17], + [11, 36, 12, 5, 37, 13], + + // 15 + [5, 109, 87, 1, 110, 88], + [5, 65, 41, 5, 66, 42], + [5, 54, 24, 7, 55, 25], + [11, 36, 12, 7, 37, 13], + + // 16 + [5, 122, 98, 1, 123, 99], + [7, 73, 45, 3, 74, 46], + [15, 43, 19, 2, 44, 20], + [3, 45, 15, 13, 46, 16], + + // 17 + [1, 135, 107, 5, 136, 108], + [10, 74, 46, 1, 75, 47], + [1, 50, 22, 15, 51, 23], + [2, 42, 14, 17, 43, 15], + + // 18 + [5, 150, 120, 1, 151, 121], + [9, 69, 43, 4, 70, 44], + [17, 50, 22, 1, 51, 23], + [2, 42, 14, 19, 43, 15], + + // 19 + [3, 141, 113, 4, 142, 114], + [3, 70, 44, 11, 71, 45], + [17, 47, 21, 4, 48, 22], + [9, 39, 13, 16, 40, 14], + + // 20 + [3, 135, 107, 5, 136, 108], + [3, 67, 41, 13, 68, 42], + [15, 54, 24, 5, 55, 25], + [15, 43, 15, 10, 44, 16], + + // 21 + [4, 144, 116, 4, 145, 117], + [17, 68, 42], + [17, 50, 22, 6, 51, 23], + [19, 46, 16, 6, 47, 17], + + // 22 + [2, 139, 111, 7, 140, 112], + [17, 74, 46], + [7, 54, 24, 16, 55, 25], + [34, 37, 13], + + // 23 + [4, 151, 121, 5, 152, 122], + [4, 75, 47, 14, 76, 48], + [11, 54, 24, 14, 55, 25], + [16, 45, 15, 14, 46, 16], + + // 24 + [6, 147, 117, 4, 148, 118], + [6, 73, 45, 14, 74, 46], + [11, 54, 24, 16, 55, 25], + [30, 46, 16, 2, 47, 17], + + // 25 + [8, 132, 106, 4, 133, 107], + [8, 75, 47, 13, 76, 48], + [7, 54, 24, 22, 55, 25], + [22, 45, 15, 13, 46, 16], + + // 26 + [10, 142, 114, 2, 143, 115], + [19, 74, 46, 4, 75, 47], + [28, 50, 22, 6, 51, 23], + [33, 46, 16, 4, 47, 17], + + // 27 + [8, 152, 122, 4, 153, 123], + [22, 73, 45, 3, 74, 46], + [8, 53, 23, 26, 54, 24], + [12, 45, 15, 28, 46, 16], + + // 28 + [3, 147, 117, 10, 148, 118], + [3, 73, 45, 23, 74, 46], + [4, 54, 24, 31, 55, 25], + [11, 45, 15, 31, 46, 16], + + // 29 + [7, 146, 116, 7, 147, 117], + [21, 73, 45, 7, 74, 46], + [1, 53, 23, 37, 54, 24], + [19, 45, 15, 26, 46, 16], + + // 30 + [5, 145, 115, 10, 146, 116], + [19, 75, 47, 10, 76, 48], + [15, 54, 24, 25, 55, 25], + [23, 45, 15, 25, 46, 16], + + // 31 + [13, 145, 115, 3, 146, 116], + [2, 74, 46, 29, 75, 47], + [42, 54, 24, 1, 55, 25], + [23, 45, 15, 28, 46, 16], + + // 32 + [17, 145, 115], + [10, 74, 46, 23, 75, 47], + [10, 54, 24, 35, 55, 25], + [19, 45, 15, 35, 46, 16], + + // 33 + [17, 145, 115, 1, 146, 116], + [14, 74, 46, 21, 75, 47], + [29, 54, 24, 19, 55, 25], + [11, 45, 15, 46, 46, 16], + + // 34 + [13, 145, 115, 6, 146, 116], + [14, 74, 46, 23, 75, 47], + [44, 54, 24, 7, 55, 25], + [59, 46, 16, 1, 47, 17], + + // 35 + [12, 151, 121, 7, 152, 122], + [12, 75, 47, 26, 76, 48], + [39, 54, 24, 14, 55, 25], + [22, 45, 15, 41, 46, 16], + + // 36 + [6, 151, 121, 14, 152, 122], + [6, 75, 47, 34, 76, 48], + [46, 54, 24, 10, 55, 25], + [2, 45, 15, 64, 46, 16], + + // 37 + [17, 152, 122, 4, 153, 123], + [29, 74, 46, 14, 75, 47], + [49, 54, 24, 10, 55, 25], + [24, 45, 15, 46, 46, 16], + + // 38 + [4, 152, 122, 18, 153, 123], + [13, 74, 46, 32, 75, 47], + [48, 54, 24, 14, 55, 25], + [42, 45, 15, 32, 46, 16], + + // 39 + [20, 147, 117, 4, 148, 118], + [40, 75, 47, 7, 76, 48], + [43, 54, 24, 22, 55, 25], + [10, 45, 15, 67, 46, 16], + + // 40 + [19, 148, 118, 6, 149, 119], + [18, 75, 47, 31, 76, 48], + [34, 54, 24, 34, 55, 25], + [20, 45, 15, 61, 46, 16] + ]; + + var qrRSBlock = function(totalCount, dataCount) { + var _this = {}; + _this.totalCount = totalCount; + _this.dataCount = dataCount; + return _this; + }; + + var _this = {}; + + var getRsBlockTable = function(typeNumber, errorCorrectLevel) { + + switch(errorCorrectLevel) { + case QRErrorCorrectLevel.L : + return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]; + case QRErrorCorrectLevel.M : + return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]; + case QRErrorCorrectLevel.Q : + return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]; + case QRErrorCorrectLevel.H : + return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]; + default : + return undefined; + } + }; + + _this.getRSBlocks = function(typeNumber, errorCorrectLevel) { + + var rsBlock = getRsBlockTable(typeNumber, errorCorrectLevel); + + if (typeof rsBlock == 'undefined') { + throw new Error('bad rs block @ typeNumber:' + typeNumber + + '/errorCorrectLevel:' + errorCorrectLevel); + } + + var length = rsBlock.length / 3; + + var list = new Array(); + + for (var i = 0; i < length; i += 1) { + + var count = rsBlock[i * 3 + 0]; + var totalCount = rsBlock[i * 3 + 1]; + var dataCount = rsBlock[i * 3 + 2]; + + for (var j = 0; j < count; j += 1) { + list.push(qrRSBlock(totalCount, dataCount) ); + } + } + + return list; + }; + + return _this; + }(); + + //--------------------------------------------------------------------- + // qrBitBuffer + //--------------------------------------------------------------------- + + var qrBitBuffer = function() { + + var _buffer = new Array(); + var _length = 0; + + var _this = {}; + + _this.getBuffer = function() { + return _buffer; + }; + + _this.getAt = function(index) { + var bufIndex = Math.floor(index / 8); + return ( (_buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1; + }; + + _this.put = function(num, length) { + for (var i = 0; i < length; i += 1) { + _this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1); + } + }; + + _this.getLengthInBits = function() { + return _length; + }; + + _this.putBit = function(bit) { + + var bufIndex = Math.floor(_length / 8); + if (_buffer.length <= bufIndex) { + _buffer.push(0); + } + + if (bit) { + _buffer[bufIndex] |= (0x80 >>> (_length % 8) ); + } + + _length += 1; + }; + + return _this; + }; + + //--------------------------------------------------------------------- + // qr8BitByte + //--------------------------------------------------------------------- + + var qr8BitByte = function(data) { + + var _mode = QRMode.MODE_8BIT_BYTE; + var _data = data; + var _bytes = qrcode.stringToBytes(data); + + var _this = {}; + + _this.getMode = function() { + return _mode; + }; + + _this.getLength = function(buffer) { + return _bytes.length; + }; + + _this.write = function(buffer) { + for (var i = 0; i < _bytes.length; i += 1) { + buffer.put(_bytes[i], 8); + } + }; + + return _this; + }; + + //===================================================================== + // GIF Support etc. + // + + //--------------------------------------------------------------------- + // byteArrayOutputStream + //--------------------------------------------------------------------- + + var byteArrayOutputStream = function() { + + var _bytes = new Array(); + + var _this = {}; + + _this.writeByte = function(b) { + _bytes.push(b & 0xff); + }; + + _this.writeShort = function(i) { + _this.writeByte(i); + _this.writeByte(i >>> 8); + }; + + _this.writeBytes = function(b, off, len) { + off = off || 0; + len = len || b.length; + for (var i = 0; i < len; i += 1) { + _this.writeByte(b[i + off]); + } + }; + + _this.writeString = function(s) { + for (var i = 0; i < s.length; i += 1) { + _this.writeByte(s.charCodeAt(i) ); + } + }; + + _this.toByteArray = function() { + return _bytes; + }; + + _this.toString = function() { + var s = ''; + s += '['; + for (var i = 0; i < _bytes.length; i += 1) { + if (i > 0) { + s += ','; + } + s += _bytes[i]; + } + s += ']'; + return s; + }; + + return _this; + }; + + //--------------------------------------------------------------------- + // base64EncodeOutputStream + //--------------------------------------------------------------------- + + var base64EncodeOutputStream = function() { + + var _buffer = 0; + var _buflen = 0; + var _length = 0; + var _base64 = ''; + + var _this = {}; + + var writeEncoded = function(b) { + _base64 += String.fromCharCode(encode(b & 0x3f) ); + }; + + var encode = function(n) { + if (n < 0) { + // error. + } else if (n < 26) { + return 0x41 + n; + } else if (n < 52) { + return 0x61 + (n - 26); + } else if (n < 62) { + return 0x30 + (n - 52); + } else if (n == 62) { + return 0x2b; + } else if (n == 63) { + return 0x2f; + } + throw new Error('n:' + n); + }; + + _this.writeByte = function(n) { + + _buffer = (_buffer << 8) | (n & 0xff); + _buflen += 8; + _length += 1; + + while (_buflen >= 6) { + writeEncoded(_buffer >>> (_buflen - 6) ); + _buflen -= 6; + } + }; + + _this.flush = function() { + + if (_buflen > 0) { + writeEncoded(_buffer << (6 - _buflen) ); + _buffer = 0; + _buflen = 0; + } + + if (_length % 3 != 0) { + // padding + var padlen = 3 - _length % 3; + for (var i = 0; i < padlen; i += 1) { + _base64 += '='; + } + } + }; + + _this.toString = function() { + return _base64; + }; + + return _this; + }; + + //--------------------------------------------------------------------- + // base64DecodeInputStream + //--------------------------------------------------------------------- + + var base64DecodeInputStream = function(str) { + + var _str = str; + var _pos = 0; + var _buffer = 0; + var _buflen = 0; + + var _this = {}; + + _this.read = function() { + + while (_buflen < 8) { + + if (_pos >= _str.length) { + if (_buflen == 0) { + return -1; + } + throw new Error('unexpected end of file./' + _buflen); + } + + var c = _str.charAt(_pos); + _pos += 1; + + if (c == '=') { + _buflen = 0; + return -1; + } else if (c.match(/^\s$/) ) { + // ignore if whitespace. + continue; + } + + _buffer = (_buffer << 6) | decode(c.charCodeAt(0) ); + _buflen += 6; + } + + var n = (_buffer >>> (_buflen - 8) ) & 0xff; + _buflen -= 8; + return n; + }; + + var decode = function(c) { + if (0x41 <= c && c <= 0x5a) { + return c - 0x41; + } else if (0x61 <= c && c <= 0x7a) { + return c - 0x61 + 26; + } else if (0x30 <= c && c <= 0x39) { + return c - 0x30 + 52; + } else if (c == 0x2b) { + return 62; + } else if (c == 0x2f) { + return 63; + } else { + throw new Error('c:' + c); + } + }; + + return _this; + }; + + //--------------------------------------------------------------------- + // gifImage (B/W) + //--------------------------------------------------------------------- + + var gifImage = function(width, height) { + + var _width = width; + var _height = height; + var _data = new Array(width * height); + + var _this = {}; + + _this.setPixel = function(x, y, pixel) { + _data[y * _width + x] = pixel; + }; + + _this.write = function(out) { + + //--------------------------------- + // GIF Signature + + out.writeString('GIF87a'); + + //--------------------------------- + // Screen Descriptor + + out.writeShort(_width); + out.writeShort(_height); + + out.writeByte(0x80); // 2bit + out.writeByte(0); + out.writeByte(0); + + //--------------------------------- + // Global Color Map + + // black + out.writeByte(0x00); + out.writeByte(0x00); + out.writeByte(0x00); + + // white + out.writeByte(0xff); + out.writeByte(0xff); + out.writeByte(0xff); + + //--------------------------------- + // Image Descriptor + + out.writeString(','); + out.writeShort(0); + out.writeShort(0); + out.writeShort(_width); + out.writeShort(_height); + out.writeByte(0); + + //--------------------------------- + // Local Color Map + + //--------------------------------- + // Raster Data + + var lzwMinCodeSize = 2; + var raster = getLZWRaster(lzwMinCodeSize); + + out.writeByte(lzwMinCodeSize); + + var offset = 0; + + while (raster.length - offset > 255) { + out.writeByte(255); + out.writeBytes(raster, offset, 255); + offset += 255; + } + + out.writeByte(raster.length - offset); + out.writeBytes(raster, offset, raster.length - offset); + out.writeByte(0x00); + + //--------------------------------- + // GIF Terminator + out.writeString(';'); + }; + + var bitOutputStream = function(out) { + + var _out = out; + var _bitLength = 0; + var _bitBuffer = 0; + + var _this = {}; + + _this.write = function(data, length) { + + if ( (data >>> length) != 0) { + throw new Error('length over'); + } + + while (_bitLength + length >= 8) { + _out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) ); + length -= (8 - _bitLength); + data >>>= (8 - _bitLength); + _bitBuffer = 0; + _bitLength = 0; + } + + _bitBuffer = (data << _bitLength) | _bitBuffer; + _bitLength = _bitLength + length; + }; + + _this.flush = function() { + if (_bitLength > 0) { + _out.writeByte(_bitBuffer); + } + }; + + return _this; + }; + + var getLZWRaster = function(lzwMinCodeSize) { + + var clearCode = 1 << lzwMinCodeSize; + var endCode = (1 << lzwMinCodeSize) + 1; + var bitLength = lzwMinCodeSize + 1; + + // Setup LZWTable + var table = lzwTable(); + + for (var i = 0; i < clearCode; i += 1) { + table.add(String.fromCharCode(i) ); + } + table.add(String.fromCharCode(clearCode) ); + table.add(String.fromCharCode(endCode) ); + + var byteOut = byteArrayOutputStream(); + var bitOut = bitOutputStream(byteOut); + + // clear code + bitOut.write(clearCode, bitLength); + + var dataIndex = 0; + + var s = String.fromCharCode(_data[dataIndex]); + dataIndex += 1; + + while (dataIndex < _data.length) { + + var c = String.fromCharCode(_data[dataIndex]); + dataIndex += 1; + + if (table.contains(s + c) ) { + + s = s + c; + + } else { + + bitOut.write(table.indexOf(s), bitLength); + + if (table.size() < 0xfff) { + + if (table.size() == (1 << bitLength) ) { + bitLength += 1; + } + + table.add(s + c); + } + + s = c; + } + } + + bitOut.write(table.indexOf(s), bitLength); + + // end code + bitOut.write(endCode, bitLength); + + bitOut.flush(); + + return byteOut.toByteArray(); + }; + + var lzwTable = function() { + + var _map = {}; + var _size = 0; + + var _this = {}; + + _this.add = function(key) { + if (_this.contains(key) ) { + throw new Error('dup key:' + key); + } + _map[key] = _size; + _size += 1; + }; + + _this.size = function() { + return _size; + }; + + _this.indexOf = function(key) { + return _map[key]; + }; + + _this.contains = function(key) { + return typeof _map[key] != 'undefined'; + }; + + return _this; + }; + + return _this; + }; + + var createImgTag = function(width, height, getPixel, alt) { + + var gif = gifImage(width, height); + for (var y = 0; y < height; y += 1) { + for (var x = 0; x < width; x += 1) { + gif.setPixel(x, y, getPixel(x, y) ); + } + } + + var b = byteArrayOutputStream(); + gif.write(b); + + var base64 = base64EncodeOutputStream(); + var bytes = b.toByteArray(); + for (var i = 0; i < bytes.length; i += 1) { + base64.writeByte(bytes[i]); + } + base64.flush(); + + var img = ''; + img += '> 6), + 0x80 | (charcode & 0x3f)); + } + else if (charcode < 0xd800 || charcode >= 0xe000) { + utf8.push(0xe0 | (charcode >> 12), + 0x80 | ((charcode>>6) & 0x3f), + 0x80 | (charcode & 0x3f)); + } + // surrogate pair + else { + i++; + // UTF-16 encodes 0x10000-0x10FFFF by + // subtracting 0x10000 and splitting the + // 20 bits of 0x0-0xFFFFF into two halves + charcode = 0x10000 + (((charcode & 0x3ff)<<10) + | (str.charCodeAt(i) & 0x3ff)); + utf8.push(0xf0 | (charcode >>18), + 0x80 | ((charcode>>12) & 0x3f), + 0x80 | ((charcode>>6) & 0x3f), + 0x80 | (charcode & 0x3f)); + } + } + return utf8; + } + return toUTF8Array(s); + }; + + }(qrcode); + + return qrcode; // eslint-disable-line no-undef +}())); diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery-qrcode/jquery-qrcode.min.js b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery-qrcode/jquery-qrcode.min.js new file mode 100755 index 00000000..f718c22b --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery-qrcode/jquery-qrcode.min.js @@ -0,0 +1,2 @@ +/*! jquery-qrcode v0.14.0 - https://larsjung.de/jquery-qrcode/ */ +!function(r){"use strict";function t(t,e,n,o){function a(r,t){return r-=o,t-=o,0>r||r>=c||0>t||t>=c?!1:f.isDark(r,t)}function i(r,t,e,n){var o=u.isDark,a=1/l;u.isDark=function(i,u){var f=u*a,c=i*a,l=f+a,g=c+a;return o(i,u)&&(r>l||f>e||t>g||c>n)}}var u={},f=r(n,e);f.addData(t),f.make(),o=o||0;var c=f.getModuleCount(),l=f.getModuleCount()+2*o;return u.text=t,u.level=e,u.version=n,u.moduleCount=l,u.isDark=a,u.addBlank=i,u}function e(r,e,n,o,a){n=Math.max(1,n||1),o=Math.min(40,o||40);for(var i=n;o>=i;i+=1)try{return t(r,e,i,a)}catch(u){}}function n(r,t,e){var n=e.size,o="bold "+e.mSize*n+"px "+e.fontname,a=w("")[0].getContext("2d");a.font=o;var i=a.measureText(e.label).width,u=e.mSize,f=i/n,c=(1-f)*e.mPosX,l=(1-u)*e.mPosY,g=c+f,s=l+u,v=.01;1===e.mode?r.addBlank(0,l-v,n,s+v):r.addBlank(c-v,l-v,g+v,s+v),t.fillStyle=e.fontcolor,t.font=o,t.fillText(e.label,c*n,l*n+.75*e.mSize*n)}function o(r,t,e){var n=e.size,o=e.image.naturalWidth||1,a=e.image.naturalHeight||1,i=e.mSize,u=i*o/a,f=(1-u)*e.mPosX,c=(1-i)*e.mPosY,l=f+u,g=c+i,s=.01;3===e.mode?r.addBlank(0,c-s,n,g+s):r.addBlank(f-s,c-s,l+s,g+s),t.drawImage(e.image,f*n,c*n,u*n,i*n)}function a(r,t,e){w(e.background).is("img")?t.drawImage(e.background,0,0,e.size,e.size):e.background&&(t.fillStyle=e.background,t.fillRect(e.left,e.top,e.size,e.size));var a=e.mode;1===a||2===a?n(r,t,e):(3===a||4===a)&&o(r,t,e)}function i(r,t,e,n,o,a,i,u){r.isDark(i,u)&&t.rect(n,o,a,a)}function u(r,t,e,n,o,a,i,u,f,c){i?r.moveTo(t+a,e):r.moveTo(t,e),u?(r.lineTo(n-a,e),r.arcTo(n,e,n,o,a)):r.lineTo(n,e),f?(r.lineTo(n,o-a),r.arcTo(n,o,t,o,a)):r.lineTo(n,o),c?(r.lineTo(t+a,o),r.arcTo(t,o,t,e,a)):r.lineTo(t,o),i?(r.lineTo(t,e+a),r.arcTo(t,e,n,e,a)):r.lineTo(t,e)}function f(r,t,e,n,o,a,i,u,f,c){i&&(r.moveTo(t+a,e),r.lineTo(t,e),r.lineTo(t,e+a),r.arcTo(t,e,t+a,e,a)),u&&(r.moveTo(n-a,e),r.lineTo(n,e),r.lineTo(n,e+a),r.arcTo(n,e,n-a,e,a)),f&&(r.moveTo(n-a,o),r.lineTo(n,o),r.lineTo(n,o-a),r.arcTo(n,o,n-a,o,a)),c&&(r.moveTo(t+a,o),r.lineTo(t,o),r.lineTo(t,o-a),r.arcTo(t,o,t+a,o,a))}function c(r,t,e,n,o,a,i,c){var l=r.isDark,g=n+a,s=o+a,v=e.radius*a,h=i-1,d=i+1,w=c-1,m=c+1,y=l(i,c),T=l(h,w),p=l(h,c),B=l(h,m),A=l(i,m),E=l(d,m),k=l(d,c),M=l(d,w),C=l(i,w);y?u(t,n,o,g,s,v,!p&&!C,!p&&!A,!k&&!A,!k&&!C):f(t,n,o,g,s,v,p&&C&&T,p&&A&&B,k&&A&&E,k&&C&&M)}function l(r,t,e){var n,o,a=r.moduleCount,u=e.size/a,f=i;for(e.radius>0&&e.radius<=.5&&(f=c),t.beginPath(),n=0;a>n;n+=1)for(o=0;a>o;o+=1){var l=e.left+o*u,g=e.top+n*u,s=u;f(r,t,e,l,g,s,n,o)}if(w(e.fill).is("img")){t.strokeStyle="rgba(0,0,0,0.5)",t.lineWidth=2,t.stroke();var v=t.globalCompositeOperation;t.globalCompositeOperation="destination-out",t.fill(),t.globalCompositeOperation=v,t.clip(),t.drawImage(e.fill,0,0,e.size,e.size),t.restore()}else t.fillStyle=e.fill,t.fill()}function g(r,t){var n=e(t.text,t.ecLevel,t.minVersion,t.maxVersion,t.quiet);if(!n)return null;var o=w(r).data("qrcode",n),i=o[0].getContext("2d");return a(n,i,t),l(n,i,t),o}function s(r){var t=w("").attr("width",r.size).attr("height",r.size);return g(t,r)}function v(r){return w("").attr("src",s(r)[0].toDataURL("image/png"))}function h(r){var t=e(r.text,r.ecLevel,r.minVersion,r.maxVersion,r.quiet);if(!t)return null;var n,o,a=r.size,i=r.background,u=Math.floor,f=t.moduleCount,c=u(a/f),l=u(.5*(a-c*f)),g={position:"relative",left:0,top:0,padding:0,margin:0,width:a,height:a},s={position:"absolute",padding:0,margin:0,width:c,height:c,"background-color":r.fill},v=w("
").data("qrcode",t).css(g);for(i&&v.css("background-color",i),n=0;f>n;n+=1)for(o=0;f>o;o+=1)t.isDark(n,o)&&w("
").css(s).css({left:l+o*c,top:l+n*c}).appendTo(v);return v}function d(r){return m&&"canvas"===r.render?s(r):m&&"image"===r.render?v(r):h(r)}var w=window.jQuery,m=function(){var r=document.createElement("canvas");return!(!r.getContext||!r.getContext("2d"))}(),y={render:"canvas",minVersion:1,maxVersion:40,ecLevel:"L",left:0,top:0,size:200,fill:"#000",background:null,text:"no text",radius:0,quiet:0,mode:0,mSize:.1,mPosX:.5,mPosY:.5,label:"no label",fontname:"sans",fontcolor:"#000",image:null};w.fn.qrcode=function(r){var t=w.extend({},y,r);return this.each(function(r,e){"canvas"===e.nodeName.toLowerCase()?g(e,t):w(e).append(d(t))})}}(function(){var r=function(){function r(t,e){if("undefined"==typeof t.length)throw new Error(t.length+"/"+e);var n=function(){for(var r=0;re;e+=1){t[e]=new Array(r);for(var n=0;r>n;n+=1)t[e][n]=null}return t}(v),T(0,0),T(v-7,0),T(0,v-7),A(),B(),k(r,t),l>=7&&E(r),null==d&&(d=D(l,g,w)),M(d,t)},T=function(r,t){for(var e=-1;7>=e;e+=1)if(!(-1>=r+e||r+e>=v))for(var n=-1;7>=n;n+=1)-1>=t+n||t+n>=v||(e>=0&&6>=e&&(0==n||6==n)||n>=0&&6>=n&&(0==e||6==e)||e>=2&&4>=e&&n>=2&&4>=n?s[r+e][t+n]=!0:s[r+e][t+n]=!1)},p=function(){for(var r=0,t=0,e=0;8>e;e+=1){y(!0,e);var n=a.getLostPoint(m);(0==e||r>n)&&(r=n,t=e)}return t},B=function(){for(var r=8;v-8>r;r+=1)null==s[r][6]&&(s[r][6]=r%2==0);for(var t=8;v-8>t;t+=1)null==s[6][t]&&(s[6][t]=t%2==0)},A=function(){for(var r=a.getPatternPosition(l),t=0;t=i;i+=1)for(var u=-2;2>=u;u+=1)-2==i||2==i||-2==u||2==u||0==i&&0==u?s[n+i][o+u]=!0:s[n+i][o+u]=!1}},E=function(r){for(var t=a.getBCHTypeNumber(l),e=0;18>e;e+=1){var n=!r&&1==(t>>e&1);s[Math.floor(e/3)][e%3+v-8-3]=n}for(var e=0;18>e;e+=1){var n=!r&&1==(t>>e&1);s[e%3+v-8-3][Math.floor(e/3)]=n}},k=function(r,t){for(var e=g<<3|t,n=a.getBCHTypeInfo(e),o=0;15>o;o+=1){var i=!r&&1==(n>>o&1);6>o?s[o][8]=i:8>o?s[o+1][8]=i:s[v-15+o][8]=i}for(var o=0;15>o;o+=1){var i=!r&&1==(n>>o&1);8>o?s[8][v-o-1]=i:9>o?s[8][15-o-1+1]=i:s[8][15-o-1]=i}s[v-8][8]=!r},M=function(r,t){for(var e=-1,n=v-1,o=7,i=0,u=a.getMaskFunction(t),f=v-1;f>0;f-=2)for(6==f&&(f-=1);;){for(var c=0;2>c;c+=1)if(null==s[n][f-c]){var l=!1;i>>o&1));var g=u(n,f-c);g&&(l=!l),s[n][f-c]=l,o-=1,-1==o&&(i+=1,o=7)}if(n+=e,0>n||n>=v){n-=e,e=-e;break}}},C=function(t,e){for(var n=0,o=0,i=0,u=new Array(e.length),f=new Array(e.length),c=0;c=0?d.getAt(w):0}}for(var m=0,s=0;ss;s+=1)for(var c=0;cs;s+=1)for(var c=0;c8*s)throw new Error("code length overflow. ("+c.getLengthInBits()+">"+8*s+")");for(c.getLengthInBits()+4<=8*s&&c.put(0,4);c.getLengthInBits()%8!=0;)c.putBit(!1);for(;;){if(c.getLengthInBits()>=8*s)break;if(c.put(o,8),c.getLengthInBits()>=8*s)break;c.put(i,8)}return C(c,n)};return m.addData=function(r){var t=c(r);w.push(t),d=null},m.isDark=function(r,t){if(0>r||r>=v||0>t||t>=v)throw new Error(r+","+t);return s[r][t]},m.getModuleCount=function(){return v},m.make=function(){y(!1,p())},m.createTableTag=function(r,t){r=r||2,t="undefined"==typeof t?4*r:t;var e="";e+='";for(var o=0;o';e+=""}return e+="",e+="
"},m.createImgTag=function(r,t){r=r||2,t="undefined"==typeof t?4*r:t;var e=m.getModuleCount()*r+2*t,n=t,o=e-t;return h(e,e,function(t,e){if(t>=n&&o>t&&e>=n&&o>e){var a=Math.floor((t-n)/r),i=Math.floor((e-n)/r);return m.isDark(i,a)?0:1}return 1})},m};t.stringToBytes=function(r){for(var t=new Array,e=0;ea)t.push(a);else{var i=e[r.charAt(o)];"number"==typeof i?(255&i)==i?t.push(i):(t.push(i>>>8),t.push(255&i)):t.push(n)}}return t}};var e={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8},n={L:1,M:0,Q:3,H:2},o={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7},a=function(){var t=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],n=1335,a=7973,u=21522,f={},c=function(r){for(var t=0;0!=r;)t+=1,r>>>=1;return t};return f.getBCHTypeInfo=function(r){for(var t=r<<10;c(t)-c(n)>=0;)t^=n<=0;)t^=a<n;n+=1)e=e.multiply(r([1,i.gexp(n)],0));return e},f.getLengthInBits=function(r,t){if(t>=1&&10>t)switch(r){case e.MODE_NUMBER:return 10;case e.MODE_ALPHA_NUM:return 9;case e.MODE_8BIT_BYTE:return 8;case e.MODE_KANJI:return 8;default:throw new Error("mode:"+r)}else if(27>t)switch(r){case e.MODE_NUMBER:return 12;case e.MODE_ALPHA_NUM:return 11;case e.MODE_8BIT_BYTE:return 16;case e.MODE_KANJI:return 10;default:throw new Error("mode:"+r)}else{if(!(41>t))throw new Error("type:"+t);switch(r){case e.MODE_NUMBER:return 14;case e.MODE_ALPHA_NUM:return 13;case e.MODE_8BIT_BYTE:return 16;case e.MODE_KANJI:return 12;default:throw new Error("mode:"+r)}}},f.getLostPoint=function(r){for(var t=r.getModuleCount(),e=0,n=0;t>n;n+=1)for(var o=0;t>o;o+=1){for(var a=0,i=r.isDark(n,o),u=-1;1>=u;u+=1)if(!(0>n+u||n+u>=t))for(var f=-1;1>=f;f+=1)0>o+f||o+f>=t||(0!=u||0!=f)&&i==r.isDark(n+u,o+f)&&(a+=1);a>5&&(e+=3+a-5)}for(var n=0;t-1>n;n+=1)for(var o=0;t-1>o;o+=1){var c=0;r.isDark(n,o)&&(c+=1),r.isDark(n+1,o)&&(c+=1),r.isDark(n,o+1)&&(c+=1),r.isDark(n+1,o+1)&&(c+=1),(0==c||4==c)&&(e+=3)}for(var n=0;t>n;n+=1)for(var o=0;t-6>o;o+=1)r.isDark(n,o)&&!r.isDark(n,o+1)&&r.isDark(n,o+2)&&r.isDark(n,o+3)&&r.isDark(n,o+4)&&!r.isDark(n,o+5)&&r.isDark(n,o+6)&&(e+=40);for(var o=0;t>o;o+=1)for(var n=0;t-6>n;n+=1)r.isDark(n,o)&&!r.isDark(n+1,o)&&r.isDark(n+2,o)&&r.isDark(n+3,o)&&r.isDark(n+4,o)&&!r.isDark(n+5,o)&&r.isDark(n+6,o)&&(e+=40);for(var l=0,o=0;t>o;o+=1)for(var n=0;t>n;n+=1)r.isDark(n,o)&&(l+=1);var g=Math.abs(100*l/t/t-50)/5;return e+=10*g},f}(),i=function(){for(var r=new Array(256),t=new Array(256),e=0;8>e;e+=1)r[e]=1<e;e+=1)r[e]=r[e-4]^r[e-5]^r[e-6]^r[e-8];for(var e=0;255>e;e+=1)t[r[e]]=e;var n={};return n.glog=function(r){if(1>r)throw new Error("glog("+r+")");return t[r]},n.gexp=function(t){for(;0>t;)t+=255;for(;t>=256;)t-=255;return r[t]},n}(),u=function(){var r=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12,7,37,13],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]],t=function(r,t){var e={};return e.totalCount=r,e.dataCount=t,e},e={},o=function(t,e){switch(e){case n.L:return r[4*(t-1)+0];case n.M:return r[4*(t-1)+1];case n.Q:return r[4*(t-1)+2];case n.H:return r[4*(t-1)+3];default:return}};return e.getRSBlocks=function(r,e){var n=o(r,e);if("undefined"==typeof n)throw new Error("bad rs block @ typeNumber:"+r+"/errorCorrectLevel:"+e);for(var a=n.length/3,i=new Array,u=0;a>u;u+=1)for(var f=n[3*u+0],c=n[3*u+1],l=n[3*u+2],g=0;f>g;g+=1)i.push(t(c,l));return i},e}(),f=function(){var r=new Array,t=0,e={};return e.getBuffer=function(){return r},e.getAt=function(t){var e=Math.floor(t/8);return 1==(r[e]>>>7-t%8&1)},e.put=function(r,t){for(var n=0;t>n;n+=1)e.putBit(1==(r>>>t-n-1&1))},e.getLengthInBits=function(){return t},e.putBit=function(e){var n=Math.floor(t/8);r.length<=n&&r.push(0),e&&(r[n]|=128>>>t%8),t+=1},e},c=function(r){var n=e.MODE_8BIT_BYTE,o=t.stringToBytes(r),a={};return a.getMode=function(){return n},a.getLength=function(r){return o.length},a.write=function(r){for(var t=0;t>>8)},t.writeBytes=function(r,e,n){e=e||0,n=n||r.length;for(var o=0;n>o;o+=1)t.writeByte(r[o+e])},t.writeString=function(r){for(var e=0;e0&&(t+=","),t+=r[e];return t+="]"},t},g=function(){var r=0,t=0,e=0,n="",o={},a=function(r){n+=String.fromCharCode(i(63&r))},i=function(r){if(0>r);else{if(26>r)return 65+r;if(52>r)return 97+(r-26);if(62>r)return 48+(r-52);if(62==r)return 43;if(63==r)return 47}throw new Error("n:"+r)};return o.writeByte=function(n){for(r=r<<8|255&n,t+=8,e+=1;t>=6;)a(r>>>t-6),t-=6},o.flush=function(){if(t>0&&(a(r<<6-t),r=0,t=0),e%3!=0)for(var o=3-e%3,i=0;o>i;i+=1)n+="="},o.toString=function(){return n},o},s=function(r){var t=r,e=0,n=0,o=0,a={};a.read=function(){for(;8>o;){if(e>=t.length){if(0==o)return-1;throw new Error("unexpected end of file./"+o)}var r=t.charAt(e);if(e+=1,"="==r)return o=0,-1;r.match(/^\s$/)||(n=n<<6|i(r.charCodeAt(0)),o+=6)}var a=n>>>o-8&255;return o-=8,a};var i=function(r){if(r>=65&&90>=r)return r-65;if(r>=97&&122>=r)return r-97+26;if(r>=48&&57>=r)return r-48+52;if(43==r)return 62;if(47==r)return 63;throw new Error("c:"+r)};return a},v=function(r,t){var e=r,n=t,o=new Array(r*t),a={};a.setPixel=function(r,t,n){o[t*e+r]=n},a.write=function(r){r.writeString("GIF87a"),r.writeShort(e),r.writeShort(n),r.writeByte(128),r.writeByte(0),r.writeByte(0),r.writeByte(0),r.writeByte(0),r.writeByte(0),r.writeByte(255),r.writeByte(255),r.writeByte(255),r.writeString(","),r.writeShort(0),r.writeShort(0),r.writeShort(e),r.writeShort(n),r.writeByte(0);var t=2,o=u(t);r.writeByte(t);for(var a=0;o.length-a>255;)r.writeByte(255),r.writeBytes(o,a,255),a+=255;r.writeByte(o.length-a),r.writeBytes(o,a,o.length-a),r.writeByte(0),r.writeString(";")};var i=function(r){var t=r,e=0,n=0,o={};return o.write=function(r,o){if(r>>>o!=0)throw new Error("length over");for(;e+o>=8;)t.writeByte(255&(r<>>=8-e,n=0,e=0;n=r<0&&t.writeByte(n)},o},u=function(r){for(var t=1<u;u+=1)a.add(String.fromCharCode(u));a.add(String.fromCharCode(t)),a.add(String.fromCharCode(e));var c=l(),g=i(c);g.write(t,n);var s=0,v=String.fromCharCode(o[s]);for(s+=1;sa;a+=1)for(var i=0;r>i;i+=1)o.setPixel(i,a,e(i,a));var u=l();o.write(u);for(var f=g(),c=u.toByteArray(),s=0;sn?t.push(n):2048>n?t.push(192|n>>6,128|63&n):55296>n||n>=57344?t.push(224|n>>12,128|n>>6&63,128|63&n):(e++,n=65536+((1023&n)<<10|1023&r.charCodeAt(e)),t.push(240|n>>18,128|n>>12&63,128|n>>6&63,128|63&n))}return t}return t(r)}}(r),r}()); \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery.blockUI.js b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery.blockUI.js new file mode 100755 index 00000000..29b1325f --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery.blockUI.js @@ -0,0 +1,619 @@ +/*! + * jQuery blockUI plugin + * Version 2.70.0-2014.11.23 + * Requires jQuery v1.7 or later + * + * Examples at: http://malsup.com/jquery/block/ + * Copyright (c) 2007-2013 M. Alsup + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * Thanks to Amir-Hossein Sobhi for some excellent contributions! + */ +;(function() { +/*jshint eqeqeq:false curly:false latedef:false */ +"use strict"; + + function setup($) { + $.fn._fadeIn = $.fn.fadeIn; + + var noOp = $.noop || function() {}; + + // this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle + // confusing userAgent strings on Vista) + var msie = /MSIE/.test(navigator.userAgent); + var ie6 = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent); + var mode = document.documentMode || 0; + var setExpr = $.isFunction( document.createElement('div').style.setExpression ); + + // global $ methods for blocking/unblocking the entire page + $.blockUI = function(opts) { install(window, opts); }; + $.unblockUI = function(opts) { remove(window, opts); }; + + // convenience method for quick growl-like notifications (http://www.google.com/search?q=growl) + $.growlUI = function(title, message, timeout, onClose) { + var $m = $('
'); + if (title) $m.append('

'+title+'

'); + if (message) $m.append('

'+message+'

'); + if (timeout === undefined) timeout = 3000; + + // Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications + var callBlock = function(opts) { + opts = opts || {}; + + $.blockUI({ + message: $m, + fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700, + fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000, + timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout, + centerY: false, + showOverlay: false, + onUnblock: onClose, + css: $.blockUI.defaults.growlCSS + }); + }; + + callBlock(); + var nonmousedOpacity = $m.css('opacity'); + $m.mouseover(function() { + callBlock({ + fadeIn: 0, + timeout: 30000 + }); + + var displayBlock = $('.blockMsg'); + displayBlock.stop(); // cancel fadeout if it has started + displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency + }).mouseout(function() { + $('.blockMsg').fadeOut(1000); + }); + // End konapun additions + }; + + // plugin method for blocking element content + $.fn.block = function(opts) { + if ( this[0] === window ) { + $.blockUI( opts ); + return this; + } + var fullOpts = $.extend({}, $.blockUI.defaults, opts || {}); + this.each(function() { + var $el = $(this); + if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked')) + return; + $el.unblock({ fadeOut: 0 }); + }); + + return this.each(function() { + if ($.css(this,'position') == 'static') { + this.style.position = 'relative'; + $(this).data('blockUI.static', true); + } + this.style.zoom = 1; // force 'hasLayout' in ie + install(this, opts); + }); + }; + + // plugin method for unblocking element content + $.fn.unblock = function(opts) { + if ( this[0] === window ) { + $.unblockUI( opts ); + return this; + } + return this.each(function() { + remove(this, opts); + }); + }; + + $.blockUI.version = 2.70; // 2nd generation blocking at no extra cost! + + // override these in your code to change the default behavior and style + $.blockUI.defaults = { + // message displayed when blocking (use null for no message) + message: '

Please wait...

', + + title: null, // title string; only used when theme == true + draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded) + + theme: false, // set to true to use with jQuery UI themes + + // styles for the message when blocking; if you wish to disable + // these and use an external stylesheet then do this in your code: + // $.blockUI.defaults.css = {}; + css: { + padding: 0, + margin: 0, + width: '30%', + top: '40%', + left: '35%', + textAlign: 'center', + color: '#000', + border: '3px solid #aaa', + backgroundColor:'#fff', + cursor: 'wait' + }, + + // minimal style set used when themes are used + themedCSS: { + width: '30%', + top: '40%', + left: '35%' + }, + + // styles for the overlay + overlayCSS: { + backgroundColor: '#000', + opacity: 0.6, + cursor: 'wait' + }, + + // style to replace wait cursor before unblocking to correct issue + // of lingering wait cursor + cursorReset: 'default', + + // styles applied when using $.growlUI + growlCSS: { + width: '350px', + top: '10px', + left: '', + right: '10px', + border: 'none', + padding: '5px', + opacity: 0.6, + cursor: 'default', + color: '#fff', + backgroundColor: '#000', + '-webkit-border-radius':'10px', + '-moz-border-radius': '10px', + 'border-radius': '10px' + }, + + // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w + // (hat tip to Jorge H. N. de Vasconcelos) + /*jshint scripturl:true */ + iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank', + + // force usage of iframe in non-IE browsers (handy for blocking applets) + forceIframe: false, + + // z-index for the blocking overlay + baseZ: 1000, + + // set these to true to have the message automatically centered + centerX: true, // <-- only effects element blocking (page block controlled via css above) + centerY: true, + + // allow body element to be stetched in ie6; this makes blocking look better + // on "short" pages. disable if you wish to prevent changes to the body height + allowBodyStretch: true, + + // enable if you want key and mouse events to be disabled for content that is blocked + bindEvents: true, + + // be default blockUI will suppress tab navigation from leaving blocking content + // (if bindEvents is true) + constrainTabKey: true, + + // fadeIn time in millis; set to 0 to disable fadeIn on block + fadeIn: 200, + + // fadeOut time in millis; set to 0 to disable fadeOut on unblock + fadeOut: 400, + + // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock + timeout: 0, + + // disable if you don't want to show the overlay + showOverlay: true, + + // if true, focus will be placed in the first available input field when + // page blocking + focusInput: true, + + // elements that can receive focus + focusableElements: ':input:enabled:visible', + + // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity) + // no longer needed in 2012 + // applyPlatformOpacityRules: true, + + // callback method invoked when fadeIn has completed and blocking message is visible + onBlock: null, + + // callback method invoked when unblocking has completed; the callback is + // passed the element that has been unblocked (which is the window object for page + // blocks) and the options that were passed to the unblock call: + // onUnblock(element, options) + onUnblock: null, + + // callback method invoked when the overlay area is clicked. + // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used. + onOverlayClick: null, + + // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493 + quirksmodeOffsetHack: 4, + + // class name of the message block + blockMsgClass: 'blockMsg', + + // if it is already blocked, then ignore it (don't unblock and reblock) + ignoreIfBlocked: false + }; + + // private data and functions follow... + + var pageBlock = null; + var pageBlockEls = []; + + function install(el, opts) { + var css, themedCSS; + var full = (el == window); + var msg = (opts && opts.message !== undefined ? opts.message : undefined); + opts = $.extend({}, $.blockUI.defaults, opts || {}); + + if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked')) + return; + + opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {}); + css = $.extend({}, $.blockUI.defaults.css, opts.css || {}); + if (opts.onOverlayClick) + opts.overlayCSS.cursor = 'pointer'; + + themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {}); + msg = msg === undefined ? opts.message : msg; + + // remove the current block (if there is one) + if (full && pageBlock) + remove(window, {fadeOut:0}); + + // if an existing element is being used as the blocking content then we capture + // its current place in the DOM (and current display style) so we can restore + // it when we unblock + if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) { + var node = msg.jquery ? msg[0] : msg; + var data = {}; + $(el).data('blockUI.history', data); + data.el = node; + data.parent = node.parentNode; + data.display = node.style.display; + data.position = node.style.position; + if (data.parent) + data.parent.removeChild(node); + } + + $(el).data('blockUI.onUnblock', opts.onUnblock); + var z = opts.baseZ; + + // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform; + // layer1 is the iframe layer which is used to suppress bleed through of underlying content + // layer2 is the overlay layer which has opacity and a wait cursor (by default) + // layer3 is the message content that is displayed while blocking + var lyr1, lyr2, lyr3, s; + if (msie || opts.forceIframe) + lyr1 = $(''); + else + lyr1 = $(''); + + if (opts.theme) + lyr2 = $(''); + else + lyr2 = $(''); + + if (opts.theme && full) { + s = ''; + } + else if (opts.theme) { + s = ''; + } + else if (full) { + s = ''; + } + else { + s = ''; + } + lyr3 = $(s); + + // if we have a message, style it + if (msg) { + if (opts.theme) { + lyr3.css(themedCSS); + lyr3.addClass('ui-widget-content'); + } + else + lyr3.css(css); + } + + // style the overlay + if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/) + lyr2.css(opts.overlayCSS); + lyr2.css('position', full ? 'fixed' : 'absolute'); + + // make iframe layer transparent in IE + if (msie || opts.forceIframe) + lyr1.css('opacity',0.0); + + //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el); + var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el); + $.each(layers, function() { + this.appendTo($par); + }); + + if (opts.theme && opts.draggable && $.fn.draggable) { + lyr3.draggable({ + handle: '.ui-dialog-titlebar', + cancel: 'li' + }); + } + + // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling) + var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0); + if (ie6 || expr) { + // give body 100% height + if (full && opts.allowBodyStretch && $.support.boxModel) + $('html,body').css('height','100%'); + + // fix ie6 issue when blocked element has a border width + if ((ie6 || !$.support.boxModel) && !full) { + var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth'); + var fixT = t ? '(0 - '+t+')' : 0; + var fixL = l ? '(0 - '+l+')' : 0; + } + + // simulate fixed position + $.each(layers, function(i,o) { + var s = o[0].style; + s.position = 'absolute'; + if (i < 2) { + if (full) + s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"'); + else + s.setExpression('height','this.parentNode.offsetHeight + "px"'); + if (full) + s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"'); + else + s.setExpression('width','this.parentNode.offsetWidth + "px"'); + if (fixL) s.setExpression('left', fixL); + if (fixT) s.setExpression('top', fixT); + } + else if (opts.centerY) { + if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"'); + s.marginTop = 0; + } + else if (!opts.centerY && full) { + var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0; + var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"'; + s.setExpression('top',expression); + } + }); + } + + // show the message + if (msg) { + if (opts.theme) + lyr3.find('.ui-widget-content').append(msg); + else + lyr3.append(msg); + if (msg.jquery || msg.nodeType) + $(msg).show(); + } + + if ((msie || opts.forceIframe) && opts.showOverlay) + lyr1.show(); // opacity is zero + if (opts.fadeIn) { + var cb = opts.onBlock ? opts.onBlock : noOp; + var cb1 = (opts.showOverlay && !msg) ? cb : noOp; + var cb2 = msg ? cb : noOp; + if (opts.showOverlay) + lyr2._fadeIn(opts.fadeIn, cb1); + if (msg) + lyr3._fadeIn(opts.fadeIn, cb2); + } + else { + if (opts.showOverlay) + lyr2.show(); + if (msg) + lyr3.show(); + if (opts.onBlock) + opts.onBlock.bind(lyr3)(); + } + + // bind key and mouse events + bind(1, el, opts); + + if (full) { + pageBlock = lyr3[0]; + pageBlockEls = $(opts.focusableElements,pageBlock); + if (opts.focusInput) + setTimeout(focus, 20); + } + else + center(lyr3[0], opts.centerX, opts.centerY); + + if (opts.timeout) { + // auto-unblock + var to = setTimeout(function() { + if (full) + $.unblockUI(opts); + else + $(el).unblock(opts); + }, opts.timeout); + $(el).data('blockUI.timeout', to); + } + } + + // remove the block + function remove(el, opts) { + var count; + var full = (el == window); + var $el = $(el); + var data = $el.data('blockUI.history'); + var to = $el.data('blockUI.timeout'); + if (to) { + clearTimeout(to); + $el.removeData('blockUI.timeout'); + } + opts = $.extend({}, $.blockUI.defaults, opts || {}); + bind(0, el, opts); // unbind events + + if (opts.onUnblock === null) { + opts.onUnblock = $el.data('blockUI.onUnblock'); + $el.removeData('blockUI.onUnblock'); + } + + var els; + if (full) // crazy selector to handle odd field errors in ie6/7 + els = $('body').children().filter('.blockUI').add('body > .blockUI'); + else + els = $el.find('>.blockUI'); + + // fix cursor issue + if ( opts.cursorReset ) { + if ( els.length > 1 ) + els[1].style.cursor = opts.cursorReset; + if ( els.length > 2 ) + els[2].style.cursor = opts.cursorReset; + } + + if (full) + pageBlock = pageBlockEls = null; + + if (opts.fadeOut) { + count = els.length; + els.stop().fadeOut(opts.fadeOut, function() { + if ( --count === 0) + reset(els,data,opts,el); + }); + } + else + reset(els, data, opts, el); + } + + // move blocking element back into the DOM where it started + function reset(els,data,opts,el) { + var $el = $(el); + if ( $el.data('blockUI.isBlocked') ) + return; + + els.each(function(i,o) { + // remove via DOM calls so we don't lose event handlers + if (this.parentNode) + this.parentNode.removeChild(this); + }); + + if (data && data.el) { + data.el.style.display = data.display; + data.el.style.position = data.position; + data.el.style.cursor = 'default'; // #59 + if (data.parent) + data.parent.appendChild(data.el); + $el.removeData('blockUI.history'); + } + + if ($el.data('blockUI.static')) { + $el.css('position', 'static'); // #22 + } + + if (typeof opts.onUnblock == 'function') + opts.onUnblock(el,opts); + + // fix issue in Safari 6 where block artifacts remain until reflow + var body = $(document.body), w = body.width(), cssW = body[0].style.width; + body.width(w-1).width(w); + body[0].style.width = cssW; + } + + // bind/unbind the handler + function bind(b, el, opts) { + var full = el == window, $el = $(el); + + // don't bother unbinding if there is nothing to unbind + if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked'))) + return; + + $el.data('blockUI.isBlocked', b); + + // don't bind events when overlay is not in use or if bindEvents is false + if (!full || !opts.bindEvents || (b && !opts.showOverlay)) + return; + + // bind anchors and inputs for mouse and key events + var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove'; + if (b) + $(document).bind(events, opts, handler); + else + $(document).unbind(events, handler); + + // former impl... + // var $e = $('a,:input'); + // b ? $e.bind(events, opts, handler) : $e.unbind(events, handler); + } + + // event handler to suppress keyboard/mouse events when blocking + function handler(e) { + // allow tab navigation (conditionally) + if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) { + if (pageBlock && e.data.constrainTabKey) { + var els = pageBlockEls; + var fwd = !e.shiftKey && e.target === els[els.length-1]; + var back = e.shiftKey && e.target === els[0]; + if (fwd || back) { + setTimeout(function(){focus(back);},10); + return false; + } + } + } + var opts = e.data; + var target = $(e.target); + if (target.hasClass('blockOverlay') && opts.onOverlayClick) + opts.onOverlayClick(e); + + // allow events within the message content + if (target.parents('div.' + opts.blockMsgClass).length > 0) + return true; + + // allow events for content that is not being blocked + return target.parents().children().filter('div.blockUI').length === 0; + } + + function focus(back) { + if (!pageBlockEls) + return; + var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0]; + if (e) + e.focus(); + } + + function center(el, x, y) { + var p = el.parentNode, s = el.style; + var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth'); + var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth'); + if (x) s.left = l > 0 ? (l+'px') : '0'; + if (y) s.top = t > 0 ? (t+'px') : '0'; + } + + function sz(el, p) { + return parseInt($.css(el,p),10)||0; + } + + } + + + /*global define:true */ + if (typeof define === 'function' && define.amd && define.amd.jQuery) { + define(['jquery'], setup); + } else { + setup(jQuery); + } + +})(); \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery.blockUI.min.js b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery.blockUI.min.js new file mode 100755 index 00000000..47fb9744 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/jquery.blockUI.min.js @@ -0,0 +1,14 @@ +/*! + * jQuery blockUI plugin + * Version 2.70.0-2014.11.23 + * Requires jQuery v1.7 or later + * + * Examples at: http://malsup.com/jquery/block/ + * Copyright (c) 2007-2013 M. Alsup + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * Thanks to Amir-Hossein Sobhi for some excellent contributions! + */ +!function(){"use strict";function a(a){function b(b,d){var f,p,q=b==window,r=d&&void 0!==d.message?d.message:void 0;if(d=a.extend({},a.blockUI.defaults,d||{}),!d.ignoreIfBlocked||!a(b).data("blockUI.isBlocked")){if(d.overlayCSS=a.extend({},a.blockUI.defaults.overlayCSS,d.overlayCSS||{}),f=a.extend({},a.blockUI.defaults.css,d.css||{}),d.onOverlayClick&&(d.overlayCSS.cursor="pointer"),p=a.extend({},a.blockUI.defaults.themedCSS,d.themedCSS||{}),r=void 0===r?d.message:r,q&&n&&c(window,{fadeOut:0}),r&&"string"!=typeof r&&(r.parentNode||r.jquery)){var s=r.jquery?r[0]:r,t={};a(b).data("blockUI.history",t),t.el=s,t.parent=s.parentNode,t.display=s.style.display,t.position=s.style.position,t.parent&&t.parent.removeChild(s)}a(b).data("blockUI.onUnblock",d.onUnblock);var u,v,w,x,y=d.baseZ;u=a(k||d.forceIframe?'':''),v=a(d.theme?'':''),d.theme&&q?(x='"):d.theme?(x='"):x=q?'':'',w=a(x),r&&(d.theme?(w.css(p),w.addClass("ui-widget-content")):w.css(f)),d.theme||v.css(d.overlayCSS),v.css("position",q?"fixed":"absolute"),(k||d.forceIframe)&&u.css("opacity",0);var z=[u,v,w],A=a(q?"body":b);a.each(z,function(){this.appendTo(A)}),d.theme&&d.draggable&&a.fn.draggable&&w.draggable({handle:".ui-dialog-titlebar",cancel:"li"});var B=m&&(!a.support.boxModel||a("object,embed",q?null:b).length>0);if(l||B){if(q&&d.allowBodyStretch&&a.support.boxModel&&a("html,body").css("height","100%"),(l||!a.support.boxModel)&&!q)var C=i(b,"borderTopWidth"),D=i(b,"borderLeftWidth"),E=C?"(0 - "+C+")":0,F=D?"(0 - "+D+")":0;a.each(z,function(a,b){var c=b[0].style;if(c.position="absolute",2>a)q?c.setExpression("height","Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:"+d.quirksmodeOffsetHack+') + "px"'):c.setExpression("height",'this.parentNode.offsetHeight + "px"'),q?c.setExpression("width",'jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"'):c.setExpression("width",'this.parentNode.offsetWidth + "px"'),F&&c.setExpression("left",F),E&&c.setExpression("top",E);else if(d.centerY)q&&c.setExpression("top",'(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"'),c.marginTop=0;else if(!d.centerY&&q){var e=d.css&&d.css.top?parseInt(d.css.top,10):0,f="((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "+e+') + "px"';c.setExpression("top",f)}})}if(r&&(d.theme?w.find(".ui-widget-content").append(r):w.append(r),(r.jquery||r.nodeType)&&a(r).show()),(k||d.forceIframe)&&d.showOverlay&&u.show(),d.fadeIn){var G=d.onBlock?d.onBlock:j,H=d.showOverlay&&!r?G:j,I=r?G:j;d.showOverlay&&v._fadeIn(d.fadeIn,H),r&&w._fadeIn(d.fadeIn,I)}else d.showOverlay&&v.show(),r&&w.show(),d.onBlock&&d.onBlock.bind(w)();if(e(1,b,d),q?(n=w[0],o=a(d.focusableElements,n),d.focusInput&&setTimeout(g,20)):h(w[0],d.centerX,d.centerY),d.timeout){var J=setTimeout(function(){q?a.unblockUI(d):a(b).unblock(d)},d.timeout);a(b).data("blockUI.timeout",J)}}}function c(b,c){var f,g=b==window,h=a(b),i=h.data("blockUI.history"),j=h.data("blockUI.timeout");j&&(clearTimeout(j),h.removeData("blockUI.timeout")),c=a.extend({},a.blockUI.defaults,c||{}),e(0,b,c),null===c.onUnblock&&(c.onUnblock=h.data("blockUI.onUnblock"),h.removeData("blockUI.onUnblock"));var k;k=g?a("body").children().filter(".blockUI").add("body > .blockUI"):h.find(">.blockUI"),c.cursorReset&&(k.length>1&&(k[1].style.cursor=c.cursorReset),k.length>2&&(k[2].style.cursor=c.cursorReset)),g&&(n=o=null),c.fadeOut?(f=k.length,k.stop().fadeOut(c.fadeOut,function(){0===--f&&d(k,i,c,b)})):d(k,i,c,b)}function d(b,c,d,e){var f=a(e);if(!f.data("blockUI.isBlocked")){b.each(function(){this.parentNode&&this.parentNode.removeChild(this)}),c&&c.el&&(c.el.style.display=c.display,c.el.style.position=c.position,c.el.style.cursor="default",c.parent&&c.parent.appendChild(c.el),f.removeData("blockUI.history")),f.data("blockUI.static")&&f.css("position","static"),"function"==typeof d.onUnblock&&d.onUnblock(e,d);var g=a(document.body),h=g.width(),i=g[0].style.width;g.width(h-1).width(h),g[0].style.width=i}}function e(b,c,d){var e=c==window,g=a(c);if((b||(!e||n)&&(e||g.data("blockUI.isBlocked")))&&(g.data("blockUI.isBlocked",b),e&&d.bindEvents&&(!b||d.showOverlay))){var h="mousedown mouseup keydown keypress keyup touchstart touchend touchmove";b?a(document).bind(h,d,f):a(document).unbind(h,f)}}function f(b){if("keydown"===b.type&&b.keyCode&&9==b.keyCode&&n&&b.data.constrainTabKey){var c=o,d=!b.shiftKey&&b.target===c[c.length-1],e=b.shiftKey&&b.target===c[0];if(d||e)return setTimeout(function(){g(e)},10),!1}var f=b.data,h=a(b.target);return h.hasClass("blockOverlay")&&f.onOverlayClick&&f.onOverlayClick(b),h.parents("div."+f.blockMsgClass).length>0?!0:0===h.parents().children().filter("div.blockUI").length}function g(a){if(o){var b=o[a===!0?o.length-1:0];b&&b.focus()}}function h(a,b,c){var d=a.parentNode,e=a.style,f=(d.offsetWidth-a.offsetWidth)/2-i(d,"borderLeftWidth"),g=(d.offsetHeight-a.offsetHeight)/2-i(d,"borderTopWidth");b&&(e.left=f>0?f+"px":"0"),c&&(e.top=g>0?g+"px":"0")}function i(b,c){return parseInt(a.css(b,c),10)||0}a.fn._fadeIn=a.fn.fadeIn;var j=a.noop||function(){},k=/MSIE/.test(navigator.userAgent),l=/MSIE 6.0/.test(navigator.userAgent)&&!/MSIE 8.0/.test(navigator.userAgent),m=(document.documentMode||0,a.isFunction(document.createElement("div").style.setExpression));a.blockUI=function(a){b(window,a)},a.unblockUI=function(a){c(window,a)},a.growlUI=function(b,c,d,e){var f=a('
');b&&f.append("

"+b+"

"),c&&f.append("

"+c+"

"),void 0===d&&(d=3e3);var g=function(b){b=b||{},a.blockUI({message:f,fadeIn:"undefined"!=typeof b.fadeIn?b.fadeIn:700,fadeOut:"undefined"!=typeof b.fadeOut?b.fadeOut:1e3,timeout:"undefined"!=typeof b.timeout?b.timeout:d,centerY:!1,showOverlay:!1,onUnblock:e,css:a.blockUI.defaults.growlCSS})};g();f.css("opacity");f.mouseover(function(){g({fadeIn:0,timeout:3e4});var b=a(".blockMsg");b.stop(),b.fadeTo(300,1)}).mouseout(function(){a(".blockMsg").fadeOut(1e3)})},a.fn.block=function(c){if(this[0]===window)return a.blockUI(c),this;var d=a.extend({},a.blockUI.defaults,c||{});return this.each(function(){var b=a(this);d.ignoreIfBlocked&&b.data("blockUI.isBlocked")||b.unblock({fadeOut:0})}),this.each(function(){"static"==a.css(this,"position")&&(this.style.position="relative",a(this).data("blockUI.static",!0)),this.style.zoom=1,b(this,c)})},a.fn.unblock=function(b){return this[0]===window?(a.unblockUI(b),this):this.each(function(){c(this,b)})},a.blockUI.version=2.7,a.blockUI.defaults={message:"

Please wait...

",title:null,draggable:!0,theme:!1,css:{padding:0,margin:0,width:"30%",top:"40%",left:"35%",textAlign:"center",color:"#000",border:"3px solid #aaa",backgroundColor:"#fff",cursor:"wait"},themedCSS:{width:"30%",top:"40%",left:"35%"},overlayCSS:{backgroundColor:"#000",opacity:.6,cursor:"wait"},cursorReset:"default",growlCSS:{width:"350px",top:"10px",left:"",right:"10px",border:"none",padding:"5px",opacity:.6,cursor:"default",color:"#fff",backgroundColor:"#000","-webkit-border-radius":"10px","-moz-border-radius":"10px","border-radius":"10px"},iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank",forceIframe:!1,baseZ:1e3,centerX:!0,centerY:!0,allowBodyStretch:!0,bindEvents:!0,constrainTabKey:!0,fadeIn:200,fadeOut:400,timeout:0,showOverlay:!0,focusInput:!0,focusableElements:":input:enabled:visible",onBlock:null,onUnblock:null,onOverlayClick:null,quirksmodeOffsetHack:4,blockMsgClass:"blockMsg",ignoreIfBlocked:!1};var n=null,o=[]}"function"==typeof define&&define.amd&&define.amd.jQuery?define(["jquery"],a):a(jQuery)}(); \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/login-form-integrations.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/login-form-integrations.php new file mode 100755 index 00000000..931560a9 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/login-form-integrations.php @@ -0,0 +1,146 @@ +tfa = $tfa; + + $enqueue_upon_actions = array( + // This is needed for the login form on the dedicated payment page (e.g. /checkout/order-pay/123456/?pay_for_order=true&key=wc_order_blahblahblah) + 'woocommerce_login_form_start', + 'woocommerce_before_customer_login_form', + // The login form on the checkout doesn't call the woocommerce_before_customer_login_form action + 'woocommerce_before_checkout_form', + 'affwp_login_fields_before', + ); + + foreach ($enqueue_upon_actions as $action) { + add_action($action, array($this->tfa, 'login_enqueue_scripts')); + } + + if (!defined('TWO_FACTOR_DISABLE') || !TWO_FACTOR_DISABLE) { + add_action('affwp_process_login_form', array($this, 'affwp_process_login_form')); + } + + add_filter('tml_display', array($this, 'tml_display')); + add_filter('wppb_login_form_bottom', array($this, 'pb_login_form')); + + // We want to run first if possible, so that we're not aborted by JavaScript exceptions in other components (our code is critical to the login process for TFA users) + // Unfortunately, though, people start enqueuing from init onwards (before that is buggy - https://core.trac.wordpress.org/ticket/11526), so, we try to detect the login page and go earlier there. + if (isset($GLOBALS['pagenow']) && 'wp-login.php' === $GLOBALS['pagenow']) { + add_action('init', array($this->tfa, 'login_enqueue_scripts'), -99999999999); + } else { + add_action('login_enqueue_scripts', array($this->tfa, 'login_enqueue_scripts'), -99999999999); + } + + add_filter('do_shortcode_tag', array($this, 'do_shortcode_tag'), 10, 2); + + add_filter('simba_tfa_login_enqueue_localize', array($this, 'simba_tfa_login_enqueue_localize'), 9); + + } + + /** + * Catch TML login widgets (other TML login forms already trigger) + * + * @param Mixed $whatever + * + * @return Mixed + */ + public function tml_display($whatever) { + $this->tfa->login_enqueue_scripts(); + return $whatever; + } + + /** + * Catch Profile Builder login form + * + * @param Mixed $whatever + * + * @return Mixed + */ + public function pb_login_form($whatever) { + $this->tfa->login_enqueue_scripts(); + return $whatever; + } + + /** + * Runs upon the WP filter simba_tfa_login_enqueue_localize. + * + * @param Array $localize + * + * @return Array + */ + public function simba_tfa_login_enqueue_localize($localize) { + // WP login form is #loginform + // Ultimate Membership Pro - April 2018 + // Theme My Login 6.x - .tml-login form[name="loginform"] + // Theme My Login 7.x - .tml-login form[name="login"] (July 2018) + // WP Members - March 2018 + // bbPress - June 2021 + // WooCommerce - ported over from the separate wooextend.js code, June 2021 + // Affiliates WP - ported over from the separate wooextend.js code, June 2021 + $localize['login_form_selectors'] .= '.tml-login form[name="loginform"], .tml-login form[name="login"], #loginform, #wpmem_login form, form#ihc_login_form, .bbp-login-form, .woocommerce form.login, #affwp-login-form, #wppb-loginform'; + $localize['login_form_off_selectors'] .= '#ihc_login_form'; + return $localize; + } + + /** + * Runs upon the WP action affwp_process_login_form + */ + public function affwp_process_login_form() { + + if (!function_exists('affiliate_wp')) return; + + $affiliate_wp = affiliate_wp(); + $login = $affiliate_wp->login; + + $params = array( + // phpcs:ignore WordPress.Security.NonceVerification -- No nonce. + 'log' => isset($_POST['affwp_user_login']) ? sanitize_user(wp_unslash($_POST['affwp_user_login'])): '', + + $request_uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : '', + 'caller'=> isset($_SERVER['PHP_SELF']) ? sanitize_text_field(wp_unslash($_SERVER['PHP_SELF'])) : $request_uri, + // phpcs:ignore WordPress.Security.NonceVerification -- No nonce. + 'two_factor_code' => isset($_POST['two_factor_code']) ? sanitize_text_field(wp_unslash((string) $_POST['two_factor_code'])) : '', + ); + $code_ok = $this->tfa->authorise_user_from_login($params, true); + + $code_ok = apply_filters('simbatfa_affwp_process_login_form_auth_result', $code_ok, $params); + + if (is_wp_error($code_ok)) { + $login->add_error($code_ok->get_error_code(), $code_ok->get_error_message()); + } elseif (!$code_ok) { + $login->add_error('authentication_failed', __('Error:', 'all-in-one-wp-security-and-firewall').' '.apply_filters('simba_tfa_message_code_incorrect', __('The one-time password (TFA code) you entered was incorrect.', 'all-in-one-wp-security-and-firewall'))); + } + + } + + /** + * Ultimate Membership Pro support + * + * @param String $output + * @param String $tag + * + * @return String + */ + public function do_shortcode_tag($output, $tag) { + if ('ihc-login-form' == $tag) $this->tfa->login_enqueue_scripts(); + return $output; + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/select2.css b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/select2.css new file mode 100755 index 00000000..750b3207 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/select2.css @@ -0,0 +1,481 @@ +.select2-container { + box-sizing: border-box; + display: inline-block; + margin: 0; + position: relative; + vertical-align: middle; } + .select2-container .select2-selection--single { + box-sizing: border-box; + cursor: pointer; + display: block; + height: 28px; + user-select: none; + -webkit-user-select: none; } + .select2-container .select2-selection--single .select2-selection__rendered { + display: block; + padding-left: 8px; + padding-right: 20px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } + .select2-container .select2-selection--single .select2-selection__clear { + position: relative; } + .select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered { + padding-right: 8px; + padding-left: 20px; } + .select2-container .select2-selection--multiple { + box-sizing: border-box; + cursor: pointer; + display: block; + min-height: 32px; + user-select: none; + -webkit-user-select: none; } + .select2-container .select2-selection--multiple .select2-selection__rendered { + display: inline-block; + overflow: hidden; + padding-left: 8px; + text-overflow: ellipsis; + white-space: nowrap; } + .select2-container .select2-search--inline { + float: left; } + .select2-container .select2-search--inline .select2-search__field { + box-sizing: border-box; + border: none; + font-size: 100%; + margin-top: 5px; + padding: 0; } + .select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button { + -webkit-appearance: none; } + +.select2-dropdown { + background-color: white; + border: 1px solid #aaa; + border-radius: 4px; + box-sizing: border-box; + display: block; + position: absolute; + left: -100000px; + width: 100%; + z-index: 1051; } + +.select2-results { + display: block; } + +.select2-results__options { + list-style: none; + margin: 0; + padding: 0; } + +.select2-results__option { + padding: 6px; + user-select: none; + -webkit-user-select: none; } + .select2-results__option[aria-selected] { + cursor: pointer; } + +.select2-container--open .select2-dropdown { + left: 0; } + +.select2-container--open .select2-dropdown--above { + border-bottom: none; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; } + +.select2-container--open .select2-dropdown--below { + border-top: none; + border-top-left-radius: 0; + border-top-right-radius: 0; } + +.select2-search--dropdown { + display: block; + padding: 4px; } + .select2-search--dropdown .select2-search__field { + padding: 4px; + width: 100%; + box-sizing: border-box; } + .select2-search--dropdown .select2-search__field::-webkit-search-cancel-button { + -webkit-appearance: none; } + .select2-search--dropdown.select2-search--hide { + display: none; } + +.select2-close-mask { + border: 0; + margin: 0; + padding: 0; + display: block; + position: fixed; + left: 0; + top: 0; + min-height: 100%; + min-width: 100%; + height: auto; + width: auto; + opacity: 0; + z-index: 99; + background-color: #fff; + filter: alpha(opacity=0); } + +.select2-hidden-accessible { + border: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(50%) !important; + clip-path: inset(50%) !important; + height: 1px !important; + overflow: hidden !important; + padding: 0 !important; + position: absolute !important; + width: 1px !important; + white-space: nowrap !important; } + +.select2-container--default .select2-selection--single { + background-color: #fff; + border: 1px solid #aaa; + border-radius: 4px; } + .select2-container--default .select2-selection--single .select2-selection__rendered { + color: #444; + line-height: 28px; } + .select2-container--default .select2-selection--single .select2-selection__clear { + cursor: pointer; + float: right; + font-weight: bold; } + .select2-container--default .select2-selection--single .select2-selection__placeholder { + color: #999; } + .select2-container--default .select2-selection--single .select2-selection__arrow { + height: 26px; + position: absolute; + top: 1px; + right: 1px; + width: 20px; } + .select2-container--default .select2-selection--single .select2-selection__arrow b { + border-color: #888 transparent transparent transparent; + border-style: solid; + border-width: 5px 4px 0 4px; + height: 0; + left: 50%; + margin-left: -4px; + margin-top: -2px; + position: absolute; + top: 50%; + width: 0; } + +.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear { + float: left; } + +.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow { + left: 1px; + right: auto; } + +.select2-container--default.select2-container--disabled .select2-selection--single { + background-color: #eee; + cursor: default; } + .select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear { + display: none; } + +.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b { + border-color: transparent transparent #888 transparent; + border-width: 0 4px 5px 4px; } + +.select2-container--default .select2-selection--multiple { + background-color: white; + border: 1px solid #aaa; + border-radius: 4px; + cursor: text; } + .select2-container--default .select2-selection--multiple .select2-selection__rendered { + box-sizing: border-box; + list-style: none; + margin: 0; + padding: 0 5px; + width: 100%; } + .select2-container--default .select2-selection--multiple .select2-selection__rendered li { + list-style: none; } + .select2-container--default .select2-selection--multiple .select2-selection__clear { + cursor: pointer; + float: right; + font-weight: bold; + margin-top: 5px; + margin-right: 10px; + padding: 1px; } + .select2-container--default .select2-selection--multiple .select2-selection__choice { + background-color: #e4e4e4; + border: 1px solid #aaa; + border-radius: 4px; + cursor: default; + float: left; + margin-right: 5px; + margin-top: 5px; + padding: 0 5px; } + .select2-container--default .select2-selection--multiple .select2-selection__choice__remove { + color: #999; + cursor: pointer; + display: inline-block; + font-weight: bold; + margin-right: 2px; } + .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover { + color: #333; } + +.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline { + float: right; } + +.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice { + margin-left: 5px; + margin-right: auto; } + +.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { + margin-left: 2px; + margin-right: auto; } + +.select2-container--default.select2-container--focus .select2-selection--multiple { + border: solid black 1px; + outline: 0; } + +.select2-container--default.select2-container--disabled .select2-selection--multiple { + background-color: #eee; + cursor: default; } + +.select2-container--default.select2-container--disabled .select2-selection__choice__remove { + display: none; } + +.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple { + border-top-left-radius: 0; + border-top-right-radius: 0; } + +.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; } + +.select2-container--default .select2-search--dropdown .select2-search__field { + border: 1px solid #aaa; } + +.select2-container--default .select2-search--inline .select2-search__field { + background: transparent; + border: none; + outline: 0; + box-shadow: none; + -webkit-appearance: textfield; } + +.select2-container--default .select2-results > .select2-results__options { + max-height: 200px; + overflow-y: auto; } + +.select2-container--default .select2-results__option[role=group] { + padding: 0; } + +.select2-container--default .select2-results__option[aria-disabled=true] { + color: #999; } + +.select2-container--default .select2-results__option[aria-selected=true] { + background-color: #ddd; } + +.select2-container--default .select2-results__option .select2-results__option { + padding-left: 1em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__group { + padding-left: 0; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option { + margin-left: -1em; + padding-left: 2em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -2em; + padding-left: 3em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -3em; + padding-left: 4em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -4em; + padding-left: 5em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -5em; + padding-left: 6em; } + +.select2-container--default .select2-results__option--highlighted[aria-selected] { + background-color: #5897fb; + color: white; } + +.select2-container--default .select2-results__group { + cursor: default; + display: block; + padding: 6px; } + +.select2-container--classic .select2-selection--single { + background-color: #f7f7f7; + border: 1px solid #aaa; + border-radius: 4px; + outline: 0; + background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%); + background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%); + background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } + .select2-container--classic .select2-selection--single:focus { + border: 1px solid #5897fb; } + .select2-container--classic .select2-selection--single .select2-selection__rendered { + color: #444; + line-height: 28px; } + .select2-container--classic .select2-selection--single .select2-selection__clear { + cursor: pointer; + float: right; + font-weight: bold; + margin-right: 10px; } + .select2-container--classic .select2-selection--single .select2-selection__placeholder { + color: #999; } + .select2-container--classic .select2-selection--single .select2-selection__arrow { + background-color: #ddd; + border: none; + border-left: 1px solid #aaa; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + height: 26px; + position: absolute; + top: 1px; + right: 1px; + width: 20px; + background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%); + background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%); + background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); } + .select2-container--classic .select2-selection--single .select2-selection__arrow b { + border-color: #888 transparent transparent transparent; + border-style: solid; + border-width: 5px 4px 0 4px; + height: 0; + left: 50%; + margin-left: -4px; + margin-top: -2px; + position: absolute; + top: 50%; + width: 0; } + +.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear { + float: left; } + +.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow { + border: none; + border-right: 1px solid #aaa; + border-radius: 0; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + left: 1px; + right: auto; } + +.select2-container--classic.select2-container--open .select2-selection--single { + border: 1px solid #5897fb; } + .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow { + background: transparent; + border: none; } + .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b { + border-color: transparent transparent #888 transparent; + border-width: 0 4px 5px 4px; } + +.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single { + border-top: none; + border-top-left-radius: 0; + border-top-right-radius: 0; + background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%); + background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%); + background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } + +.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single { + border-bottom: none; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%); + background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%); + background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); } + +.select2-container--classic .select2-selection--multiple { + background-color: white; + border: 1px solid #aaa; + border-radius: 4px; + cursor: text; + outline: 0; } + .select2-container--classic .select2-selection--multiple:focus { + border: 1px solid #5897fb; } + .select2-container--classic .select2-selection--multiple .select2-selection__rendered { + list-style: none; + margin: 0; + padding: 0 5px; } + .select2-container--classic .select2-selection--multiple .select2-selection__clear { + display: none; } + .select2-container--classic .select2-selection--multiple .select2-selection__choice { + background-color: #e4e4e4; + border: 1px solid #aaa; + border-radius: 4px; + cursor: default; + float: left; + margin-right: 5px; + margin-top: 5px; + padding: 0 5px; } + .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove { + color: #888; + cursor: pointer; + display: inline-block; + font-weight: bold; + margin-right: 2px; } + .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover { + color: #555; } + +.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice { + float: right; + margin-left: 5px; + margin-right: auto; } + +.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { + margin-left: 2px; + margin-right: auto; } + +.select2-container--classic.select2-container--open .select2-selection--multiple { + border: 1px solid #5897fb; } + +.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple { + border-top: none; + border-top-left-radius: 0; + border-top-right-radius: 0; } + +.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple { + border-bottom: none; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; } + +.select2-container--classic .select2-search--dropdown .select2-search__field { + border: 1px solid #aaa; + outline: 0; } + +.select2-container--classic .select2-search--inline .select2-search__field { + outline: 0; + box-shadow: none; } + +.select2-container--classic .select2-dropdown { + background-color: white; + border: 1px solid transparent; } + +.select2-container--classic .select2-dropdown--above { + border-bottom: none; } + +.select2-container--classic .select2-dropdown--below { + border-top: none; } + +.select2-container--classic .select2-results > .select2-results__options { + max-height: 200px; + overflow-y: auto; } + +.select2-container--classic .select2-results__option[role=group] { + padding: 0; } + +.select2-container--classic .select2-results__option[aria-disabled=true] { + color: grey; } + +.select2-container--classic .select2-results__option--highlighted[aria-selected] { + background-color: #3875d7; + color: white; } + +.select2-container--classic .select2-results__group { + cursor: default; + display: block; + padding: 6px; } + +.select2-container--classic.select2-container--open .select2-dropdown { + border-color: #5897fb; } diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/select2.js b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/select2.js new file mode 100755 index 00000000..fcfb5ab4 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/select2.js @@ -0,0 +1,6108 @@ +/*! + * Select2 4.0.13 + * https://select2.github.io + * + * Released under the MIT license + * https://github.com/select2/select2/blob/master/LICENSE.md + */ +;(function (factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else if (typeof module === 'object' && module.exports) { + // Node/CommonJS + module.exports = function (root, jQuery) { + if (jQuery === undefined) { + // require('jQuery') returns a factory that requires window to + // build a jQuery instance, we normalize how we use modules + // that require this pattern but the window provided is a noop + // if it's defined (how jquery works) + if (typeof window !== 'undefined') { + jQuery = require('jquery'); + } + else { + jQuery = require('jquery')(root); + } + } + factory(jQuery); + return jQuery; + }; + } else { + // Browser globals + factory(jQuery); + } +} (function (jQuery) { + // This is needed so we can catch the AMD loader configuration and use it + // The inner file should be wrapped (by `banner.start.js`) in a function that + // returns the AMD loader references. + var S2 =(function () { + // Restore the Select2 AMD loader so it can be used + // Needed mostly in the language files, where the loader is not inserted + if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) { + var S2 = jQuery.fn.select2.amd; + } +var S2;(function () { if (!S2 || !S2.requirejs) { +if (!S2) { S2 = {}; } else { require = S2; } +/** + * @license almond 0.3.3 Copyright jQuery Foundation and other contributors. + * Released under MIT license, http://github.com/requirejs/almond/LICENSE + */ +//Going sloppy to avoid 'use strict' string cost, but strict practices should +//be followed. +/*global setTimeout: false */ + +var requirejs, require, define; +(function (undef) { + var main, req, makeMap, handlers, + defined = {}, + waiting = {}, + config = {}, + defining = {}, + hasOwn = Object.prototype.hasOwnProperty, + aps = [].slice, + jsSuffixRegExp = /\.js$/; + + function hasProp(obj, prop) { + return hasOwn.call(obj, prop); + } + + /** + * Given a relative module name, like ./something, normalize it to + * a real name that can be mapped to a path. + * @param {String} name the relative name + * @param {String} baseName a real name that the name arg is relative + * to. + * @returns {String} normalized name + */ + function normalize(name, baseName) { + var nameParts, nameSegment, mapValue, foundMap, lastIndex, + foundI, foundStarMap, starI, i, j, part, normalizedBaseParts, + baseParts = baseName && baseName.split("/"), + map = config.map, + starMap = (map && map['*']) || {}; + + //Adjust any relative paths. + if (name) { + name = name.split('/'); + lastIndex = name.length - 1; + + // If wanting node ID compatibility, strip .js from end + // of IDs. Have to do this here, and not in nameToUrl + // because node allows either .js or non .js to map + // to same file. + if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) { + name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, ''); + } + + // Starts with a '.' so need the baseName + if (name[0].charAt(0) === '.' && baseParts) { + //Convert baseName to array, and lop off the last part, + //so that . matches that 'directory' and not name of the baseName's + //module. For instance, baseName of 'one/two/three', maps to + //'one/two/three.js', but we want the directory, 'one/two' for + //this normalization. + normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); + name = normalizedBaseParts.concat(name); + } + + //start trimDots + for (i = 0; i < name.length; i++) { + part = name[i]; + if (part === '.') { + name.splice(i, 1); + i -= 1; + } else if (part === '..') { + // If at the start, or previous value is still .., + // keep them so that when converted to a path it may + // still work when converted to a path, even though + // as an ID it is less than ideal. In larger point + // releases, may be better to just kick out an error. + if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') { + continue; + } else if (i > 0) { + name.splice(i - 1, 2); + i -= 2; + } + } + } + //end trimDots + + name = name.join('/'); + } + + //Apply map config if available. + if ((baseParts || starMap) && map) { + nameParts = name.split('/'); + + for (i = nameParts.length; i > 0; i -= 1) { + nameSegment = nameParts.slice(0, i).join("/"); + + if (baseParts) { + //Find the longest baseName segment match in the config. + //So, do joins on the biggest to smallest lengths of baseParts. + for (j = baseParts.length; j > 0; j -= 1) { + mapValue = map[baseParts.slice(0, j).join('/')]; + + //baseName segment has config, find if it has one for + //this name. + if (mapValue) { + mapValue = mapValue[nameSegment]; + if (mapValue) { + //Match, update name to the new value. + foundMap = mapValue; + foundI = i; + break; + } + } + } + } + + if (foundMap) { + break; + } + + //Check for a star map match, but just hold on to it, + //if there is a shorter segment match later in a matching + //config, then favor over this star map. + if (!foundStarMap && starMap && starMap[nameSegment]) { + foundStarMap = starMap[nameSegment]; + starI = i; + } + } + + if (!foundMap && foundStarMap) { + foundMap = foundStarMap; + foundI = starI; + } + + if (foundMap) { + nameParts.splice(0, foundI, foundMap); + name = nameParts.join('/'); + } + } + + return name; + } + + function makeRequire(relName, forceSync) { + return function () { + //A version of a require function that passes a moduleName + //value for items that may need to + //look up paths relative to the moduleName + var args = aps.call(arguments, 0); + + //If first arg is not require('string'), and there is only + //one arg, it is the array form without a callback. Insert + //a null so that the following concat is correct. + if (typeof args[0] !== 'string' && args.length === 1) { + args.push(null); + } + return req.apply(undef, args.concat([relName, forceSync])); + }; + } + + function makeNormalize(relName) { + return function (name) { + return normalize(name, relName); + }; + } + + function makeLoad(depName) { + return function (value) { + defined[depName] = value; + }; + } + + function callDep(name) { + if (hasProp(waiting, name)) { + var args = waiting[name]; + delete waiting[name]; + defining[name] = true; + main.apply(undef, args); + } + + if (!hasProp(defined, name) && !hasProp(defining, name)) { + throw new Error('No ' + name); + } + return defined[name]; + } + + //Turns a plugin!resource to [plugin, resource] + //with the plugin being undefined if the name + //did not have a plugin prefix. + function splitPrefix(name) { + var prefix, + index = name ? name.indexOf('!') : -1; + if (index > -1) { + prefix = name.substring(0, index); + name = name.substring(index + 1, name.length); + } + return [prefix, name]; + } + + //Creates a parts array for a relName where first part is plugin ID, + //second part is resource ID. Assumes relName has already been normalized. + function makeRelParts(relName) { + return relName ? splitPrefix(relName) : []; + } + + /** + * Makes a name map, normalizing the name, and using a plugin + * for normalization if necessary. Grabs a ref to plugin + * too, as an optimization. + */ + makeMap = function (name, relParts) { + var plugin, + parts = splitPrefix(name), + prefix = parts[0], + relResourceName = relParts[1]; + + name = parts[1]; + + if (prefix) { + prefix = normalize(prefix, relResourceName); + plugin = callDep(prefix); + } + + //Normalize according + if (prefix) { + if (plugin && plugin.normalize) { + name = plugin.normalize(name, makeNormalize(relResourceName)); + } else { + name = normalize(name, relResourceName); + } + } else { + name = normalize(name, relResourceName); + parts = splitPrefix(name); + prefix = parts[0]; + name = parts[1]; + if (prefix) { + plugin = callDep(prefix); + } + } + + //Using ridiculous property names for space reasons + return { + f: prefix ? prefix + '!' + name : name, //fullName + n: name, + pr: prefix, + p: plugin + }; + }; + + function makeConfig(name) { + return function () { + return (config && config.config && config.config[name]) || {}; + }; + } + + handlers = { + require: function (name) { + return makeRequire(name); + }, + exports: function (name) { + var e = defined[name]; + if (typeof e !== 'undefined') { + return e; + } else { + return (defined[name] = {}); + } + }, + module: function (name) { + return { + id: name, + uri: '', + exports: defined[name], + config: makeConfig(name) + }; + } + }; + + main = function (name, deps, callback, relName) { + var cjsModule, depName, ret, map, i, relParts, + args = [], + callbackType = typeof callback, + usingExports; + + //Use name if no relName + relName = relName || name; + relParts = makeRelParts(relName); + + //Call the callback to define the module, if necessary. + if (callbackType === 'undefined' || callbackType === 'function') { + //Pull out the defined dependencies and pass the ordered + //values to the callback. + //Default to [require, exports, module] if no deps + deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps; + for (i = 0; i < deps.length; i += 1) { + map = makeMap(deps[i], relParts); + depName = map.f; + + //Fast path CommonJS standard dependencies. + if (depName === "require") { + args[i] = handlers.require(name); + } else if (depName === "exports") { + //CommonJS module spec 1.1 + args[i] = handlers.exports(name); + usingExports = true; + } else if (depName === "module") { + //CommonJS module spec 1.1 + cjsModule = args[i] = handlers.module(name); + } else if (hasProp(defined, depName) || + hasProp(waiting, depName) || + hasProp(defining, depName)) { + args[i] = callDep(depName); + } else if (map.p) { + map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {}); + args[i] = defined[depName]; + } else { + throw new Error(name + ' missing ' + depName); + } + } + + ret = callback ? callback.apply(defined[name], args) : undefined; + + if (name) { + //If setting exports via "module" is in play, + //favor that over return value and exports. After that, + //favor a non-undefined return value over exports use. + if (cjsModule && cjsModule.exports !== undef && + cjsModule.exports !== defined[name]) { + defined[name] = cjsModule.exports; + } else if (ret !== undef || !usingExports) { + //Use the return value from the function. + defined[name] = ret; + } + } + } else if (name) { + //May just be an object definition for the module. Only + //worry about defining if have a module name. + defined[name] = callback; + } + }; + + requirejs = require = req = function (deps, callback, relName, forceSync, alt) { + if (typeof deps === "string") { + if (handlers[deps]) { + //callback in this case is really relName + return handlers[deps](callback); + } + //Just return the module wanted. In this scenario, the + //deps arg is the module name, and second arg (if passed) + //is just the relName. + //Normalize module name, if it contains . or .. + return callDep(makeMap(deps, makeRelParts(callback)).f); + } else if (!deps.splice) { + //deps is a config object, not an array. + config = deps; + if (config.deps) { + req(config.deps, config.callback); + } + if (!callback) { + return; + } + + if (callback.splice) { + //callback is an array, which means it is a dependency list. + //Adjust args if there are dependencies + deps = callback; + callback = relName; + relName = null; + } else { + deps = undef; + } + } + + //Support require(['a']) + callback = callback || function () {}; + + //If relName is a function, it is an errback handler, + //so remove it. + if (typeof relName === 'function') { + relName = forceSync; + forceSync = alt; + } + + //Simulate async callback; + if (forceSync) { + main(undef, deps, callback, relName); + } else { + //Using a non-zero value because of concern for what old browsers + //do, and latest browsers "upgrade" to 4 if lower value is used: + //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout: + //If want a value immediately, use require('id') instead -- something + //that works in almond on the global level, but not guaranteed and + //unlikely to work in other AMD implementations. + setTimeout(function () { + main(undef, deps, callback, relName); + }, 4); + } + + return req; + }; + + /** + * Just drops the config on the floor, but returns req in case + * the config return value is used. + */ + req.config = function (cfg) { + return req(cfg); + }; + + /** + * Expose module registry for debugging and tooling + */ + requirejs._defined = defined; + + define = function (name, deps, callback) { + if (typeof name !== 'string') { + throw new Error('See almond README: incorrect module build, no module name'); + } + + //This module may not have dependencies + if (!deps.splice) { + //deps is not an array, so probably means + //an object literal or factory function for + //the value. Adjust args. + callback = deps; + deps = []; + } + + if (!hasProp(defined, name) && !hasProp(waiting, name)) { + waiting[name] = [name, deps, callback]; + } + }; + + define.amd = { + jQuery: true + }; +}()); + +S2.requirejs = requirejs;S2.require = require;S2.define = define; +} +}()); +S2.define("almond", function(){}); + +/* global jQuery:false, $:false */ +S2.define('jquery',[],function () { + var _$ = jQuery || $; + + if (_$ == null && console && console.error) { + console.error( + 'Select2: An instance of jQuery or a jQuery-compatible library was not ' + + 'found. Make sure that you are including jQuery before Select2 on your ' + + 'web page.' + ); + } + + return _$; +}); + +S2.define('select2/utils',[ + 'jquery' +], function ($) { + var Utils = {}; + + Utils.Extend = function (ChildClass, SuperClass) { + var __hasProp = {}.hasOwnProperty; + + function BaseConstructor () { + this.constructor = ChildClass; + } + + for (var key in SuperClass) { + if (__hasProp.call(SuperClass, key)) { + ChildClass[key] = SuperClass[key]; + } + } + + BaseConstructor.prototype = SuperClass.prototype; + ChildClass.prototype = new BaseConstructor(); + ChildClass.__super__ = SuperClass.prototype; + + return ChildClass; + }; + + function getMethods (theClass) { + var proto = theClass.prototype; + + var methods = []; + + for (var methodName in proto) { + var m = proto[methodName]; + + if (typeof m !== 'function') { + continue; + } + + if (methodName === 'constructor') { + continue; + } + + methods.push(methodName); + } + + return methods; + } + + Utils.Decorate = function (SuperClass, DecoratorClass) { + var decoratedMethods = getMethods(DecoratorClass); + var superMethods = getMethods(SuperClass); + + function DecoratedClass () { + var unshift = Array.prototype.unshift; + + var argCount = DecoratorClass.prototype.constructor.length; + + var calledConstructor = SuperClass.prototype.constructor; + + if (argCount > 0) { + unshift.call(arguments, SuperClass.prototype.constructor); + + calledConstructor = DecoratorClass.prototype.constructor; + } + + calledConstructor.apply(this, arguments); + } + + DecoratorClass.displayName = SuperClass.displayName; + + function ctr () { + this.constructor = DecoratedClass; + } + + DecoratedClass.prototype = new ctr(); + + for (var m = 0; m < superMethods.length; m++) { + var superMethod = superMethods[m]; + + DecoratedClass.prototype[superMethod] = + SuperClass.prototype[superMethod]; + } + + var calledMethod = function (methodName) { + // Stub out the original method if it's not decorating an actual method + var originalMethod = function () {}; + + if (methodName in DecoratedClass.prototype) { + originalMethod = DecoratedClass.prototype[methodName]; + } + + var decoratedMethod = DecoratorClass.prototype[methodName]; + + return function () { + var unshift = Array.prototype.unshift; + + unshift.call(arguments, originalMethod); + + return decoratedMethod.apply(this, arguments); + }; + }; + + for (var d = 0; d < decoratedMethods.length; d++) { + var decoratedMethod = decoratedMethods[d]; + + DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod); + } + + return DecoratedClass; + }; + + var Observable = function () { + this.listeners = {}; + }; + + Observable.prototype.on = function (event, callback) { + this.listeners = this.listeners || {}; + + if (event in this.listeners) { + this.listeners[event].push(callback); + } else { + this.listeners[event] = [callback]; + } + }; + + Observable.prototype.trigger = function (event) { + var slice = Array.prototype.slice; + var params = slice.call(arguments, 1); + + this.listeners = this.listeners || {}; + + // Params should always come in as an array + if (params == null) { + params = []; + } + + // If there are no arguments to the event, use a temporary object + if (params.length === 0) { + params.push({}); + } + + // Set the `_type` of the first object to the event + params[0]._type = event; + + if (event in this.listeners) { + this.invoke(this.listeners[event], slice.call(arguments, 1)); + } + + if ('*' in this.listeners) { + this.invoke(this.listeners['*'], arguments); + } + }; + + Observable.prototype.invoke = function (listeners, params) { + for (var i = 0, len = listeners.length; i < len; i++) { + listeners[i].apply(this, params); + } + }; + + Utils.Observable = Observable; + + Utils.generateChars = function (length) { + var chars = ''; + + for (var i = 0; i < length; i++) { + var randomChar = Math.floor(Math.random() * 36); + chars += randomChar.toString(36); + } + + return chars; + }; + + Utils.bind = function (func, context) { + return function () { + func.apply(context, arguments); + }; + }; + + Utils._convertData = function (data) { + for (var originalKey in data) { + var keys = originalKey.split('-'); + + var dataLevel = data; + + if (keys.length === 1) { + continue; + } + + for (var k = 0; k < keys.length; k++) { + var key = keys[k]; + + // Lowercase the first letter + // By default, dash-separated becomes camelCase + key = key.substring(0, 1).toLowerCase() + key.substring(1); + + if (!(key in dataLevel)) { + dataLevel[key] = {}; + } + + if (k == keys.length - 1) { + dataLevel[key] = data[originalKey]; + } + + dataLevel = dataLevel[key]; + } + + delete data[originalKey]; + } + + return data; + }; + + Utils.hasScroll = function (index, el) { + // Adapted from the function created by @ShadowScripter + // and adapted by @BillBarry on the Stack Exchange Code Review website. + // The original code can be found at + // http://codereview.stackexchange.com/q/13338 + // and was designed to be used with the Sizzle selector engine. + + var $el = $(el); + var overflowX = el.style.overflowX; + var overflowY = el.style.overflowY; + + //Check both x and y declarations + if (overflowX === overflowY && + (overflowY === 'hidden' || overflowY === 'visible')) { + return false; + } + + if (overflowX === 'scroll' || overflowY === 'scroll') { + return true; + } + + return ($el.innerHeight() < el.scrollHeight || + $el.innerWidth() < el.scrollWidth); + }; + + Utils.escapeMarkup = function (markup) { + var replaceMap = { + '\\': '\', + '&': '&', + '<': '<', + '>': '>', + '"': '"', + '\'': ''', + '/': '/' + }; + + // Do not try to escape the markup if it's not a string + if (typeof markup !== 'string') { + return markup; + } + + return String(markup).replace(/[&<>"'\/\\]/g, function (match) { + return replaceMap[match]; + }); + }; + + // Append an array of jQuery nodes to a given element. + Utils.appendMany = function ($element, $nodes) { + // jQuery 1.7.x does not support $.fn.append() with an array + // Fall back to a jQuery object collection using $.fn.add() + if ($.fn.jquery.substr(0, 3) === '1.7') { + var $jqNodes = $(); + + $.map($nodes, function (node) { + $jqNodes = $jqNodes.add(node); + }); + + $nodes = $jqNodes; + } + + $element.append($nodes); + }; + + // Cache objects in Utils.__cache instead of $.data (see #4346) + Utils.__cache = {}; + + var id = 0; + Utils.GetUniqueElementId = function (element) { + // Get a unique element Id. If element has no id, + // creates a new unique number, stores it in the id + // attribute and returns the new id. + // If an id already exists, it simply returns it. + + var select2Id = element.getAttribute('data-select2-id'); + if (select2Id == null) { + // If element has id, use it. + if (element.id) { + select2Id = element.id; + element.setAttribute('data-select2-id', select2Id); + } else { + element.setAttribute('data-select2-id', ++id); + select2Id = id.toString(); + } + } + return select2Id; + }; + + Utils.StoreData = function (element, name, value) { + // Stores an item in the cache for a specified element. + // name is the cache key. + var id = Utils.GetUniqueElementId(element); + if (!Utils.__cache[id]) { + Utils.__cache[id] = {}; + } + + Utils.__cache[id][name] = value; + }; + + Utils.GetData = function (element, name) { + // Retrieves a value from the cache by its key (name) + // name is optional. If no name specified, return + // all cache items for the specified element. + // and for a specified element. + var id = Utils.GetUniqueElementId(element); + if (name) { + if (Utils.__cache[id]) { + if (Utils.__cache[id][name] != null) { + return Utils.__cache[id][name]; + } + return $(element).data(name); // Fallback to HTML5 data attribs. + } + return $(element).data(name); // Fallback to HTML5 data attribs. + } else { + return Utils.__cache[id]; + } + }; + + Utils.RemoveData = function (element) { + // Removes all cached items for a specified element. + var id = Utils.GetUniqueElementId(element); + if (Utils.__cache[id] != null) { + delete Utils.__cache[id]; + } + + element.removeAttribute('data-select2-id'); + }; + + return Utils; +}); + +S2.define('select2/results',[ + 'jquery', + './utils' +], function ($, Utils) { + function Results ($element, options, dataAdapter) { + this.$element = $element; + this.data = dataAdapter; + this.options = options; + + Results.__super__.constructor.call(this); + } + + Utils.Extend(Results, Utils.Observable); + + Results.prototype.render = function () { + var $results = $( + '
    ' + ); + + if (this.options.get('multiple')) { + $results.attr('aria-multiselectable', 'true'); + } + + this.$results = $results; + + return $results; + }; + + Results.prototype.clear = function () { + this.$results.empty(); + }; + + Results.prototype.displayMessage = function (params) { + var escapeMarkup = this.options.get('escapeMarkup'); + + this.clear(); + this.hideLoading(); + + var $message = $( + '' + ); + + var message = this.options.get('translations').get(params.message); + + $message.append( + escapeMarkup( + message(params.args) + ) + ); + + $message[0].className += ' select2-results__message'; + + this.$results.append($message); + }; + + Results.prototype.hideMessages = function () { + this.$results.find('.select2-results__message').remove(); + }; + + Results.prototype.append = function (data) { + this.hideLoading(); + + var $options = []; + + if (data.results == null || data.results.length === 0) { + if (this.$results.children().length === 0) { + this.trigger('results:message', { + message: 'noResults' + }); + } + + return; + } + + data.results = this.sort(data.results); + + for (var d = 0; d < data.results.length; d++) { + var item = data.results[d]; + + var $option = this.option(item); + + $options.push($option); + } + + this.$results.append($options); + }; + + Results.prototype.position = function ($results, $dropdown) { + var $resultsContainer = $dropdown.find('.select2-results'); + $resultsContainer.append($results); + }; + + Results.prototype.sort = function (data) { + var sorter = this.options.get('sorter'); + + return sorter(data); + }; + + Results.prototype.highlightFirstItem = function () { + var $options = this.$results + .find('.select2-results__option[aria-selected]'); + + var $selected = $options.filter('[aria-selected=true]'); + + // Check if there are any selected options + if ($selected.length > 0) { + // If there are selected options, highlight the first + $selected.first().trigger('mouseenter'); + } else { + // If there are no selected options, highlight the first option + // in the dropdown + $options.first().trigger('mouseenter'); + } + + this.ensureHighlightVisible(); + }; + + Results.prototype.setClasses = function () { + var self = this; + + this.data.current(function (selected) { + var selectedIds = $.map(selected, function (s) { + return s.id.toString(); + }); + + var $options = self.$results + .find('.select2-results__option[aria-selected]'); + + $options.each(function () { + var $option = $(this); + + var item = Utils.GetData(this, 'data'); + + // id needs to be converted to a string when comparing + var id = '' + item.id; + + if ((item.element != null && item.element.selected) || + (item.element == null && $.inArray(id, selectedIds) > -1)) { + $option.attr('aria-selected', 'true'); + } else { + $option.attr('aria-selected', 'false'); + } + }); + + }); + }; + + Results.prototype.showLoading = function (params) { + this.hideLoading(); + + var loadingMore = this.options.get('translations').get('searching'); + + var loading = { + disabled: true, + loading: true, + text: loadingMore(params) + }; + var $loading = this.option(loading); + $loading.className += ' loading-results'; + + this.$results.prepend($loading); + }; + + Results.prototype.hideLoading = function () { + this.$results.find('.loading-results').remove(); + }; + + Results.prototype.option = function (data) { + var option = document.createElement('li'); + option.className = 'select2-results__option'; + + var attrs = { + 'role': 'option', + 'aria-selected': 'false' + }; + + var matches = window.Element.prototype.matches || + window.Element.prototype.msMatchesSelector || + window.Element.prototype.webkitMatchesSelector; + + if ((data.element != null && matches.call(data.element, ':disabled')) || + (data.element == null && data.disabled)) { + delete attrs['aria-selected']; + attrs['aria-disabled'] = 'true'; + } + + if (data.id == null) { + delete attrs['aria-selected']; + } + + if (data._resultId != null) { + option.id = data._resultId; + } + + if (data.title) { + option.title = data.title; + } + + if (data.children) { + attrs.role = 'group'; + attrs['aria-label'] = data.text; + delete attrs['aria-selected']; + } + + for (var attr in attrs) { + var val = attrs[attr]; + + option.setAttribute(attr, val); + } + + if (data.children) { + var $option = $(option); + + var label = document.createElement('strong'); + label.className = 'select2-results__group'; + + var $label = $(label); + this.template(data, label); + + var $children = []; + + for (var c = 0; c < data.children.length; c++) { + var child = data.children[c]; + + var $child = this.option(child); + + $children.push($child); + } + + var $childrenContainer = $('
      ', { + 'class': 'select2-results__options select2-results__options--nested' + }); + + $childrenContainer.append($children); + + $option.append(label); + $option.append($childrenContainer); + } else { + this.template(data, option); + } + + Utils.StoreData(option, 'data', data); + + return option; + }; + + Results.prototype.bind = function (container, $container) { + var self = this; + + var id = container.id + '-results'; + + this.$results.attr('id', id); + + container.on('results:all', function (params) { + self.clear(); + self.append(params.data); + + if (container.isOpen()) { + self.setClasses(); + self.highlightFirstItem(); + } + }); + + container.on('results:append', function (params) { + self.append(params.data); + + if (container.isOpen()) { + self.setClasses(); + } + }); + + container.on('query', function (params) { + self.hideMessages(); + self.showLoading(params); + }); + + container.on('select', function () { + if (!container.isOpen()) { + return; + } + + self.setClasses(); + + if (self.options.get('scrollAfterSelect')) { + self.highlightFirstItem(); + } + }); + + container.on('unselect', function () { + if (!container.isOpen()) { + return; + } + + self.setClasses(); + + if (self.options.get('scrollAfterSelect')) { + self.highlightFirstItem(); + } + }); + + container.on('open', function () { + // When the dropdown is open, aria-expended="true" + self.$results.attr('aria-expanded', 'true'); + self.$results.attr('aria-hidden', 'false'); + + self.setClasses(); + self.ensureHighlightVisible(); + }); + + container.on('close', function () { + // When the dropdown is closed, aria-expended="false" + self.$results.attr('aria-expanded', 'false'); + self.$results.attr('aria-hidden', 'true'); + self.$results.removeAttr('aria-activedescendant'); + }); + + container.on('results:toggle', function () { + var $highlighted = self.getHighlightedResults(); + + if ($highlighted.length === 0) { + return; + } + + $highlighted.trigger('mouseup'); + }); + + container.on('results:select', function () { + var $highlighted = self.getHighlightedResults(); + + if ($highlighted.length === 0) { + return; + } + + var data = Utils.GetData($highlighted[0], 'data'); + + if ($highlighted.attr('aria-selected') == 'true') { + self.trigger('close', {}); + } else { + self.trigger('select', { + data: data + }); + } + }); + + container.on('results:previous', function () { + var $highlighted = self.getHighlightedResults(); + + var $options = self.$results.find('[aria-selected]'); + + var currentIndex = $options.index($highlighted); + + // If we are already at the top, don't move further + // If no options, currentIndex will be -1 + if (currentIndex <= 0) { + return; + } + + var nextIndex = currentIndex - 1; + + // If none are highlighted, highlight the first + if ($highlighted.length === 0) { + nextIndex = 0; + } + + var $next = $options.eq(nextIndex); + + $next.trigger('mouseenter'); + + var currentOffset = self.$results.offset().top; + var nextTop = $next.offset().top; + var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset); + + if (nextIndex === 0) { + self.$results.scrollTop(0); + } else if (nextTop - currentOffset < 0) { + self.$results.scrollTop(nextOffset); + } + }); + + container.on('results:next', function () { + var $highlighted = self.getHighlightedResults(); + + var $options = self.$results.find('[aria-selected]'); + + var currentIndex = $options.index($highlighted); + + var nextIndex = currentIndex + 1; + + // If we are at the last option, stay there + if (nextIndex >= $options.length) { + return; + } + + var $next = $options.eq(nextIndex); + + $next.trigger('mouseenter'); + + var currentOffset = self.$results.offset().top + + self.$results.outerHeight(false); + var nextBottom = $next.offset().top + $next.outerHeight(false); + var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset; + + if (nextIndex === 0) { + self.$results.scrollTop(0); + } else if (nextBottom > currentOffset) { + self.$results.scrollTop(nextOffset); + } + }); + + container.on('results:focus', function (params) { + params.element.addClass('select2-results__option--highlighted'); + }); + + container.on('results:message', function (params) { + self.displayMessage(params); + }); + + if ($.fn.mousewheel) { + this.$results.on('mousewheel', function (e) { + var top = self.$results.scrollTop(); + + var bottom = self.$results.get(0).scrollHeight - top + e.deltaY; + + var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0; + var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height(); + + if (isAtTop) { + self.$results.scrollTop(0); + + e.preventDefault(); + e.stopPropagation(); + } else if (isAtBottom) { + self.$results.scrollTop( + self.$results.get(0).scrollHeight - self.$results.height() + ); + + e.preventDefault(); + e.stopPropagation(); + } + }); + } + + this.$results.on('mouseup', '.select2-results__option[aria-selected]', + function (evt) { + var $this = $(this); + + var data = Utils.GetData(this, 'data'); + + if ($this.attr('aria-selected') === 'true') { + if (self.options.get('multiple')) { + self.trigger('unselect', { + originalEvent: evt, + data: data + }); + } else { + self.trigger('close', {}); + } + + return; + } + + self.trigger('select', { + originalEvent: evt, + data: data + }); + }); + + this.$results.on('mouseenter', '.select2-results__option[aria-selected]', + function (evt) { + var data = Utils.GetData(this, 'data'); + + self.getHighlightedResults() + .removeClass('select2-results__option--highlighted'); + + self.trigger('results:focus', { + data: data, + element: $(this) + }); + }); + }; + + Results.prototype.getHighlightedResults = function () { + var $highlighted = this.$results + .find('.select2-results__option--highlighted'); + + return $highlighted; + }; + + Results.prototype.destroy = function () { + this.$results.remove(); + }; + + Results.prototype.ensureHighlightVisible = function () { + var $highlighted = this.getHighlightedResults(); + + if ($highlighted.length === 0) { + return; + } + + var $options = this.$results.find('[aria-selected]'); + + var currentIndex = $options.index($highlighted); + + var currentOffset = this.$results.offset().top; + var nextTop = $highlighted.offset().top; + var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset); + + var offsetDelta = nextTop - currentOffset; + nextOffset -= $highlighted.outerHeight(false) * 2; + + if (currentIndex <= 2) { + this.$results.scrollTop(0); + } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) { + this.$results.scrollTop(nextOffset); + } + }; + + Results.prototype.template = function (result, container) { + var template = this.options.get('templateResult'); + var escapeMarkup = this.options.get('escapeMarkup'); + + var content = template(result, container); + + if (content == null) { + container.style.display = 'none'; + } else if (typeof content === 'string') { + container.innerHTML = escapeMarkup(content); + } else { + $(container).append(content); + } + }; + + return Results; +}); + +S2.define('select2/keys',[ + +], function () { + var KEYS = { + BACKSPACE: 8, + TAB: 9, + ENTER: 13, + SHIFT: 16, + CTRL: 17, + ALT: 18, + ESC: 27, + SPACE: 32, + PAGE_UP: 33, + PAGE_DOWN: 34, + END: 35, + HOME: 36, + LEFT: 37, + UP: 38, + RIGHT: 39, + DOWN: 40, + DELETE: 46 + }; + + return KEYS; +}); + +S2.define('select2/selection/base',[ + 'jquery', + '../utils', + '../keys' +], function ($, Utils, KEYS) { + function BaseSelection ($element, options) { + this.$element = $element; + this.options = options; + + BaseSelection.__super__.constructor.call(this); + } + + Utils.Extend(BaseSelection, Utils.Observable); + + BaseSelection.prototype.render = function () { + var $selection = $( + '' + ); + + this._tabindex = 0; + + if (Utils.GetData(this.$element[0], 'old-tabindex') != null) { + this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex'); + } else if (this.$element.attr('tabindex') != null) { + this._tabindex = this.$element.attr('tabindex'); + } + + $selection.attr('title', this.$element.attr('title')); + $selection.attr('tabindex', this._tabindex); + $selection.attr('aria-disabled', 'false'); + + this.$selection = $selection; + + return $selection; + }; + + BaseSelection.prototype.bind = function (container, $container) { + var self = this; + + var resultsId = container.id + '-results'; + + this.container = container; + + this.$selection.on('focus', function (evt) { + self.trigger('focus', evt); + }); + + this.$selection.on('blur', function (evt) { + self._handleBlur(evt); + }); + + this.$selection.on('keydown', function (evt) { + self.trigger('keypress', evt); + + if (evt.which === KEYS.SPACE) { + evt.preventDefault(); + } + }); + + container.on('results:focus', function (params) { + self.$selection.attr('aria-activedescendant', params.data._resultId); + }); + + container.on('selection:update', function (params) { + self.update(params.data); + }); + + container.on('open', function () { + // When the dropdown is open, aria-expanded="true" + self.$selection.attr('aria-expanded', 'true'); + self.$selection.attr('aria-owns', resultsId); + + self._attachCloseHandler(container); + }); + + container.on('close', function () { + // When the dropdown is closed, aria-expanded="false" + self.$selection.attr('aria-expanded', 'false'); + self.$selection.removeAttr('aria-activedescendant'); + self.$selection.removeAttr('aria-owns'); + + self.$selection.trigger('focus'); + + self._detachCloseHandler(container); + }); + + container.on('enable', function () { + self.$selection.attr('tabindex', self._tabindex); + self.$selection.attr('aria-disabled', 'false'); + }); + + container.on('disable', function () { + self.$selection.attr('tabindex', '-1'); + self.$selection.attr('aria-disabled', 'true'); + }); + }; + + BaseSelection.prototype._handleBlur = function (evt) { + var self = this; + + // This needs to be delayed as the active element is the body when the tab + // key is pressed, possibly along with others. + window.setTimeout(function () { + // Don't trigger `blur` if the focus is still in the selection + if ( + (document.activeElement == self.$selection[0]) || + ($.contains(self.$selection[0], document.activeElement)) + ) { + return; + } + + self.trigger('blur', evt); + }, 1); + }; + + BaseSelection.prototype._attachCloseHandler = function (container) { + + $(document.body).on('mousedown.select2.' + container.id, function (e) { + var $target = $(e.target); + + var $select = $target.closest('.select2'); + + var $all = $('.select2.select2-container--open'); + + $all.each(function () { + if (this == $select[0]) { + return; + } + + var $element = Utils.GetData(this, 'element'); + + $element.select2('close'); + }); + }); + }; + + BaseSelection.prototype._detachCloseHandler = function (container) { + $(document.body).off('mousedown.select2.' + container.id); + }; + + BaseSelection.prototype.position = function ($selection, $container) { + var $selectionContainer = $container.find('.selection'); + $selectionContainer.append($selection); + }; + + BaseSelection.prototype.destroy = function () { + this._detachCloseHandler(this.container); + }; + + BaseSelection.prototype.update = function (data) { + throw new Error('The `update` method must be defined in child classes.'); + }; + + /** + * Helper method to abstract the "enabled" (not "disabled") state of this + * object. + * + * @return {true} if the instance is not disabled. + * @return {false} if the instance is disabled. + */ + BaseSelection.prototype.isEnabled = function () { + return !this.isDisabled(); + }; + + /** + * Helper method to abstract the "disabled" state of this object. + * + * @return {true} if the disabled option is true. + * @return {false} if the disabled option is false. + */ + BaseSelection.prototype.isDisabled = function () { + return this.options.get('disabled'); + }; + + return BaseSelection; +}); + +S2.define('select2/selection/single',[ + 'jquery', + './base', + '../utils', + '../keys' +], function ($, BaseSelection, Utils, KEYS) { + function SingleSelection () { + SingleSelection.__super__.constructor.apply(this, arguments); + } + + Utils.Extend(SingleSelection, BaseSelection); + + SingleSelection.prototype.render = function () { + var $selection = SingleSelection.__super__.render.call(this); + + $selection.addClass('select2-selection--single'); + + $selection.html( + '' + + '' + + '' + + '' + ); + + return $selection; + }; + + SingleSelection.prototype.bind = function (container, $container) { + var self = this; + + SingleSelection.__super__.bind.apply(this, arguments); + + var id = container.id + '-container'; + + this.$selection.find('.select2-selection__rendered') + .attr('id', id) + .attr('role', 'textbox') + .attr('aria-readonly', 'true'); + this.$selection.attr('aria-labelledby', id); + + this.$selection.on('mousedown', function (evt) { + // Only respond to left clicks + if (evt.which !== 1) { + return; + } + + self.trigger('toggle', { + originalEvent: evt + }); + }); + + this.$selection.on('focus', function (evt) { + // User focuses on the container + }); + + this.$selection.on('blur', function (evt) { + // User exits the container + }); + + container.on('focus', function (evt) { + if (!container.isOpen()) { + self.$selection.trigger('focus'); + } + }); + }; + + SingleSelection.prototype.clear = function () { + var $rendered = this.$selection.find('.select2-selection__rendered'); + $rendered.empty(); + $rendered.removeAttr('title'); // clear tooltip on empty + }; + + SingleSelection.prototype.display = function (data, container) { + var template = this.options.get('templateSelection'); + var escapeMarkup = this.options.get('escapeMarkup'); + + return escapeMarkup(template(data, container)); + }; + + SingleSelection.prototype.selectionContainer = function () { + return $(''); + }; + + SingleSelection.prototype.update = function (data) { + if (data.length === 0) { + this.clear(); + return; + } + + var selection = data[0]; + + var $rendered = this.$selection.find('.select2-selection__rendered'); + var formatted = this.display(selection, $rendered); + + $rendered.empty().append(formatted); + + var title = selection.title || selection.text; + + if (title) { + $rendered.attr('title', title); + } else { + $rendered.removeAttr('title'); + } + }; + + return SingleSelection; +}); + +S2.define('select2/selection/multiple',[ + 'jquery', + './base', + '../utils' +], function ($, BaseSelection, Utils) { + function MultipleSelection ($element, options) { + MultipleSelection.__super__.constructor.apply(this, arguments); + } + + Utils.Extend(MultipleSelection, BaseSelection); + + MultipleSelection.prototype.render = function () { + var $selection = MultipleSelection.__super__.render.call(this); + + $selection.addClass('select2-selection--multiple'); + + $selection.html( + '
        ' + ); + + return $selection; + }; + + MultipleSelection.prototype.bind = function (container, $container) { + var self = this; + + MultipleSelection.__super__.bind.apply(this, arguments); + + this.$selection.on('click', function (evt) { + self.trigger('toggle', { + originalEvent: evt + }); + }); + + this.$selection.on( + 'click', + '.select2-selection__choice__remove', + function (evt) { + // Ignore the event if it is disabled + if (self.isDisabled()) { + return; + } + + var $remove = $(this); + var $selection = $remove.parent(); + + var data = Utils.GetData($selection[0], 'data'); + + self.trigger('unselect', { + originalEvent: evt, + data: data + }); + } + ); + }; + + MultipleSelection.prototype.clear = function () { + var $rendered = this.$selection.find('.select2-selection__rendered'); + $rendered.empty(); + $rendered.removeAttr('title'); + }; + + MultipleSelection.prototype.display = function (data, container) { + var template = this.options.get('templateSelection'); + var escapeMarkup = this.options.get('escapeMarkup'); + + return escapeMarkup(template(data, container)); + }; + + MultipleSelection.prototype.selectionContainer = function () { + var $container = $( + '
      • ' + + '' + + '×' + + '' + + '
      • ' + ); + + return $container; + }; + + MultipleSelection.prototype.update = function (data) { + this.clear(); + + if (data.length === 0) { + return; + } + + var $selections = []; + + for (var d = 0; d < data.length; d++) { + var selection = data[d]; + + var $selection = this.selectionContainer(); + var formatted = this.display(selection, $selection); + + $selection.append(formatted); + + var title = selection.title || selection.text; + + if (title) { + $selection.attr('title', title); + } + + Utils.StoreData($selection[0], 'data', selection); + + $selections.push($selection); + } + + var $rendered = this.$selection.find('.select2-selection__rendered'); + + Utils.appendMany($rendered, $selections); + }; + + return MultipleSelection; +}); + +S2.define('select2/selection/placeholder',[ + '../utils' +], function (Utils) { + function Placeholder (decorated, $element, options) { + this.placeholder = this.normalizePlaceholder(options.get('placeholder')); + + decorated.call(this, $element, options); + } + + Placeholder.prototype.normalizePlaceholder = function (_, placeholder) { + if (typeof placeholder === 'string') { + placeholder = { + id: '', + text: placeholder + }; + } + + return placeholder; + }; + + Placeholder.prototype.createPlaceholder = function (decorated, placeholder) { + var $placeholder = this.selectionContainer(); + + $placeholder.html(this.display(placeholder)); + $placeholder.addClass('select2-selection__placeholder') + .removeClass('select2-selection__choice'); + + return $placeholder; + }; + + Placeholder.prototype.update = function (decorated, data) { + var singlePlaceholder = ( + data.length == 1 && data[0].id != this.placeholder.id + ); + var multipleSelections = data.length > 1; + + if (multipleSelections || singlePlaceholder) { + return decorated.call(this, data); + } + + this.clear(); + + var $placeholder = this.createPlaceholder(this.placeholder); + + this.$selection.find('.select2-selection__rendered').append($placeholder); + }; + + return Placeholder; +}); + +S2.define('select2/selection/allowClear',[ + 'jquery', + '../keys', + '../utils' +], function ($, KEYS, Utils) { + function AllowClear () { } + + AllowClear.prototype.bind = function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + if (this.placeholder == null) { + if (this.options.get('debug') && window.console && console.error) { + console.error( + 'Select2: The `allowClear` option should be used in combination ' + + 'with the `placeholder` option.' + ); + } + } + + this.$selection.on('mousedown', '.select2-selection__clear', + function (evt) { + self._handleClear(evt); + }); + + container.on('keypress', function (evt) { + self._handleKeyboardClear(evt, container); + }); + }; + + AllowClear.prototype._handleClear = function (_, evt) { + // Ignore the event if it is disabled + if (this.isDisabled()) { + return; + } + + var $clear = this.$selection.find('.select2-selection__clear'); + + // Ignore the event if nothing has been selected + if ($clear.length === 0) { + return; + } + + evt.stopPropagation(); + + var data = Utils.GetData($clear[0], 'data'); + + var previousVal = this.$element.val(); + this.$element.val(this.placeholder.id); + + var unselectData = { + data: data + }; + this.trigger('clear', unselectData); + if (unselectData.prevented) { + this.$element.val(previousVal); + return; + } + + for (var d = 0; d < data.length; d++) { + unselectData = { + data: data[d] + }; + + // Trigger the `unselect` event, so people can prevent it from being + // cleared. + this.trigger('unselect', unselectData); + + // If the event was prevented, don't clear it out. + if (unselectData.prevented) { + this.$element.val(previousVal); + return; + } + } + + this.$element.trigger('input').trigger('change'); + + this.trigger('toggle', {}); + }; + + AllowClear.prototype._handleKeyboardClear = function (_, evt, container) { + if (container.isOpen()) { + return; + } + + if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) { + this._handleClear(evt); + } + }; + + AllowClear.prototype.update = function (decorated, data) { + decorated.call(this, data); + + if (this.$selection.find('.select2-selection__placeholder').length > 0 || + data.length === 0) { + return; + } + + var removeAll = this.options.get('translations').get('removeAllItems'); + + var $remove = $( + '' + + '×' + + '' + ); + Utils.StoreData($remove[0], 'data', data); + + this.$selection.find('.select2-selection__rendered').prepend($remove); + }; + + return AllowClear; +}); + +S2.define('select2/selection/search',[ + 'jquery', + '../utils', + '../keys' +], function ($, Utils, KEYS) { + function Search (decorated, $element, options) { + decorated.call(this, $element, options); + } + + Search.prototype.render = function (decorated) { + var $search = $( + '' + ); + + this.$searchContainer = $search; + this.$search = $search.find('input'); + + var $rendered = decorated.call(this); + + this._transferTabIndex(); + + return $rendered; + }; + + Search.prototype.bind = function (decorated, container, $container) { + var self = this; + + var resultsId = container.id + '-results'; + + decorated.call(this, container, $container); + + container.on('open', function () { + self.$search.attr('aria-controls', resultsId); + self.$search.trigger('focus'); + }); + + container.on('close', function () { + self.$search.val(''); + self.$search.removeAttr('aria-controls'); + self.$search.removeAttr('aria-activedescendant'); + self.$search.trigger('focus'); + }); + + container.on('enable', function () { + self.$search.prop('disabled', false); + + self._transferTabIndex(); + }); + + container.on('disable', function () { + self.$search.prop('disabled', true); + }); + + container.on('focus', function (evt) { + self.$search.trigger('focus'); + }); + + container.on('results:focus', function (params) { + if (params.data._resultId) { + self.$search.attr('aria-activedescendant', params.data._resultId); + } else { + self.$search.removeAttr('aria-activedescendant'); + } + }); + + this.$selection.on('focusin', '.select2-search--inline', function (evt) { + self.trigger('focus', evt); + }); + + this.$selection.on('focusout', '.select2-search--inline', function (evt) { + self._handleBlur(evt); + }); + + this.$selection.on('keydown', '.select2-search--inline', function (evt) { + evt.stopPropagation(); + + self.trigger('keypress', evt); + + self._keyUpPrevented = evt.isDefaultPrevented(); + + var key = evt.which; + + if (key === KEYS.BACKSPACE && self.$search.val() === '') { + var $previousChoice = self.$searchContainer + .prev('.select2-selection__choice'); + + if ($previousChoice.length > 0) { + var item = Utils.GetData($previousChoice[0], 'data'); + + self.searchRemoveChoice(item); + + evt.preventDefault(); + } + } + }); + + this.$selection.on('click', '.select2-search--inline', function (evt) { + if (self.$search.val()) { + evt.stopPropagation(); + } + }); + + // Try to detect the IE version should the `documentMode` property that + // is stored on the document. This is only implemented in IE and is + // slightly cleaner than doing a user agent check. + // This property is not available in Edge, but Edge also doesn't have + // this bug. + var msie = document.documentMode; + var disableInputEvents = msie && msie <= 11; + + // Workaround for browsers which do not support the `input` event + // This will prevent double-triggering of events for browsers which support + // both the `keyup` and `input` events. + this.$selection.on( + 'input.searchcheck', + '.select2-search--inline', + function (evt) { + // IE will trigger the `input` event when a placeholder is used on a + // search box. To get around this issue, we are forced to ignore all + // `input` events in IE and keep using `keyup`. + if (disableInputEvents) { + self.$selection.off('input.search input.searchcheck'); + return; + } + + // Unbind the duplicated `keyup` event + self.$selection.off('keyup.search'); + } + ); + + this.$selection.on( + 'keyup.search input.search', + '.select2-search--inline', + function (evt) { + // IE will trigger the `input` event when a placeholder is used on a + // search box. To get around this issue, we are forced to ignore all + // `input` events in IE and keep using `keyup`. + if (disableInputEvents && evt.type === 'input') { + self.$selection.off('input.search input.searchcheck'); + return; + } + + var key = evt.which; + + // We can freely ignore events from modifier keys + if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) { + return; + } + + // Tabbing will be handled during the `keydown` phase + if (key == KEYS.TAB) { + return; + } + + self.handleSearch(evt); + } + ); + }; + + /** + * This method will transfer the tabindex attribute from the rendered + * selection to the search box. This allows for the search box to be used as + * the primary focus instead of the selection container. + * + * @private + */ + Search.prototype._transferTabIndex = function (decorated) { + this.$search.attr('tabindex', this.$selection.attr('tabindex')); + this.$selection.attr('tabindex', '-1'); + }; + + Search.prototype.createPlaceholder = function (decorated, placeholder) { + this.$search.attr('placeholder', placeholder.text); + }; + + Search.prototype.update = function (decorated, data) { + var searchHadFocus = this.$search[0] == document.activeElement; + + this.$search.attr('placeholder', ''); + + decorated.call(this, data); + + this.$selection.find('.select2-selection__rendered') + .append(this.$searchContainer); + + this.resizeSearch(); + if (searchHadFocus) { + this.$search.trigger('focus'); + } + }; + + Search.prototype.handleSearch = function () { + this.resizeSearch(); + + if (!this._keyUpPrevented) { + var input = this.$search.val(); + + this.trigger('query', { + term: input + }); + } + + this._keyUpPrevented = false; + }; + + Search.prototype.searchRemoveChoice = function (decorated, item) { + this.trigger('unselect', { + data: item + }); + + this.$search.val(item.text); + this.handleSearch(); + }; + + Search.prototype.resizeSearch = function () { + this.$search.css('width', '25px'); + + var width = ''; + + if (this.$search.attr('placeholder') !== '') { + width = this.$selection.find('.select2-selection__rendered').width(); + } else { + var minimumWidth = this.$search.val().length + 1; + + width = (minimumWidth * 0.75) + 'em'; + } + + this.$search.css('width', width); + }; + + return Search; +}); + +S2.define('select2/selection/eventRelay',[ + 'jquery' +], function ($) { + function EventRelay () { } + + EventRelay.prototype.bind = function (decorated, container, $container) { + var self = this; + var relayEvents = [ + 'open', 'opening', + 'close', 'closing', + 'select', 'selecting', + 'unselect', 'unselecting', + 'clear', 'clearing' + ]; + + var preventableEvents = [ + 'opening', 'closing', 'selecting', 'unselecting', 'clearing' + ]; + + decorated.call(this, container, $container); + + container.on('*', function (name, params) { + // Ignore events that should not be relayed + if ($.inArray(name, relayEvents) === -1) { + return; + } + + // The parameters should always be an object + params = params || {}; + + // Generate the jQuery event for the Select2 event + var evt = $.Event('select2:' + name, { + params: params + }); + + self.$element.trigger(evt); + + // Only handle preventable events if it was one + if ($.inArray(name, preventableEvents) === -1) { + return; + } + + params.prevented = evt.isDefaultPrevented(); + }); + }; + + return EventRelay; +}); + +S2.define('select2/translation',[ + 'jquery', + 'require' +], function ($, require) { + function Translation (dict) { + this.dict = dict || {}; + } + + Translation.prototype.all = function () { + return this.dict; + }; + + Translation.prototype.get = function (key) { + return this.dict[key]; + }; + + Translation.prototype.extend = function (translation) { + this.dict = $.extend({}, translation.all(), this.dict); + }; + + // Static functions + + Translation._cache = {}; + + Translation.loadPath = function (path) { + if (!(path in Translation._cache)) { + var translations = require(path); + + Translation._cache[path] = translations; + } + + return new Translation(Translation._cache[path]); + }; + + return Translation; +}); + +S2.define('select2/diacritics',[ + +], function () { + var diacritics = { + '\u24B6': 'A', + '\uFF21': 'A', + '\u00C0': 'A', + '\u00C1': 'A', + '\u00C2': 'A', + '\u1EA6': 'A', + '\u1EA4': 'A', + '\u1EAA': 'A', + '\u1EA8': 'A', + '\u00C3': 'A', + '\u0100': 'A', + '\u0102': 'A', + '\u1EB0': 'A', + '\u1EAE': 'A', + '\u1EB4': 'A', + '\u1EB2': 'A', + '\u0226': 'A', + '\u01E0': 'A', + '\u00C4': 'A', + '\u01DE': 'A', + '\u1EA2': 'A', + '\u00C5': 'A', + '\u01FA': 'A', + '\u01CD': 'A', + '\u0200': 'A', + '\u0202': 'A', + '\u1EA0': 'A', + '\u1EAC': 'A', + '\u1EB6': 'A', + '\u1E00': 'A', + '\u0104': 'A', + '\u023A': 'A', + '\u2C6F': 'A', + '\uA732': 'AA', + '\u00C6': 'AE', + '\u01FC': 'AE', + '\u01E2': 'AE', + '\uA734': 'AO', + '\uA736': 'AU', + '\uA738': 'AV', + '\uA73A': 'AV', + '\uA73C': 'AY', + '\u24B7': 'B', + '\uFF22': 'B', + '\u1E02': 'B', + '\u1E04': 'B', + '\u1E06': 'B', + '\u0243': 'B', + '\u0182': 'B', + '\u0181': 'B', + '\u24B8': 'C', + '\uFF23': 'C', + '\u0106': 'C', + '\u0108': 'C', + '\u010A': 'C', + '\u010C': 'C', + '\u00C7': 'C', + '\u1E08': 'C', + '\u0187': 'C', + '\u023B': 'C', + '\uA73E': 'C', + '\u24B9': 'D', + '\uFF24': 'D', + '\u1E0A': 'D', + '\u010E': 'D', + '\u1E0C': 'D', + '\u1E10': 'D', + '\u1E12': 'D', + '\u1E0E': 'D', + '\u0110': 'D', + '\u018B': 'D', + '\u018A': 'D', + '\u0189': 'D', + '\uA779': 'D', + '\u01F1': 'DZ', + '\u01C4': 'DZ', + '\u01F2': 'Dz', + '\u01C5': 'Dz', + '\u24BA': 'E', + '\uFF25': 'E', + '\u00C8': 'E', + '\u00C9': 'E', + '\u00CA': 'E', + '\u1EC0': 'E', + '\u1EBE': 'E', + '\u1EC4': 'E', + '\u1EC2': 'E', + '\u1EBC': 'E', + '\u0112': 'E', + '\u1E14': 'E', + '\u1E16': 'E', + '\u0114': 'E', + '\u0116': 'E', + '\u00CB': 'E', + '\u1EBA': 'E', + '\u011A': 'E', + '\u0204': 'E', + '\u0206': 'E', + '\u1EB8': 'E', + '\u1EC6': 'E', + '\u0228': 'E', + '\u1E1C': 'E', + '\u0118': 'E', + '\u1E18': 'E', + '\u1E1A': 'E', + '\u0190': 'E', + '\u018E': 'E', + '\u24BB': 'F', + '\uFF26': 'F', + '\u1E1E': 'F', + '\u0191': 'F', + '\uA77B': 'F', + '\u24BC': 'G', + '\uFF27': 'G', + '\u01F4': 'G', + '\u011C': 'G', + '\u1E20': 'G', + '\u011E': 'G', + '\u0120': 'G', + '\u01E6': 'G', + '\u0122': 'G', + '\u01E4': 'G', + '\u0193': 'G', + '\uA7A0': 'G', + '\uA77D': 'G', + '\uA77E': 'G', + '\u24BD': 'H', + '\uFF28': 'H', + '\u0124': 'H', + '\u1E22': 'H', + '\u1E26': 'H', + '\u021E': 'H', + '\u1E24': 'H', + '\u1E28': 'H', + '\u1E2A': 'H', + '\u0126': 'H', + '\u2C67': 'H', + '\u2C75': 'H', + '\uA78D': 'H', + '\u24BE': 'I', + '\uFF29': 'I', + '\u00CC': 'I', + '\u00CD': 'I', + '\u00CE': 'I', + '\u0128': 'I', + '\u012A': 'I', + '\u012C': 'I', + '\u0130': 'I', + '\u00CF': 'I', + '\u1E2E': 'I', + '\u1EC8': 'I', + '\u01CF': 'I', + '\u0208': 'I', + '\u020A': 'I', + '\u1ECA': 'I', + '\u012E': 'I', + '\u1E2C': 'I', + '\u0197': 'I', + '\u24BF': 'J', + '\uFF2A': 'J', + '\u0134': 'J', + '\u0248': 'J', + '\u24C0': 'K', + '\uFF2B': 'K', + '\u1E30': 'K', + '\u01E8': 'K', + '\u1E32': 'K', + '\u0136': 'K', + '\u1E34': 'K', + '\u0198': 'K', + '\u2C69': 'K', + '\uA740': 'K', + '\uA742': 'K', + '\uA744': 'K', + '\uA7A2': 'K', + '\u24C1': 'L', + '\uFF2C': 'L', + '\u013F': 'L', + '\u0139': 'L', + '\u013D': 'L', + '\u1E36': 'L', + '\u1E38': 'L', + '\u013B': 'L', + '\u1E3C': 'L', + '\u1E3A': 'L', + '\u0141': 'L', + '\u023D': 'L', + '\u2C62': 'L', + '\u2C60': 'L', + '\uA748': 'L', + '\uA746': 'L', + '\uA780': 'L', + '\u01C7': 'LJ', + '\u01C8': 'Lj', + '\u24C2': 'M', + '\uFF2D': 'M', + '\u1E3E': 'M', + '\u1E40': 'M', + '\u1E42': 'M', + '\u2C6E': 'M', + '\u019C': 'M', + '\u24C3': 'N', + '\uFF2E': 'N', + '\u01F8': 'N', + '\u0143': 'N', + '\u00D1': 'N', + '\u1E44': 'N', + '\u0147': 'N', + '\u1E46': 'N', + '\u0145': 'N', + '\u1E4A': 'N', + '\u1E48': 'N', + '\u0220': 'N', + '\u019D': 'N', + '\uA790': 'N', + '\uA7A4': 'N', + '\u01CA': 'NJ', + '\u01CB': 'Nj', + '\u24C4': 'O', + '\uFF2F': 'O', + '\u00D2': 'O', + '\u00D3': 'O', + '\u00D4': 'O', + '\u1ED2': 'O', + '\u1ED0': 'O', + '\u1ED6': 'O', + '\u1ED4': 'O', + '\u00D5': 'O', + '\u1E4C': 'O', + '\u022C': 'O', + '\u1E4E': 'O', + '\u014C': 'O', + '\u1E50': 'O', + '\u1E52': 'O', + '\u014E': 'O', + '\u022E': 'O', + '\u0230': 'O', + '\u00D6': 'O', + '\u022A': 'O', + '\u1ECE': 'O', + '\u0150': 'O', + '\u01D1': 'O', + '\u020C': 'O', + '\u020E': 'O', + '\u01A0': 'O', + '\u1EDC': 'O', + '\u1EDA': 'O', + '\u1EE0': 'O', + '\u1EDE': 'O', + '\u1EE2': 'O', + '\u1ECC': 'O', + '\u1ED8': 'O', + '\u01EA': 'O', + '\u01EC': 'O', + '\u00D8': 'O', + '\u01FE': 'O', + '\u0186': 'O', + '\u019F': 'O', + '\uA74A': 'O', + '\uA74C': 'O', + '\u0152': 'OE', + '\u01A2': 'OI', + '\uA74E': 'OO', + '\u0222': 'OU', + '\u24C5': 'P', + '\uFF30': 'P', + '\u1E54': 'P', + '\u1E56': 'P', + '\u01A4': 'P', + '\u2C63': 'P', + '\uA750': 'P', + '\uA752': 'P', + '\uA754': 'P', + '\u24C6': 'Q', + '\uFF31': 'Q', + '\uA756': 'Q', + '\uA758': 'Q', + '\u024A': 'Q', + '\u24C7': 'R', + '\uFF32': 'R', + '\u0154': 'R', + '\u1E58': 'R', + '\u0158': 'R', + '\u0210': 'R', + '\u0212': 'R', + '\u1E5A': 'R', + '\u1E5C': 'R', + '\u0156': 'R', + '\u1E5E': 'R', + '\u024C': 'R', + '\u2C64': 'R', + '\uA75A': 'R', + '\uA7A6': 'R', + '\uA782': 'R', + '\u24C8': 'S', + '\uFF33': 'S', + '\u1E9E': 'S', + '\u015A': 'S', + '\u1E64': 'S', + '\u015C': 'S', + '\u1E60': 'S', + '\u0160': 'S', + '\u1E66': 'S', + '\u1E62': 'S', + '\u1E68': 'S', + '\u0218': 'S', + '\u015E': 'S', + '\u2C7E': 'S', + '\uA7A8': 'S', + '\uA784': 'S', + '\u24C9': 'T', + '\uFF34': 'T', + '\u1E6A': 'T', + '\u0164': 'T', + '\u1E6C': 'T', + '\u021A': 'T', + '\u0162': 'T', + '\u1E70': 'T', + '\u1E6E': 'T', + '\u0166': 'T', + '\u01AC': 'T', + '\u01AE': 'T', + '\u023E': 'T', + '\uA786': 'T', + '\uA728': 'TZ', + '\u24CA': 'U', + '\uFF35': 'U', + '\u00D9': 'U', + '\u00DA': 'U', + '\u00DB': 'U', + '\u0168': 'U', + '\u1E78': 'U', + '\u016A': 'U', + '\u1E7A': 'U', + '\u016C': 'U', + '\u00DC': 'U', + '\u01DB': 'U', + '\u01D7': 'U', + '\u01D5': 'U', + '\u01D9': 'U', + '\u1EE6': 'U', + '\u016E': 'U', + '\u0170': 'U', + '\u01D3': 'U', + '\u0214': 'U', + '\u0216': 'U', + '\u01AF': 'U', + '\u1EEA': 'U', + '\u1EE8': 'U', + '\u1EEE': 'U', + '\u1EEC': 'U', + '\u1EF0': 'U', + '\u1EE4': 'U', + '\u1E72': 'U', + '\u0172': 'U', + '\u1E76': 'U', + '\u1E74': 'U', + '\u0244': 'U', + '\u24CB': 'V', + '\uFF36': 'V', + '\u1E7C': 'V', + '\u1E7E': 'V', + '\u01B2': 'V', + '\uA75E': 'V', + '\u0245': 'V', + '\uA760': 'VY', + '\u24CC': 'W', + '\uFF37': 'W', + '\u1E80': 'W', + '\u1E82': 'W', + '\u0174': 'W', + '\u1E86': 'W', + '\u1E84': 'W', + '\u1E88': 'W', + '\u2C72': 'W', + '\u24CD': 'X', + '\uFF38': 'X', + '\u1E8A': 'X', + '\u1E8C': 'X', + '\u24CE': 'Y', + '\uFF39': 'Y', + '\u1EF2': 'Y', + '\u00DD': 'Y', + '\u0176': 'Y', + '\u1EF8': 'Y', + '\u0232': 'Y', + '\u1E8E': 'Y', + '\u0178': 'Y', + '\u1EF6': 'Y', + '\u1EF4': 'Y', + '\u01B3': 'Y', + '\u024E': 'Y', + '\u1EFE': 'Y', + '\u24CF': 'Z', + '\uFF3A': 'Z', + '\u0179': 'Z', + '\u1E90': 'Z', + '\u017B': 'Z', + '\u017D': 'Z', + '\u1E92': 'Z', + '\u1E94': 'Z', + '\u01B5': 'Z', + '\u0224': 'Z', + '\u2C7F': 'Z', + '\u2C6B': 'Z', + '\uA762': 'Z', + '\u24D0': 'a', + '\uFF41': 'a', + '\u1E9A': 'a', + '\u00E0': 'a', + '\u00E1': 'a', + '\u00E2': 'a', + '\u1EA7': 'a', + '\u1EA5': 'a', + '\u1EAB': 'a', + '\u1EA9': 'a', + '\u00E3': 'a', + '\u0101': 'a', + '\u0103': 'a', + '\u1EB1': 'a', + '\u1EAF': 'a', + '\u1EB5': 'a', + '\u1EB3': 'a', + '\u0227': 'a', + '\u01E1': 'a', + '\u00E4': 'a', + '\u01DF': 'a', + '\u1EA3': 'a', + '\u00E5': 'a', + '\u01FB': 'a', + '\u01CE': 'a', + '\u0201': 'a', + '\u0203': 'a', + '\u1EA1': 'a', + '\u1EAD': 'a', + '\u1EB7': 'a', + '\u1E01': 'a', + '\u0105': 'a', + '\u2C65': 'a', + '\u0250': 'a', + '\uA733': 'aa', + '\u00E6': 'ae', + '\u01FD': 'ae', + '\u01E3': 'ae', + '\uA735': 'ao', + '\uA737': 'au', + '\uA739': 'av', + '\uA73B': 'av', + '\uA73D': 'ay', + '\u24D1': 'b', + '\uFF42': 'b', + '\u1E03': 'b', + '\u1E05': 'b', + '\u1E07': 'b', + '\u0180': 'b', + '\u0183': 'b', + '\u0253': 'b', + '\u24D2': 'c', + '\uFF43': 'c', + '\u0107': 'c', + '\u0109': 'c', + '\u010B': 'c', + '\u010D': 'c', + '\u00E7': 'c', + '\u1E09': 'c', + '\u0188': 'c', + '\u023C': 'c', + '\uA73F': 'c', + '\u2184': 'c', + '\u24D3': 'd', + '\uFF44': 'd', + '\u1E0B': 'd', + '\u010F': 'd', + '\u1E0D': 'd', + '\u1E11': 'd', + '\u1E13': 'd', + '\u1E0F': 'd', + '\u0111': 'd', + '\u018C': 'd', + '\u0256': 'd', + '\u0257': 'd', + '\uA77A': 'd', + '\u01F3': 'dz', + '\u01C6': 'dz', + '\u24D4': 'e', + '\uFF45': 'e', + '\u00E8': 'e', + '\u00E9': 'e', + '\u00EA': 'e', + '\u1EC1': 'e', + '\u1EBF': 'e', + '\u1EC5': 'e', + '\u1EC3': 'e', + '\u1EBD': 'e', + '\u0113': 'e', + '\u1E15': 'e', + '\u1E17': 'e', + '\u0115': 'e', + '\u0117': 'e', + '\u00EB': 'e', + '\u1EBB': 'e', + '\u011B': 'e', + '\u0205': 'e', + '\u0207': 'e', + '\u1EB9': 'e', + '\u1EC7': 'e', + '\u0229': 'e', + '\u1E1D': 'e', + '\u0119': 'e', + '\u1E19': 'e', + '\u1E1B': 'e', + '\u0247': 'e', + '\u025B': 'e', + '\u01DD': 'e', + '\u24D5': 'f', + '\uFF46': 'f', + '\u1E1F': 'f', + '\u0192': 'f', + '\uA77C': 'f', + '\u24D6': 'g', + '\uFF47': 'g', + '\u01F5': 'g', + '\u011D': 'g', + '\u1E21': 'g', + '\u011F': 'g', + '\u0121': 'g', + '\u01E7': 'g', + '\u0123': 'g', + '\u01E5': 'g', + '\u0260': 'g', + '\uA7A1': 'g', + '\u1D79': 'g', + '\uA77F': 'g', + '\u24D7': 'h', + '\uFF48': 'h', + '\u0125': 'h', + '\u1E23': 'h', + '\u1E27': 'h', + '\u021F': 'h', + '\u1E25': 'h', + '\u1E29': 'h', + '\u1E2B': 'h', + '\u1E96': 'h', + '\u0127': 'h', + '\u2C68': 'h', + '\u2C76': 'h', + '\u0265': 'h', + '\u0195': 'hv', + '\u24D8': 'i', + '\uFF49': 'i', + '\u00EC': 'i', + '\u00ED': 'i', + '\u00EE': 'i', + '\u0129': 'i', + '\u012B': 'i', + '\u012D': 'i', + '\u00EF': 'i', + '\u1E2F': 'i', + '\u1EC9': 'i', + '\u01D0': 'i', + '\u0209': 'i', + '\u020B': 'i', + '\u1ECB': 'i', + '\u012F': 'i', + '\u1E2D': 'i', + '\u0268': 'i', + '\u0131': 'i', + '\u24D9': 'j', + '\uFF4A': 'j', + '\u0135': 'j', + '\u01F0': 'j', + '\u0249': 'j', + '\u24DA': 'k', + '\uFF4B': 'k', + '\u1E31': 'k', + '\u01E9': 'k', + '\u1E33': 'k', + '\u0137': 'k', + '\u1E35': 'k', + '\u0199': 'k', + '\u2C6A': 'k', + '\uA741': 'k', + '\uA743': 'k', + '\uA745': 'k', + '\uA7A3': 'k', + '\u24DB': 'l', + '\uFF4C': 'l', + '\u0140': 'l', + '\u013A': 'l', + '\u013E': 'l', + '\u1E37': 'l', + '\u1E39': 'l', + '\u013C': 'l', + '\u1E3D': 'l', + '\u1E3B': 'l', + '\u017F': 'l', + '\u0142': 'l', + '\u019A': 'l', + '\u026B': 'l', + '\u2C61': 'l', + '\uA749': 'l', + '\uA781': 'l', + '\uA747': 'l', + '\u01C9': 'lj', + '\u24DC': 'm', + '\uFF4D': 'm', + '\u1E3F': 'm', + '\u1E41': 'm', + '\u1E43': 'm', + '\u0271': 'm', + '\u026F': 'm', + '\u24DD': 'n', + '\uFF4E': 'n', + '\u01F9': 'n', + '\u0144': 'n', + '\u00F1': 'n', + '\u1E45': 'n', + '\u0148': 'n', + '\u1E47': 'n', + '\u0146': 'n', + '\u1E4B': 'n', + '\u1E49': 'n', + '\u019E': 'n', + '\u0272': 'n', + '\u0149': 'n', + '\uA791': 'n', + '\uA7A5': 'n', + '\u01CC': 'nj', + '\u24DE': 'o', + '\uFF4F': 'o', + '\u00F2': 'o', + '\u00F3': 'o', + '\u00F4': 'o', + '\u1ED3': 'o', + '\u1ED1': 'o', + '\u1ED7': 'o', + '\u1ED5': 'o', + '\u00F5': 'o', + '\u1E4D': 'o', + '\u022D': 'o', + '\u1E4F': 'o', + '\u014D': 'o', + '\u1E51': 'o', + '\u1E53': 'o', + '\u014F': 'o', + '\u022F': 'o', + '\u0231': 'o', + '\u00F6': 'o', + '\u022B': 'o', + '\u1ECF': 'o', + '\u0151': 'o', + '\u01D2': 'o', + '\u020D': 'o', + '\u020F': 'o', + '\u01A1': 'o', + '\u1EDD': 'o', + '\u1EDB': 'o', + '\u1EE1': 'o', + '\u1EDF': 'o', + '\u1EE3': 'o', + '\u1ECD': 'o', + '\u1ED9': 'o', + '\u01EB': 'o', + '\u01ED': 'o', + '\u00F8': 'o', + '\u01FF': 'o', + '\u0254': 'o', + '\uA74B': 'o', + '\uA74D': 'o', + '\u0275': 'o', + '\u0153': 'oe', + '\u01A3': 'oi', + '\u0223': 'ou', + '\uA74F': 'oo', + '\u24DF': 'p', + '\uFF50': 'p', + '\u1E55': 'p', + '\u1E57': 'p', + '\u01A5': 'p', + '\u1D7D': 'p', + '\uA751': 'p', + '\uA753': 'p', + '\uA755': 'p', + '\u24E0': 'q', + '\uFF51': 'q', + '\u024B': 'q', + '\uA757': 'q', + '\uA759': 'q', + '\u24E1': 'r', + '\uFF52': 'r', + '\u0155': 'r', + '\u1E59': 'r', + '\u0159': 'r', + '\u0211': 'r', + '\u0213': 'r', + '\u1E5B': 'r', + '\u1E5D': 'r', + '\u0157': 'r', + '\u1E5F': 'r', + '\u024D': 'r', + '\u027D': 'r', + '\uA75B': 'r', + '\uA7A7': 'r', + '\uA783': 'r', + '\u24E2': 's', + '\uFF53': 's', + '\u00DF': 's', + '\u015B': 's', + '\u1E65': 's', + '\u015D': 's', + '\u1E61': 's', + '\u0161': 's', + '\u1E67': 's', + '\u1E63': 's', + '\u1E69': 's', + '\u0219': 's', + '\u015F': 's', + '\u023F': 's', + '\uA7A9': 's', + '\uA785': 's', + '\u1E9B': 's', + '\u24E3': 't', + '\uFF54': 't', + '\u1E6B': 't', + '\u1E97': 't', + '\u0165': 't', + '\u1E6D': 't', + '\u021B': 't', + '\u0163': 't', + '\u1E71': 't', + '\u1E6F': 't', + '\u0167': 't', + '\u01AD': 't', + '\u0288': 't', + '\u2C66': 't', + '\uA787': 't', + '\uA729': 'tz', + '\u24E4': 'u', + '\uFF55': 'u', + '\u00F9': 'u', + '\u00FA': 'u', + '\u00FB': 'u', + '\u0169': 'u', + '\u1E79': 'u', + '\u016B': 'u', + '\u1E7B': 'u', + '\u016D': 'u', + '\u00FC': 'u', + '\u01DC': 'u', + '\u01D8': 'u', + '\u01D6': 'u', + '\u01DA': 'u', + '\u1EE7': 'u', + '\u016F': 'u', + '\u0171': 'u', + '\u01D4': 'u', + '\u0215': 'u', + '\u0217': 'u', + '\u01B0': 'u', + '\u1EEB': 'u', + '\u1EE9': 'u', + '\u1EEF': 'u', + '\u1EED': 'u', + '\u1EF1': 'u', + '\u1EE5': 'u', + '\u1E73': 'u', + '\u0173': 'u', + '\u1E77': 'u', + '\u1E75': 'u', + '\u0289': 'u', + '\u24E5': 'v', + '\uFF56': 'v', + '\u1E7D': 'v', + '\u1E7F': 'v', + '\u028B': 'v', + '\uA75F': 'v', + '\u028C': 'v', + '\uA761': 'vy', + '\u24E6': 'w', + '\uFF57': 'w', + '\u1E81': 'w', + '\u1E83': 'w', + '\u0175': 'w', + '\u1E87': 'w', + '\u1E85': 'w', + '\u1E98': 'w', + '\u1E89': 'w', + '\u2C73': 'w', + '\u24E7': 'x', + '\uFF58': 'x', + '\u1E8B': 'x', + '\u1E8D': 'x', + '\u24E8': 'y', + '\uFF59': 'y', + '\u1EF3': 'y', + '\u00FD': 'y', + '\u0177': 'y', + '\u1EF9': 'y', + '\u0233': 'y', + '\u1E8F': 'y', + '\u00FF': 'y', + '\u1EF7': 'y', + '\u1E99': 'y', + '\u1EF5': 'y', + '\u01B4': 'y', + '\u024F': 'y', + '\u1EFF': 'y', + '\u24E9': 'z', + '\uFF5A': 'z', + '\u017A': 'z', + '\u1E91': 'z', + '\u017C': 'z', + '\u017E': 'z', + '\u1E93': 'z', + '\u1E95': 'z', + '\u01B6': 'z', + '\u0225': 'z', + '\u0240': 'z', + '\u2C6C': 'z', + '\uA763': 'z', + '\u0386': '\u0391', + '\u0388': '\u0395', + '\u0389': '\u0397', + '\u038A': '\u0399', + '\u03AA': '\u0399', + '\u038C': '\u039F', + '\u038E': '\u03A5', + '\u03AB': '\u03A5', + '\u038F': '\u03A9', + '\u03AC': '\u03B1', + '\u03AD': '\u03B5', + '\u03AE': '\u03B7', + '\u03AF': '\u03B9', + '\u03CA': '\u03B9', + '\u0390': '\u03B9', + '\u03CC': '\u03BF', + '\u03CD': '\u03C5', + '\u03CB': '\u03C5', + '\u03B0': '\u03C5', + '\u03CE': '\u03C9', + '\u03C2': '\u03C3', + '\u2019': '\'' + }; + + return diacritics; +}); + +S2.define('select2/data/base',[ + '../utils' +], function (Utils) { + function BaseAdapter ($element, options) { + BaseAdapter.__super__.constructor.call(this); + } + + Utils.Extend(BaseAdapter, Utils.Observable); + + BaseAdapter.prototype.current = function (callback) { + throw new Error('The `current` method must be defined in child classes.'); + }; + + BaseAdapter.prototype.query = function (params, callback) { + throw new Error('The `query` method must be defined in child classes.'); + }; + + BaseAdapter.prototype.bind = function (container, $container) { + // Can be implemented in subclasses + }; + + BaseAdapter.prototype.destroy = function () { + // Can be implemented in subclasses + }; + + BaseAdapter.prototype.generateResultId = function (container, data) { + var id = container.id + '-result-'; + + id += Utils.generateChars(4); + + if (data.id != null) { + id += '-' + data.id.toString(); + } else { + id += '-' + Utils.generateChars(4); + } + return id; + }; + + return BaseAdapter; +}); + +S2.define('select2/data/select',[ + './base', + '../utils', + 'jquery' +], function (BaseAdapter, Utils, $) { + function SelectAdapter ($element, options) { + this.$element = $element; + this.options = options; + + SelectAdapter.__super__.constructor.call(this); + } + + Utils.Extend(SelectAdapter, BaseAdapter); + + SelectAdapter.prototype.current = function (callback) { + var data = []; + var self = this; + + this.$element.find(':selected').each(function () { + var $option = $(this); + + var option = self.item($option); + + data.push(option); + }); + + callback(data); + }; + + SelectAdapter.prototype.select = function (data) { + var self = this; + + data.selected = true; + + // If data.element is a DOM node, use it instead + if ($(data.element).is('option')) { + data.element.selected = true; + + this.$element.trigger('input').trigger('change'); + + return; + } + + if (this.$element.prop('multiple')) { + this.current(function (currentData) { + var val = []; + + data = [data]; + data.push.apply(data, currentData); + + for (var d = 0; d < data.length; d++) { + var id = data[d].id; + + if ($.inArray(id, val) === -1) { + val.push(id); + } + } + + self.$element.val(val); + self.$element.trigger('input').trigger('change'); + }); + } else { + var val = data.id; + + this.$element.val(val); + this.$element.trigger('input').trigger('change'); + } + }; + + SelectAdapter.prototype.unselect = function (data) { + var self = this; + + if (!this.$element.prop('multiple')) { + return; + } + + data.selected = false; + + if ($(data.element).is('option')) { + data.element.selected = false; + + this.$element.trigger('input').trigger('change'); + + return; + } + + this.current(function (currentData) { + var val = []; + + for (var d = 0; d < currentData.length; d++) { + var id = currentData[d].id; + + if (id !== data.id && $.inArray(id, val) === -1) { + val.push(id); + } + } + + self.$element.val(val); + + self.$element.trigger('input').trigger('change'); + }); + }; + + SelectAdapter.prototype.bind = function (container, $container) { + var self = this; + + this.container = container; + + container.on('select', function (params) { + self.select(params.data); + }); + + container.on('unselect', function (params) { + self.unselect(params.data); + }); + }; + + SelectAdapter.prototype.destroy = function () { + // Remove anything added to child elements + this.$element.find('*').each(function () { + // Remove any custom data set by Select2 + Utils.RemoveData(this); + }); + }; + + SelectAdapter.prototype.query = function (params, callback) { + var data = []; + var self = this; + + var $options = this.$element.children(); + + $options.each(function () { + var $option = $(this); + + if (!$option.is('option') && !$option.is('optgroup')) { + return; + } + + var option = self.item($option); + + var matches = self.matches(params, option); + + if (matches !== null) { + data.push(matches); + } + }); + + callback({ + results: data + }); + }; + + SelectAdapter.prototype.addOptions = function ($options) { + Utils.appendMany(this.$element, $options); + }; + + SelectAdapter.prototype.option = function (data) { + var option; + + if (data.children) { + option = document.createElement('optgroup'); + option.label = data.text; + } else { + option = document.createElement('option'); + + if (option.textContent !== undefined) { + option.textContent = data.text; + } else { + option.innerText = data.text; + } + } + + if (data.id !== undefined) { + option.value = data.id; + } + + if (data.disabled) { + option.disabled = true; + } + + if (data.selected) { + option.selected = true; + } + + if (data.title) { + option.title = data.title; + } + + var $option = $(option); + + var normalizedData = this._normalizeItem(data); + normalizedData.element = option; + + // Override the option's data with the combined data + Utils.StoreData(option, 'data', normalizedData); + + return $option; + }; + + SelectAdapter.prototype.item = function ($option) { + var data = {}; + + data = Utils.GetData($option[0], 'data'); + + if (data != null) { + return data; + } + + if ($option.is('option')) { + data = { + id: $option.val(), + text: $option.text(), + disabled: $option.prop('disabled'), + selected: $option.prop('selected'), + title: $option.prop('title') + }; + } else if ($option.is('optgroup')) { + data = { + text: $option.prop('label'), + children: [], + title: $option.prop('title') + }; + + var $children = $option.children('option'); + var children = []; + + for (var c = 0; c < $children.length; c++) { + var $child = $($children[c]); + + var child = this.item($child); + + children.push(child); + } + + data.children = children; + } + + data = this._normalizeItem(data); + data.element = $option[0]; + + Utils.StoreData($option[0], 'data', data); + + return data; + }; + + SelectAdapter.prototype._normalizeItem = function (item) { + if (item !== Object(item)) { + item = { + id: item, + text: item + }; + } + + item = $.extend({}, { + text: '' + }, item); + + var defaults = { + selected: false, + disabled: false + }; + + if (item.id != null) { + item.id = item.id.toString(); + } + + if (item.text != null) { + item.text = item.text.toString(); + } + + if (item._resultId == null && item.id && this.container != null) { + item._resultId = this.generateResultId(this.container, item); + } + + return $.extend({}, defaults, item); + }; + + SelectAdapter.prototype.matches = function (params, data) { + var matcher = this.options.get('matcher'); + + return matcher(params, data); + }; + + return SelectAdapter; +}); + +S2.define('select2/data/array',[ + './select', + '../utils', + 'jquery' +], function (SelectAdapter, Utils, $) { + function ArrayAdapter ($element, options) { + this._dataToConvert = options.get('data') || []; + + ArrayAdapter.__super__.constructor.call(this, $element, options); + } + + Utils.Extend(ArrayAdapter, SelectAdapter); + + ArrayAdapter.prototype.bind = function (container, $container) { + ArrayAdapter.__super__.bind.call(this, container, $container); + + this.addOptions(this.convertToOptions(this._dataToConvert)); + }; + + ArrayAdapter.prototype.select = function (data) { + var $option = this.$element.find('option').filter(function (i, elm) { + return elm.value == data.id.toString(); + }); + + if ($option.length === 0) { + $option = this.option(data); + + this.addOptions($option); + } + + ArrayAdapter.__super__.select.call(this, data); + }; + + ArrayAdapter.prototype.convertToOptions = function (data) { + var self = this; + + var $existing = this.$element.find('option'); + var existingIds = $existing.map(function () { + return self.item($(this)).id; + }).get(); + + var $options = []; + + // Filter out all items except for the one passed in the argument + function onlyItem (item) { + return function () { + return $(this).val() == item.id; + }; + } + + for (var d = 0; d < data.length; d++) { + var item = this._normalizeItem(data[d]); + + // Skip items which were pre-loaded, only merge the data + if ($.inArray(item.id, existingIds) >= 0) { + var $existingOption = $existing.filter(onlyItem(item)); + + var existingData = this.item($existingOption); + var newData = $.extend(true, {}, item, existingData); + + var $newOption = this.option(newData); + + $existingOption.replaceWith($newOption); + + continue; + } + + var $option = this.option(item); + + if (item.children) { + var $children = this.convertToOptions(item.children); + + Utils.appendMany($option, $children); + } + + $options.push($option); + } + + return $options; + }; + + return ArrayAdapter; +}); + +S2.define('select2/data/ajax',[ + './array', + '../utils', + 'jquery' +], function (ArrayAdapter, Utils, $) { + function AjaxAdapter ($element, options) { + this.ajaxOptions = this._applyDefaults(options.get('ajax')); + + if (this.ajaxOptions.processResults != null) { + this.processResults = this.ajaxOptions.processResults; + } + + AjaxAdapter.__super__.constructor.call(this, $element, options); + } + + Utils.Extend(AjaxAdapter, ArrayAdapter); + + AjaxAdapter.prototype._applyDefaults = function (options) { + var defaults = { + data: function (params) { + return $.extend({}, params, { + q: params.term + }); + }, + transport: function (params, success, failure) { + var $request = $.ajax(params); + + $request.then(success); + $request.fail(failure); + + return $request; + } + }; + + return $.extend({}, defaults, options, true); + }; + + AjaxAdapter.prototype.processResults = function (results) { + return results; + }; + + AjaxAdapter.prototype.query = function (params, callback) { + var matches = []; + var self = this; + + if (this._request != null) { + // JSONP requests cannot always be aborted + if ($.isFunction(this._request.abort)) { + this._request.abort(); + } + + this._request = null; + } + + var options = $.extend({ + type: 'GET' + }, this.ajaxOptions); + + if (typeof options.url === 'function') { + options.url = options.url.call(this.$element, params); + } + + if (typeof options.data === 'function') { + options.data = options.data.call(this.$element, params); + } + + function request () { + var $request = options.transport(options, function (data) { + var results = self.processResults(data, params); + + if (self.options.get('debug') && window.console && console.error) { + // Check to make sure that the response included a `results` key. + if (!results || !results.results || !$.isArray(results.results)) { + console.error( + 'Select2: The AJAX results did not return an array in the ' + + '`results` key of the response.' + ); + } + } + + callback(results); + }, function () { + // Attempt to detect if a request was aborted + // Only works if the transport exposes a status property + if ('status' in $request && + ($request.status === 0 || $request.status === '0')) { + return; + } + + self.trigger('results:message', { + message: 'errorLoading' + }); + }); + + self._request = $request; + } + + if (this.ajaxOptions.delay && params.term != null) { + if (this._queryTimeout) { + window.clearTimeout(this._queryTimeout); + } + + this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay); + } else { + request(); + } + }; + + return AjaxAdapter; +}); + +S2.define('select2/data/tags',[ + 'jquery' +], function ($) { + function Tags (decorated, $element, options) { + var tags = options.get('tags'); + + var createTag = options.get('createTag'); + + if (createTag !== undefined) { + this.createTag = createTag; + } + + var insertTag = options.get('insertTag'); + + if (insertTag !== undefined) { + this.insertTag = insertTag; + } + + decorated.call(this, $element, options); + + if ($.isArray(tags)) { + for (var t = 0; t < tags.length; t++) { + var tag = tags[t]; + var item = this._normalizeItem(tag); + + var $option = this.option(item); + + this.$element.append($option); + } + } + } + + Tags.prototype.query = function (decorated, params, callback) { + var self = this; + + this._removeOldTags(); + + if (params.term == null || params.page != null) { + decorated.call(this, params, callback); + return; + } + + function wrapper (obj, child) { + var data = obj.results; + + for (var i = 0; i < data.length; i++) { + var option = data[i]; + + var checkChildren = ( + option.children != null && + !wrapper({ + results: option.children + }, true) + ); + + var optionText = (option.text || '').toUpperCase(); + var paramsTerm = (params.term || '').toUpperCase(); + + var checkText = optionText === paramsTerm; + + if (checkText || checkChildren) { + if (child) { + return false; + } + + obj.data = data; + callback(obj); + + return; + } + } + + if (child) { + return true; + } + + var tag = self.createTag(params); + + if (tag != null) { + var $option = self.option(tag); + $option.attr('data-select2-tag', true); + + self.addOptions([$option]); + + self.insertTag(data, tag); + } + + obj.results = data; + + callback(obj); + } + + decorated.call(this, params, wrapper); + }; + + Tags.prototype.createTag = function (decorated, params) { + var term = $.trim(params.term); + + if (term === '') { + return null; + } + + return { + id: term, + text: term + }; + }; + + Tags.prototype.insertTag = function (_, data, tag) { + data.unshift(tag); + }; + + Tags.prototype._removeOldTags = function (_) { + var $options = this.$element.find('option[data-select2-tag]'); + + $options.each(function () { + if (this.selected) { + return; + } + + $(this).remove(); + }); + }; + + return Tags; +}); + +S2.define('select2/data/tokenizer',[ + 'jquery' +], function ($) { + function Tokenizer (decorated, $element, options) { + var tokenizer = options.get('tokenizer'); + + if (tokenizer !== undefined) { + this.tokenizer = tokenizer; + } + + decorated.call(this, $element, options); + } + + Tokenizer.prototype.bind = function (decorated, container, $container) { + decorated.call(this, container, $container); + + this.$search = container.dropdown.$search || container.selection.$search || + $container.find('.select2-search__field'); + }; + + Tokenizer.prototype.query = function (decorated, params, callback) { + var self = this; + + function createAndSelect (data) { + // Normalize the data object so we can use it for checks + var item = self._normalizeItem(data); + + // Check if the data object already exists as a tag + // Select it if it doesn't + var $existingOptions = self.$element.find('option').filter(function () { + return $(this).val() === item.id; + }); + + // If an existing option wasn't found for it, create the option + if (!$existingOptions.length) { + var $option = self.option(item); + $option.attr('data-select2-tag', true); + + self._removeOldTags(); + self.addOptions([$option]); + } + + // Select the item, now that we know there is an option for it + select(item); + } + + function select (data) { + self.trigger('select', { + data: data + }); + } + + params.term = params.term || ''; + + var tokenData = this.tokenizer(params, this.options, createAndSelect); + + if (tokenData.term !== params.term) { + // Replace the search term if we have the search box + if (this.$search.length) { + this.$search.val(tokenData.term); + this.$search.trigger('focus'); + } + + params.term = tokenData.term; + } + + decorated.call(this, params, callback); + }; + + Tokenizer.prototype.tokenizer = function (_, params, options, callback) { + var separators = options.get('tokenSeparators') || []; + var term = params.term; + var i = 0; + + var createTag = this.createTag || function (params) { + return { + id: params.term, + text: params.term + }; + }; + + while (i < term.length) { + var termChar = term[i]; + + if ($.inArray(termChar, separators) === -1) { + i++; + + continue; + } + + var part = term.substr(0, i); + var partParams = $.extend({}, params, { + term: part + }); + + var data = createTag(partParams); + + if (data == null) { + i++; + continue; + } + + callback(data); + + // Reset the term to not include the tokenized portion + term = term.substr(i + 1) || ''; + i = 0; + } + + return { + term: term + }; + }; + + return Tokenizer; +}); + +S2.define('select2/data/minimumInputLength',[ + +], function () { + function MinimumInputLength (decorated, $e, options) { + this.minimumInputLength = options.get('minimumInputLength'); + + decorated.call(this, $e, options); + } + + MinimumInputLength.prototype.query = function (decorated, params, callback) { + params.term = params.term || ''; + + if (params.term.length < this.minimumInputLength) { + this.trigger('results:message', { + message: 'inputTooShort', + args: { + minimum: this.minimumInputLength, + input: params.term, + params: params + } + }); + + return; + } + + decorated.call(this, params, callback); + }; + + return MinimumInputLength; +}); + +S2.define('select2/data/maximumInputLength',[ + +], function () { + function MaximumInputLength (decorated, $e, options) { + this.maximumInputLength = options.get('maximumInputLength'); + + decorated.call(this, $e, options); + } + + MaximumInputLength.prototype.query = function (decorated, params, callback) { + params.term = params.term || ''; + + if (this.maximumInputLength > 0 && + params.term.length > this.maximumInputLength) { + this.trigger('results:message', { + message: 'inputTooLong', + args: { + maximum: this.maximumInputLength, + input: params.term, + params: params + } + }); + + return; + } + + decorated.call(this, params, callback); + }; + + return MaximumInputLength; +}); + +S2.define('select2/data/maximumSelectionLength',[ + +], function (){ + function MaximumSelectionLength (decorated, $e, options) { + this.maximumSelectionLength = options.get('maximumSelectionLength'); + + decorated.call(this, $e, options); + } + + MaximumSelectionLength.prototype.bind = + function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + container.on('select', function () { + self._checkIfMaximumSelected(); + }); + }; + + MaximumSelectionLength.prototype.query = + function (decorated, params, callback) { + var self = this; + + this._checkIfMaximumSelected(function () { + decorated.call(self, params, callback); + }); + }; + + MaximumSelectionLength.prototype._checkIfMaximumSelected = + function (_, successCallback) { + var self = this; + + this.current(function (currentData) { + var count = currentData != null ? currentData.length : 0; + if (self.maximumSelectionLength > 0 && + count >= self.maximumSelectionLength) { + self.trigger('results:message', { + message: 'maximumSelected', + args: { + maximum: self.maximumSelectionLength + } + }); + return; + } + + if (successCallback) { + successCallback(); + } + }); + }; + + return MaximumSelectionLength; +}); + +S2.define('select2/dropdown',[ + 'jquery', + './utils' +], function ($, Utils) { + function Dropdown ($element, options) { + this.$element = $element; + this.options = options; + + Dropdown.__super__.constructor.call(this); + } + + Utils.Extend(Dropdown, Utils.Observable); + + Dropdown.prototype.render = function () { + var $dropdown = $( + '' + + '' + + '' + ); + + $dropdown.attr('dir', this.options.get('dir')); + + this.$dropdown = $dropdown; + + return $dropdown; + }; + + Dropdown.prototype.bind = function () { + // Should be implemented in subclasses + }; + + Dropdown.prototype.position = function ($dropdown, $container) { + // Should be implemented in subclasses + }; + + Dropdown.prototype.destroy = function () { + // Remove the dropdown from the DOM + this.$dropdown.remove(); + }; + + return Dropdown; +}); + +S2.define('select2/dropdown/search',[ + 'jquery', + '../utils' +], function ($, Utils) { + function Search () { } + + Search.prototype.render = function (decorated) { + var $rendered = decorated.call(this); + + var $search = $( + '' + + '' + + '' + ); + + this.$searchContainer = $search; + this.$search = $search.find('input'); + + $rendered.prepend($search); + + return $rendered; + }; + + Search.prototype.bind = function (decorated, container, $container) { + var self = this; + + var resultsId = container.id + '-results'; + + decorated.call(this, container, $container); + + this.$search.on('keydown', function (evt) { + self.trigger('keypress', evt); + + self._keyUpPrevented = evt.isDefaultPrevented(); + }); + + // Workaround for browsers which do not support the `input` event + // This will prevent double-triggering of events for browsers which support + // both the `keyup` and `input` events. + this.$search.on('input', function (evt) { + // Unbind the duplicated `keyup` event + $(this).off('keyup'); + }); + + this.$search.on('keyup input', function (evt) { + self.handleSearch(evt); + }); + + container.on('open', function () { + self.$search.attr('tabindex', 0); + self.$search.attr('aria-controls', resultsId); + + self.$search.trigger('focus'); + + window.setTimeout(function () { + self.$search.trigger('focus'); + }, 0); + }); + + container.on('close', function () { + self.$search.attr('tabindex', -1); + self.$search.removeAttr('aria-controls'); + self.$search.removeAttr('aria-activedescendant'); + + self.$search.val(''); + self.$search.trigger('blur'); + }); + + container.on('focus', function () { + if (!container.isOpen()) { + self.$search.trigger('focus'); + } + }); + + container.on('results:all', function (params) { + if (params.query.term == null || params.query.term === '') { + var showSearch = self.showSearch(params); + + if (showSearch) { + self.$searchContainer.removeClass('select2-search--hide'); + } else { + self.$searchContainer.addClass('select2-search--hide'); + } + } + }); + + container.on('results:focus', function (params) { + if (params.data._resultId) { + self.$search.attr('aria-activedescendant', params.data._resultId); + } else { + self.$search.removeAttr('aria-activedescendant'); + } + }); + }; + + Search.prototype.handleSearch = function (evt) { + if (!this._keyUpPrevented) { + var input = this.$search.val(); + + this.trigger('query', { + term: input + }); + } + + this._keyUpPrevented = false; + }; + + Search.prototype.showSearch = function (_, params) { + return true; + }; + + return Search; +}); + +S2.define('select2/dropdown/hidePlaceholder',[ + +], function () { + function HidePlaceholder (decorated, $element, options, dataAdapter) { + this.placeholder = this.normalizePlaceholder(options.get('placeholder')); + + decorated.call(this, $element, options, dataAdapter); + } + + HidePlaceholder.prototype.append = function (decorated, data) { + data.results = this.removePlaceholder(data.results); + + decorated.call(this, data); + }; + + HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) { + if (typeof placeholder === 'string') { + placeholder = { + id: '', + text: placeholder + }; + } + + return placeholder; + }; + + HidePlaceholder.prototype.removePlaceholder = function (_, data) { + var modifiedData = data.slice(0); + + for (var d = data.length - 1; d >= 0; d--) { + var item = data[d]; + + if (this.placeholder.id === item.id) { + modifiedData.splice(d, 1); + } + } + + return modifiedData; + }; + + return HidePlaceholder; +}); + +S2.define('select2/dropdown/infiniteScroll',[ + 'jquery' +], function ($) { + function InfiniteScroll (decorated, $element, options, dataAdapter) { + this.lastParams = {}; + + decorated.call(this, $element, options, dataAdapter); + + this.$loadingMore = this.createLoadingMore(); + this.loading = false; + } + + InfiniteScroll.prototype.append = function (decorated, data) { + this.$loadingMore.remove(); + this.loading = false; + + decorated.call(this, data); + + if (this.showLoadingMore(data)) { + this.$results.append(this.$loadingMore); + this.loadMoreIfNeeded(); + } + }; + + InfiniteScroll.prototype.bind = function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + container.on('query', function (params) { + self.lastParams = params; + self.loading = true; + }); + + container.on('query:append', function (params) { + self.lastParams = params; + self.loading = true; + }); + + this.$results.on('scroll', this.loadMoreIfNeeded.bind(this)); + }; + + InfiniteScroll.prototype.loadMoreIfNeeded = function () { + var isLoadMoreVisible = $.contains( + document.documentElement, + this.$loadingMore[0] + ); + + if (this.loading || !isLoadMoreVisible) { + return; + } + + var currentOffset = this.$results.offset().top + + this.$results.outerHeight(false); + var loadingMoreOffset = this.$loadingMore.offset().top + + this.$loadingMore.outerHeight(false); + + if (currentOffset + 50 >= loadingMoreOffset) { + this.loadMore(); + } + }; + + InfiniteScroll.prototype.loadMore = function () { + this.loading = true; + + var params = $.extend({}, {page: 1}, this.lastParams); + + params.page++; + + this.trigger('query:append', params); + }; + + InfiniteScroll.prototype.showLoadingMore = function (_, data) { + return data.pagination && data.pagination.more; + }; + + InfiniteScroll.prototype.createLoadingMore = function () { + var $option = $( + '
      • ' + ); + + var message = this.options.get('translations').get('loadingMore'); + + $option.html(message(this.lastParams)); + + return $option; + }; + + return InfiniteScroll; +}); + +S2.define('select2/dropdown/attachBody',[ + 'jquery', + '../utils' +], function ($, Utils) { + function AttachBody (decorated, $element, options) { + this.$dropdownParent = $(options.get('dropdownParent') || document.body); + + decorated.call(this, $element, options); + } + + AttachBody.prototype.bind = function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + container.on('open', function () { + self._showDropdown(); + self._attachPositioningHandler(container); + + // Must bind after the results handlers to ensure correct sizing + self._bindContainerResultHandlers(container); + }); + + container.on('close', function () { + self._hideDropdown(); + self._detachPositioningHandler(container); + }); + + this.$dropdownContainer.on('mousedown', function (evt) { + evt.stopPropagation(); + }); + }; + + AttachBody.prototype.destroy = function (decorated) { + decorated.call(this); + + this.$dropdownContainer.remove(); + }; + + AttachBody.prototype.position = function (decorated, $dropdown, $container) { + // Clone all of the container classes + $dropdown.attr('class', $container.attr('class')); + + $dropdown.removeClass('select2'); + $dropdown.addClass('select2-container--open'); + + $dropdown.css({ + position: 'absolute', + top: -999999 + }); + + this.$container = $container; + }; + + AttachBody.prototype.render = function (decorated) { + var $container = $(''); + + var $dropdown = decorated.call(this); + $container.append($dropdown); + + this.$dropdownContainer = $container; + + return $container; + }; + + AttachBody.prototype._hideDropdown = function (decorated) { + this.$dropdownContainer.detach(); + }; + + AttachBody.prototype._bindContainerResultHandlers = + function (decorated, container) { + + // These should only be bound once + if (this._containerResultsHandlersBound) { + return; + } + + var self = this; + + container.on('results:all', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + + container.on('results:append', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + + container.on('results:message', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + + container.on('select', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + + container.on('unselect', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + + this._containerResultsHandlersBound = true; + }; + + AttachBody.prototype._attachPositioningHandler = + function (decorated, container) { + var self = this; + + var scrollEvent = 'scroll.select2.' + container.id; + var resizeEvent = 'resize.select2.' + container.id; + var orientationEvent = 'orientationchange.select2.' + container.id; + + var $watchers = this.$container.parents().filter(Utils.hasScroll); + $watchers.each(function () { + Utils.StoreData(this, 'select2-scroll-position', { + x: $(this).scrollLeft(), + y: $(this).scrollTop() + }); + }); + + $watchers.on(scrollEvent, function (ev) { + var position = Utils.GetData(this, 'select2-scroll-position'); + $(this).scrollTop(position.y); + }); + + $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent, + function (e) { + self._positionDropdown(); + self._resizeDropdown(); + }); + }; + + AttachBody.prototype._detachPositioningHandler = + function (decorated, container) { + var scrollEvent = 'scroll.select2.' + container.id; + var resizeEvent = 'resize.select2.' + container.id; + var orientationEvent = 'orientationchange.select2.' + container.id; + + var $watchers = this.$container.parents().filter(Utils.hasScroll); + $watchers.off(scrollEvent); + + $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent); + }; + + AttachBody.prototype._positionDropdown = function () { + var $window = $(window); + + var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above'); + var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below'); + + var newDirection = null; + + var offset = this.$container.offset(); + + offset.bottom = offset.top + this.$container.outerHeight(false); + + var container = { + height: this.$container.outerHeight(false) + }; + + container.top = offset.top; + container.bottom = offset.top + container.height; + + var dropdown = { + height: this.$dropdown.outerHeight(false) + }; + + var viewport = { + top: $window.scrollTop(), + bottom: $window.scrollTop() + $window.height() + }; + + var enoughRoomAbove = viewport.top < (offset.top - dropdown.height); + var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height); + + var css = { + left: offset.left, + top: container.bottom + }; + + // Determine what the parent element is to use for calculating the offset + var $offsetParent = this.$dropdownParent; + + // For statically positioned elements, we need to get the element + // that is determining the offset + if ($offsetParent.css('position') === 'static') { + $offsetParent = $offsetParent.offsetParent(); + } + + var parentOffset = { + top: 0, + left: 0 + }; + + if ( + $.contains(document.body, $offsetParent[0]) || + $offsetParent[0].isConnected + ) { + parentOffset = $offsetParent.offset(); + } + + css.top -= parentOffset.top; + css.left -= parentOffset.left; + + if (!isCurrentlyAbove && !isCurrentlyBelow) { + newDirection = 'below'; + } + + if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) { + newDirection = 'above'; + } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) { + newDirection = 'below'; + } + + if (newDirection == 'above' || + (isCurrentlyAbove && newDirection !== 'below')) { + css.top = container.top - parentOffset.top - dropdown.height; + } + + if (newDirection != null) { + this.$dropdown + .removeClass('select2-dropdown--below select2-dropdown--above') + .addClass('select2-dropdown--' + newDirection); + this.$container + .removeClass('select2-container--below select2-container--above') + .addClass('select2-container--' + newDirection); + } + + this.$dropdownContainer.css(css); + }; + + AttachBody.prototype._resizeDropdown = function () { + var css = { + width: this.$container.outerWidth(false) + 'px' + }; + + if (this.options.get('dropdownAutoWidth')) { + css.minWidth = css.width; + css.position = 'relative'; + css.width = 'auto'; + } + + this.$dropdown.css(css); + }; + + AttachBody.prototype._showDropdown = function (decorated) { + this.$dropdownContainer.appendTo(this.$dropdownParent); + + this._positionDropdown(); + this._resizeDropdown(); + }; + + return AttachBody; +}); + +S2.define('select2/dropdown/minimumResultsForSearch',[ + +], function () { + function countResults (data) { + var count = 0; + + for (var d = 0; d < data.length; d++) { + var item = data[d]; + + if (item.children) { + count += countResults(item.children); + } else { + count++; + } + } + + return count; + } + + function MinimumResultsForSearch (decorated, $element, options, dataAdapter) { + this.minimumResultsForSearch = options.get('minimumResultsForSearch'); + + if (this.minimumResultsForSearch < 0) { + this.minimumResultsForSearch = Infinity; + } + + decorated.call(this, $element, options, dataAdapter); + } + + MinimumResultsForSearch.prototype.showSearch = function (decorated, params) { + if (countResults(params.data.results) < this.minimumResultsForSearch) { + return false; + } + + return decorated.call(this, params); + }; + + return MinimumResultsForSearch; +}); + +S2.define('select2/dropdown/selectOnClose',[ + '../utils' +], function (Utils) { + function SelectOnClose () { } + + SelectOnClose.prototype.bind = function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + container.on('close', function (params) { + self._handleSelectOnClose(params); + }); + }; + + SelectOnClose.prototype._handleSelectOnClose = function (_, params) { + if (params && params.originalSelect2Event != null) { + var event = params.originalSelect2Event; + + // Don't select an item if the close event was triggered from a select or + // unselect event + if (event._type === 'select' || event._type === 'unselect') { + return; + } + } + + var $highlightedResults = this.getHighlightedResults(); + + // Only select highlighted results + if ($highlightedResults.length < 1) { + return; + } + + var data = Utils.GetData($highlightedResults[0], 'data'); + + // Don't re-select already selected resulte + if ( + (data.element != null && data.element.selected) || + (data.element == null && data.selected) + ) { + return; + } + + this.trigger('select', { + data: data + }); + }; + + return SelectOnClose; +}); + +S2.define('select2/dropdown/closeOnSelect',[ + +], function () { + function CloseOnSelect () { } + + CloseOnSelect.prototype.bind = function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + container.on('select', function (evt) { + self._selectTriggered(evt); + }); + + container.on('unselect', function (evt) { + self._selectTriggered(evt); + }); + }; + + CloseOnSelect.prototype._selectTriggered = function (_, evt) { + var originalEvent = evt.originalEvent; + + // Don't close if the control key is being held + if (originalEvent && (originalEvent.ctrlKey || originalEvent.metaKey)) { + return; + } + + this.trigger('close', { + originalEvent: originalEvent, + originalSelect2Event: evt + }); + }; + + return CloseOnSelect; +}); + +S2.define('select2/i18n/en',[],function () { + // English + return { + errorLoading: function () { + return 'The results could not be loaded.'; + }, + inputTooLong: function (args) { + var overChars = args.input.length - args.maximum; + + var message = 'Please delete ' + overChars + ' character'; + + if (overChars != 1) { + message += 's'; + } + + return message; + }, + inputTooShort: function (args) { + var remainingChars = args.minimum - args.input.length; + + var message = 'Please enter ' + remainingChars + ' or more characters'; + + return message; + }, + loadingMore: function () { + return 'Loading more results…'; + }, + maximumSelected: function (args) { + var message = 'You can only select ' + args.maximum + ' item'; + + if (args.maximum != 1) { + message += 's'; + } + + return message; + }, + noResults: function () { + return 'No results found'; + }, + searching: function () { + return 'Searching…'; + }, + removeAllItems: function () { + return 'Remove all items'; + } + }; +}); + +S2.define('select2/defaults',[ + 'jquery', + 'require', + + './results', + + './selection/single', + './selection/multiple', + './selection/placeholder', + './selection/allowClear', + './selection/search', + './selection/eventRelay', + + './utils', + './translation', + './diacritics', + + './data/select', + './data/array', + './data/ajax', + './data/tags', + './data/tokenizer', + './data/minimumInputLength', + './data/maximumInputLength', + './data/maximumSelectionLength', + + './dropdown', + './dropdown/search', + './dropdown/hidePlaceholder', + './dropdown/infiniteScroll', + './dropdown/attachBody', + './dropdown/minimumResultsForSearch', + './dropdown/selectOnClose', + './dropdown/closeOnSelect', + + './i18n/en' +], function ($, require, + + ResultsList, + + SingleSelection, MultipleSelection, Placeholder, AllowClear, + SelectionSearch, EventRelay, + + Utils, Translation, DIACRITICS, + + SelectData, ArrayData, AjaxData, Tags, Tokenizer, + MinimumInputLength, MaximumInputLength, MaximumSelectionLength, + + Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll, + AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect, + + EnglishTranslation) { + function Defaults () { + this.reset(); + } + + Defaults.prototype.apply = function (options) { + options = $.extend(true, {}, this.defaults, options); + + if (options.dataAdapter == null) { + if (options.ajax != null) { + options.dataAdapter = AjaxData; + } else if (options.data != null) { + options.dataAdapter = ArrayData; + } else { + options.dataAdapter = SelectData; + } + + if (options.minimumInputLength > 0) { + options.dataAdapter = Utils.Decorate( + options.dataAdapter, + MinimumInputLength + ); + } + + if (options.maximumInputLength > 0) { + options.dataAdapter = Utils.Decorate( + options.dataAdapter, + MaximumInputLength + ); + } + + if (options.maximumSelectionLength > 0) { + options.dataAdapter = Utils.Decorate( + options.dataAdapter, + MaximumSelectionLength + ); + } + + if (options.tags) { + options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags); + } + + if (options.tokenSeparators != null || options.tokenizer != null) { + options.dataAdapter = Utils.Decorate( + options.dataAdapter, + Tokenizer + ); + } + + if (options.query != null) { + var Query = require(options.amdBase + 'compat/query'); + + options.dataAdapter = Utils.Decorate( + options.dataAdapter, + Query + ); + } + + if (options.initSelection != null) { + var InitSelection = require(options.amdBase + 'compat/initSelection'); + + options.dataAdapter = Utils.Decorate( + options.dataAdapter, + InitSelection + ); + } + } + + if (options.resultsAdapter == null) { + options.resultsAdapter = ResultsList; + + if (options.ajax != null) { + options.resultsAdapter = Utils.Decorate( + options.resultsAdapter, + InfiniteScroll + ); + } + + if (options.placeholder != null) { + options.resultsAdapter = Utils.Decorate( + options.resultsAdapter, + HidePlaceholder + ); + } + + if (options.selectOnClose) { + options.resultsAdapter = Utils.Decorate( + options.resultsAdapter, + SelectOnClose + ); + } + } + + if (options.dropdownAdapter == null) { + if (options.multiple) { + options.dropdownAdapter = Dropdown; + } else { + var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch); + + options.dropdownAdapter = SearchableDropdown; + } + + if (options.minimumResultsForSearch !== 0) { + options.dropdownAdapter = Utils.Decorate( + options.dropdownAdapter, + MinimumResultsForSearch + ); + } + + if (options.closeOnSelect) { + options.dropdownAdapter = Utils.Decorate( + options.dropdownAdapter, + CloseOnSelect + ); + } + + if ( + options.dropdownCssClass != null || + options.dropdownCss != null || + options.adaptDropdownCssClass != null + ) { + var DropdownCSS = require(options.amdBase + 'compat/dropdownCss'); + + options.dropdownAdapter = Utils.Decorate( + options.dropdownAdapter, + DropdownCSS + ); + } + + options.dropdownAdapter = Utils.Decorate( + options.dropdownAdapter, + AttachBody + ); + } + + if (options.selectionAdapter == null) { + if (options.multiple) { + options.selectionAdapter = MultipleSelection; + } else { + options.selectionAdapter = SingleSelection; + } + + // Add the placeholder mixin if a placeholder was specified + if (options.placeholder != null) { + options.selectionAdapter = Utils.Decorate( + options.selectionAdapter, + Placeholder + ); + } + + if (options.allowClear) { + options.selectionAdapter = Utils.Decorate( + options.selectionAdapter, + AllowClear + ); + } + + if (options.multiple) { + options.selectionAdapter = Utils.Decorate( + options.selectionAdapter, + SelectionSearch + ); + } + + if ( + options.containerCssClass != null || + options.containerCss != null || + options.adaptContainerCssClass != null + ) { + var ContainerCSS = require(options.amdBase + 'compat/containerCss'); + + options.selectionAdapter = Utils.Decorate( + options.selectionAdapter, + ContainerCSS + ); + } + + options.selectionAdapter = Utils.Decorate( + options.selectionAdapter, + EventRelay + ); + } + + // If the defaults were not previously applied from an element, it is + // possible for the language option to have not been resolved + options.language = this._resolveLanguage(options.language); + + // Always fall back to English since it will always be complete + options.language.push('en'); + + var uniqueLanguages = []; + + for (var l = 0; l < options.language.length; l++) { + var language = options.language[l]; + + if (uniqueLanguages.indexOf(language) === -1) { + uniqueLanguages.push(language); + } + } + + options.language = uniqueLanguages; + + options.translations = this._processTranslations( + options.language, + options.debug + ); + + return options; + }; + + Defaults.prototype.reset = function () { + function stripDiacritics (text) { + // Used 'uni range + named function' from http://jsperf.com/diacritics/18 + function match(a) { + return DIACRITICS[a] || a; + } + + return text.replace(/[^\u0000-\u007E]/g, match); + } + + function matcher (params, data) { + // Always return the object if there is nothing to compare + if ($.trim(params.term) === '') { + return data; + } + + // Do a recursive check for options with children + if (data.children && data.children.length > 0) { + // Clone the data object if there are children + // This is required as we modify the object to remove any non-matches + var match = $.extend(true, {}, data); + + // Check each child of the option + for (var c = data.children.length - 1; c >= 0; c--) { + var child = data.children[c]; + + var matches = matcher(params, child); + + // If there wasn't a match, remove the object in the array + if (matches == null) { + match.children.splice(c, 1); + } + } + + // If any children matched, return the new object + if (match.children.length > 0) { + return match; + } + + // If there were no matching children, check just the plain object + return matcher(params, match); + } + + var original = stripDiacritics(data.text).toUpperCase(); + var term = stripDiacritics(params.term).toUpperCase(); + + // Check if the text contains the term + if (original.indexOf(term) > -1) { + return data; + } + + // If it doesn't contain the term, don't return anything + return null; + } + + this.defaults = { + amdBase: './', + amdLanguageBase: './i18n/', + closeOnSelect: true, + debug: false, + dropdownAutoWidth: false, + escapeMarkup: Utils.escapeMarkup, + language: {}, + matcher: matcher, + minimumInputLength: 0, + maximumInputLength: 0, + maximumSelectionLength: 0, + minimumResultsForSearch: 0, + selectOnClose: false, + scrollAfterSelect: false, + sorter: function (data) { + return data; + }, + templateResult: function (result) { + return result.text; + }, + templateSelection: function (selection) { + return selection.text; + }, + theme: 'default', + width: 'resolve' + }; + }; + + Defaults.prototype.applyFromElement = function (options, $element) { + var optionLanguage = options.language; + var defaultLanguage = this.defaults.language; + var elementLanguage = $element.prop('lang'); + var parentLanguage = $element.closest('[lang]').prop('lang'); + + var languages = Array.prototype.concat.call( + this._resolveLanguage(elementLanguage), + this._resolveLanguage(optionLanguage), + this._resolveLanguage(defaultLanguage), + this._resolveLanguage(parentLanguage) + ); + + options.language = languages; + + return options; + }; + + Defaults.prototype._resolveLanguage = function (language) { + if (!language) { + return []; + } + + if ($.isEmptyObject(language)) { + return []; + } + + if ($.isPlainObject(language)) { + return [language]; + } + + var languages; + + if (!$.isArray(language)) { + languages = [language]; + } else { + languages = language; + } + + var resolvedLanguages = []; + + for (var l = 0; l < languages.length; l++) { + resolvedLanguages.push(languages[l]); + + if (typeof languages[l] === 'string' && languages[l].indexOf('-') > 0) { + // Extract the region information if it is included + var languageParts = languages[l].split('-'); + var baseLanguage = languageParts[0]; + + resolvedLanguages.push(baseLanguage); + } + } + + return resolvedLanguages; + }; + + Defaults.prototype._processTranslations = function (languages, debug) { + var translations = new Translation(); + + for (var l = 0; l < languages.length; l++) { + var languageData = new Translation(); + + var language = languages[l]; + + if (typeof language === 'string') { + try { + // Try to load it with the original name + languageData = Translation.loadPath(language); + } catch (e) { + try { + // If we couldn't load it, check if it wasn't the full path + language = this.defaults.amdLanguageBase + language; + languageData = Translation.loadPath(language); + } catch (ex) { + // The translation could not be loaded at all. Sometimes this is + // because of a configuration problem, other times this can be + // because of how Select2 helps load all possible translation files + if (debug && window.console && console.warn) { + console.warn( + 'Select2: The language file for "' + language + '" could ' + + 'not be automatically loaded. A fallback will be used instead.' + ); + } + } + } + } else if ($.isPlainObject(language)) { + languageData = new Translation(language); + } else { + languageData = language; + } + + translations.extend(languageData); + } + + return translations; + }; + + Defaults.prototype.set = function (key, value) { + var camelKey = $.camelCase(key); + + var data = {}; + data[camelKey] = value; + + var convertedData = Utils._convertData(data); + + $.extend(true, this.defaults, convertedData); + }; + + var defaults = new Defaults(); + + return defaults; +}); + +S2.define('select2/options',[ + 'require', + 'jquery', + './defaults', + './utils' +], function (require, $, Defaults, Utils) { + function Options (options, $element) { + this.options = options; + + if ($element != null) { + this.fromElement($element); + } + + if ($element != null) { + this.options = Defaults.applyFromElement(this.options, $element); + } + + this.options = Defaults.apply(this.options); + + if ($element && $element.is('input')) { + var InputCompat = require(this.get('amdBase') + 'compat/inputData'); + + this.options.dataAdapter = Utils.Decorate( + this.options.dataAdapter, + InputCompat + ); + } + } + + Options.prototype.fromElement = function ($e) { + var excludedData = ['select2']; + + if (this.options.multiple == null) { + this.options.multiple = $e.prop('multiple'); + } + + if (this.options.disabled == null) { + this.options.disabled = $e.prop('disabled'); + } + + if (this.options.dir == null) { + if ($e.prop('dir')) { + this.options.dir = $e.prop('dir'); + } else if ($e.closest('[dir]').prop('dir')) { + this.options.dir = $e.closest('[dir]').prop('dir'); + } else { + this.options.dir = 'ltr'; + } + } + + $e.prop('disabled', this.options.disabled); + $e.prop('multiple', this.options.multiple); + + if (Utils.GetData($e[0], 'select2Tags')) { + if (this.options.debug && window.console && console.warn) { + console.warn( + 'Select2: The `data-select2-tags` attribute has been changed to ' + + 'use the `data-data` and `data-tags="true"` attributes and will be ' + + 'removed in future versions of Select2.' + ); + } + + Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags')); + Utils.StoreData($e[0], 'tags', true); + } + + if (Utils.GetData($e[0], 'ajaxUrl')) { + if (this.options.debug && window.console && console.warn) { + console.warn( + 'Select2: The `data-ajax-url` attribute has been changed to ' + + '`data-ajax--url` and support for the old attribute will be removed' + + ' in future versions of Select2.' + ); + } + + $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl')); + Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl')); + } + + var dataset = {}; + + function upperCaseLetter(_, letter) { + return letter.toUpperCase(); + } + + // Pre-load all of the attributes which are prefixed with `data-` + for (var attr = 0; attr < $e[0].attributes.length; attr++) { + var attributeName = $e[0].attributes[attr].name; + var prefix = 'data-'; + + if (attributeName.substr(0, prefix.length) == prefix) { + // Get the contents of the attribute after `data-` + var dataName = attributeName.substring(prefix.length); + + // Get the data contents from the consistent source + // This is more than likely the jQuery data helper + var dataValue = Utils.GetData($e[0], dataName); + + // camelCase the attribute name to match the spec + var camelDataName = dataName.replace(/-([a-z])/g, upperCaseLetter); + + // Store the data attribute contents into the dataset since + dataset[camelDataName] = dataValue; + } + } + + // Prefer the element's `dataset` attribute if it exists + // jQuery 1.x does not correctly handle data attributes with multiple dashes + if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) { + dataset = $.extend(true, {}, $e[0].dataset, dataset); + } + + // Prefer our internal data cache if it exists + var data = $.extend(true, {}, Utils.GetData($e[0]), dataset); + + data = Utils._convertData(data); + + for (var key in data) { + if ($.inArray(key, excludedData) > -1) { + continue; + } + + if ($.isPlainObject(this.options[key])) { + $.extend(this.options[key], data[key]); + } else { + this.options[key] = data[key]; + } + } + + return this; + }; + + Options.prototype.get = function (key) { + return this.options[key]; + }; + + Options.prototype.set = function (key, val) { + this.options[key] = val; + }; + + return Options; +}); + +S2.define('select2/core',[ + 'jquery', + './options', + './utils', + './keys' +], function ($, Options, Utils, KEYS) { + var Select2 = function ($element, options) { + if (Utils.GetData($element[0], 'select2') != null) { + Utils.GetData($element[0], 'select2').destroy(); + } + + this.$element = $element; + + this.id = this._generateId($element); + + options = options || {}; + + this.options = new Options(options, $element); + + Select2.__super__.constructor.call(this); + + // Set up the tabindex + + var tabindex = $element.attr('tabindex') || 0; + Utils.StoreData($element[0], 'old-tabindex', tabindex); + $element.attr('tabindex', '-1'); + + // Set up containers and adapters + + var DataAdapter = this.options.get('dataAdapter'); + this.dataAdapter = new DataAdapter($element, this.options); + + var $container = this.render(); + + this._placeContainer($container); + + var SelectionAdapter = this.options.get('selectionAdapter'); + this.selection = new SelectionAdapter($element, this.options); + this.$selection = this.selection.render(); + + this.selection.position(this.$selection, $container); + + var DropdownAdapter = this.options.get('dropdownAdapter'); + this.dropdown = new DropdownAdapter($element, this.options); + this.$dropdown = this.dropdown.render(); + + this.dropdown.position(this.$dropdown, $container); + + var ResultsAdapter = this.options.get('resultsAdapter'); + this.results = new ResultsAdapter($element, this.options, this.dataAdapter); + this.$results = this.results.render(); + + this.results.position(this.$results, this.$dropdown); + + // Bind events + + var self = this; + + // Bind the container to all of the adapters + this._bindAdapters(); + + // Register any DOM event handlers + this._registerDomEvents(); + + // Register any internal event handlers + this._registerDataEvents(); + this._registerSelectionEvents(); + this._registerDropdownEvents(); + this._registerResultsEvents(); + this._registerEvents(); + + // Set the initial state + this.dataAdapter.current(function (initialData) { + self.trigger('selection:update', { + data: initialData + }); + }); + + // Hide the original select + $element.addClass('select2-hidden-accessible'); + $element.attr('aria-hidden', 'true'); + + // Synchronize any monitored attributes + this._syncAttributes(); + + Utils.StoreData($element[0], 'select2', this); + + // Ensure backwards compatibility with $element.data('select2'). + $element.data('select2', this); + }; + + Utils.Extend(Select2, Utils.Observable); + + Select2.prototype._generateId = function ($element) { + var id = ''; + + if ($element.attr('id') != null) { + id = $element.attr('id'); + } else if ($element.attr('name') != null) { + id = $element.attr('name') + '-' + Utils.generateChars(2); + } else { + id = Utils.generateChars(4); + } + + id = id.replace(/(:|\.|\[|\]|,)/g, ''); + id = 'select2-' + id; + + return id; + }; + + Select2.prototype._placeContainer = function ($container) { + $container.insertAfter(this.$element); + + var width = this._resolveWidth(this.$element, this.options.get('width')); + + if (width != null) { + $container.css('width', width); + } + }; + + Select2.prototype._resolveWidth = function ($element, method) { + var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i; + + if (method == 'resolve') { + var styleWidth = this._resolveWidth($element, 'style'); + + if (styleWidth != null) { + return styleWidth; + } + + return this._resolveWidth($element, 'element'); + } + + if (method == 'element') { + var elementWidth = $element.outerWidth(false); + + if (elementWidth <= 0) { + return 'auto'; + } + + return elementWidth + 'px'; + } + + if (method == 'style') { + var style = $element.attr('style'); + + if (typeof(style) !== 'string') { + return null; + } + + var attrs = style.split(';'); + + for (var i = 0, l = attrs.length; i < l; i = i + 1) { + var attr = attrs[i].replace(/\s/g, ''); + var matches = attr.match(WIDTH); + + if (matches !== null && matches.length >= 1) { + return matches[1]; + } + } + + return null; + } + + if (method == 'computedstyle') { + var computedStyle = window.getComputedStyle($element[0]); + + return computedStyle.width; + } + + return method; + }; + + Select2.prototype._bindAdapters = function () { + this.dataAdapter.bind(this, this.$container); + this.selection.bind(this, this.$container); + + this.dropdown.bind(this, this.$container); + this.results.bind(this, this.$container); + }; + + Select2.prototype._registerDomEvents = function () { + var self = this; + + this.$element.on('change.select2', function () { + self.dataAdapter.current(function (data) { + self.trigger('selection:update', { + data: data + }); + }); + }); + + this.$element.on('focus.select2', function (evt) { + self.trigger('focus', evt); + }); + + this._syncA = Utils.bind(this._syncAttributes, this); + this._syncS = Utils.bind(this._syncSubtree, this); + + if (this.$element[0].attachEvent) { + this.$element[0].attachEvent('onpropertychange', this._syncA); + } + + var observer = window.MutationObserver || + window.WebKitMutationObserver || + window.MozMutationObserver + ; + + if (observer != null) { + this._observer = new observer(function (mutations) { + self._syncA(); + self._syncS(null, mutations); + }); + this._observer.observe(this.$element[0], { + attributes: true, + childList: true, + subtree: false + }); + } else if (this.$element[0].addEventListener) { + this.$element[0].addEventListener( + 'DOMAttrModified', + self._syncA, + false + ); + this.$element[0].addEventListener( + 'DOMNodeInserted', + self._syncS, + false + ); + this.$element[0].addEventListener( + 'DOMNodeRemoved', + self._syncS, + false + ); + } + }; + + Select2.prototype._registerDataEvents = function () { + var self = this; + + this.dataAdapter.on('*', function (name, params) { + self.trigger(name, params); + }); + }; + + Select2.prototype._registerSelectionEvents = function () { + var self = this; + var nonRelayEvents = ['toggle', 'focus']; + + this.selection.on('toggle', function () { + self.toggleDropdown(); + }); + + this.selection.on('focus', function (params) { + self.focus(params); + }); + + this.selection.on('*', function (name, params) { + if ($.inArray(name, nonRelayEvents) !== -1) { + return; + } + + self.trigger(name, params); + }); + }; + + Select2.prototype._registerDropdownEvents = function () { + var self = this; + + this.dropdown.on('*', function (name, params) { + self.trigger(name, params); + }); + }; + + Select2.prototype._registerResultsEvents = function () { + var self = this; + + this.results.on('*', function (name, params) { + self.trigger(name, params); + }); + }; + + Select2.prototype._registerEvents = function () { + var self = this; + + this.on('open', function () { + self.$container.addClass('select2-container--open'); + }); + + this.on('close', function () { + self.$container.removeClass('select2-container--open'); + }); + + this.on('enable', function () { + self.$container.removeClass('select2-container--disabled'); + }); + + this.on('disable', function () { + self.$container.addClass('select2-container--disabled'); + }); + + this.on('blur', function () { + self.$container.removeClass('select2-container--focus'); + }); + + this.on('query', function (params) { + if (!self.isOpen()) { + self.trigger('open', {}); + } + + this.dataAdapter.query(params, function (data) { + self.trigger('results:all', { + data: data, + query: params + }); + }); + }); + + this.on('query:append', function (params) { + this.dataAdapter.query(params, function (data) { + self.trigger('results:append', { + data: data, + query: params + }); + }); + }); + + this.on('keypress', function (evt) { + var key = evt.which; + + if (self.isOpen()) { + if (key === KEYS.ESC || key === KEYS.TAB || + (key === KEYS.UP && evt.altKey)) { + self.close(evt); + + evt.preventDefault(); + } else if (key === KEYS.ENTER) { + self.trigger('results:select', {}); + + evt.preventDefault(); + } else if ((key === KEYS.SPACE && evt.ctrlKey)) { + self.trigger('results:toggle', {}); + + evt.preventDefault(); + } else if (key === KEYS.UP) { + self.trigger('results:previous', {}); + + evt.preventDefault(); + } else if (key === KEYS.DOWN) { + self.trigger('results:next', {}); + + evt.preventDefault(); + } + } else { + if (key === KEYS.ENTER || key === KEYS.SPACE || + (key === KEYS.DOWN && evt.altKey)) { + self.open(); + + evt.preventDefault(); + } + } + }); + }; + + Select2.prototype._syncAttributes = function () { + this.options.set('disabled', this.$element.prop('disabled')); + + if (this.isDisabled()) { + if (this.isOpen()) { + this.close(); + } + + this.trigger('disable', {}); + } else { + this.trigger('enable', {}); + } + }; + + Select2.prototype._isChangeMutation = function (evt, mutations) { + var changed = false; + var self = this; + + // Ignore any mutation events raised for elements that aren't options or + // optgroups. This handles the case when the select element is destroyed + if ( + evt && evt.target && ( + evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP' + ) + ) { + return; + } + + if (!mutations) { + // If mutation events aren't supported, then we can only assume that the + // change affected the selections + changed = true; + } else if (mutations.addedNodes && mutations.addedNodes.length > 0) { + for (var n = 0; n < mutations.addedNodes.length; n++) { + var node = mutations.addedNodes[n]; + + if (node.selected) { + changed = true; + } + } + } else if (mutations.removedNodes && mutations.removedNodes.length > 0) { + changed = true; + } else if ($.isArray(mutations)) { + $.each(mutations, function(evt, mutation) { + if (self._isChangeMutation(evt, mutation)) { + // We've found a change mutation. + // Let's escape from the loop and continue + changed = true; + return false; + } + }); + } + return changed; + }; + + Select2.prototype._syncSubtree = function (evt, mutations) { + var changed = this._isChangeMutation(evt, mutations); + var self = this; + + // Only re-pull the data if we think there is a change + if (changed) { + this.dataAdapter.current(function (currentData) { + self.trigger('selection:update', { + data: currentData + }); + }); + } + }; + + /** + * Override the trigger method to automatically trigger pre-events when + * there are events that can be prevented. + */ + Select2.prototype.trigger = function (name, args) { + var actualTrigger = Select2.__super__.trigger; + var preTriggerMap = { + 'open': 'opening', + 'close': 'closing', + 'select': 'selecting', + 'unselect': 'unselecting', + 'clear': 'clearing' + }; + + if (args === undefined) { + args = {}; + } + + if (name in preTriggerMap) { + var preTriggerName = preTriggerMap[name]; + var preTriggerArgs = { + prevented: false, + name: name, + args: args + }; + + actualTrigger.call(this, preTriggerName, preTriggerArgs); + + if (preTriggerArgs.prevented) { + args.prevented = true; + + return; + } + } + + actualTrigger.call(this, name, args); + }; + + Select2.prototype.toggleDropdown = function () { + if (this.isDisabled()) { + return; + } + + if (this.isOpen()) { + this.close(); + } else { + this.open(); + } + }; + + Select2.prototype.open = function () { + if (this.isOpen()) { + return; + } + + if (this.isDisabled()) { + return; + } + + this.trigger('query', {}); + }; + + Select2.prototype.close = function (evt) { + if (!this.isOpen()) { + return; + } + + this.trigger('close', { originalEvent : evt }); + }; + + /** + * Helper method to abstract the "enabled" (not "disabled") state of this + * object. + * + * @return {true} if the instance is not disabled. + * @return {false} if the instance is disabled. + */ + Select2.prototype.isEnabled = function () { + return !this.isDisabled(); + }; + + /** + * Helper method to abstract the "disabled" state of this object. + * + * @return {true} if the disabled option is true. + * @return {false} if the disabled option is false. + */ + Select2.prototype.isDisabled = function () { + return this.options.get('disabled'); + }; + + Select2.prototype.isOpen = function () { + return this.$container.hasClass('select2-container--open'); + }; + + Select2.prototype.hasFocus = function () { + return this.$container.hasClass('select2-container--focus'); + }; + + Select2.prototype.focus = function (data) { + // No need to re-trigger focus events if we are already focused + if (this.hasFocus()) { + return; + } + + this.$container.addClass('select2-container--focus'); + this.trigger('focus', {}); + }; + + Select2.prototype.enable = function (args) { + if (this.options.get('debug') && window.console && console.warn) { + console.warn( + 'Select2: The `select2("enable")` method has been deprecated and will' + + ' be removed in later Select2 versions. Use $element.prop("disabled")' + + ' instead.' + ); + } + + if (args == null || args.length === 0) { + args = [true]; + } + + var disabled = !args[0]; + + this.$element.prop('disabled', disabled); + }; + + Select2.prototype.data = function () { + if (this.options.get('debug') && + arguments.length > 0 && window.console && console.warn) { + console.warn( + 'Select2: Data can no longer be set using `select2("data")`. You ' + + 'should consider setting the value instead using `$element.val()`.' + ); + } + + var data = []; + + this.dataAdapter.current(function (currentData) { + data = currentData; + }); + + return data; + }; + + Select2.prototype.val = function (args) { + if (this.options.get('debug') && window.console && console.warn) { + console.warn( + 'Select2: The `select2("val")` method has been deprecated and will be' + + ' removed in later Select2 versions. Use $element.val() instead.' + ); + } + + if (args == null || args.length === 0) { + return this.$element.val(); + } + + var newVal = args[0]; + + if ($.isArray(newVal)) { + newVal = $.map(newVal, function (obj) { + return obj.toString(); + }); + } + + this.$element.val(newVal).trigger('input').trigger('change'); + }; + + Select2.prototype.destroy = function () { + this.$container.remove(); + + if (this.$element[0].detachEvent) { + this.$element[0].detachEvent('onpropertychange', this._syncA); + } + + if (this._observer != null) { + this._observer.disconnect(); + this._observer = null; + } else if (this.$element[0].removeEventListener) { + this.$element[0] + .removeEventListener('DOMAttrModified', this._syncA, false); + this.$element[0] + .removeEventListener('DOMNodeInserted', this._syncS, false); + this.$element[0] + .removeEventListener('DOMNodeRemoved', this._syncS, false); + } + + this._syncA = null; + this._syncS = null; + + this.$element.off('.select2'); + this.$element.attr('tabindex', + Utils.GetData(this.$element[0], 'old-tabindex')); + + this.$element.removeClass('select2-hidden-accessible'); + this.$element.attr('aria-hidden', 'false'); + Utils.RemoveData(this.$element[0]); + this.$element.removeData('select2'); + + this.dataAdapter.destroy(); + this.selection.destroy(); + this.dropdown.destroy(); + this.results.destroy(); + + this.dataAdapter = null; + this.selection = null; + this.dropdown = null; + this.results = null; + }; + + Select2.prototype.render = function () { + var $container = $( + '' + + '' + + '' + + '' + ); + + $container.attr('dir', this.options.get('dir')); + + this.$container = $container; + + this.$container.addClass('select2-container--' + this.options.get('theme')); + + Utils.StoreData($container[0], 'element', this.$element); + + return $container; + }; + + return Select2; +}); + +S2.define('jquery-mousewheel',[ + 'jquery' +], function ($) { + // Used to shim jQuery.mousewheel for non-full builds. + return $; +}); + +S2.define('jquery.select2',[ + 'jquery', + 'jquery-mousewheel', + + './select2/core', + './select2/defaults', + './select2/utils' +], function ($, _, Select2, Defaults, Utils) { + if ($.fn.select2 == null) { + // All methods that should return the element + var thisMethods = ['open', 'close', 'destroy']; + + $.fn.select2 = function (options) { + options = options || {}; + + if (typeof options === 'object') { + this.each(function () { + var instanceOptions = $.extend(true, {}, options); + + var instance = new Select2($(this), instanceOptions); + }); + + return this; + } else if (typeof options === 'string') { + var ret; + var args = Array.prototype.slice.call(arguments, 1); + + this.each(function () { + var instance = Utils.GetData(this, 'select2'); + + if (instance == null && window.console && console.error) { + console.error( + 'The select2(\'' + options + '\') method was called on an ' + + 'element that is not using Select2.' + ); + } + + ret = instance[options].apply(instance, args); + }); + + // Check if we should be returning `this` + if ($.inArray(options, thisMethods) > -1) { + return this; + } + + return ret; + } else { + throw new Error('Invalid arguments for Select2: ' + options); + } + }; + } + + if ($.fn.select2.defaults == null) { + $.fn.select2.defaults = Defaults; + } + + return Select2; +}); + + // Return the AMD loader configuration so it can be used outside of this file + return { + define: S2.define, + require: S2.require + }; +}()); + + // Autoload the jQuery bindings + // We know that all of the modules exist above this, so we're safe + var select2 = S2.require('jquery.select2'); + + // Hold the AMD module references on the jQuery function that was just loaded + // This allows Select2 to use the internal loader outside of this file, such + // as in the language files. + jQuery.fn.select2.amd = S2; + + // Return the Select2 instance for anyone who is importing it. + return select2; +})); diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/select2.min.js b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/select2.min.js new file mode 100755 index 00000000..e4214264 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/select2.min.js @@ -0,0 +1,2 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ +!function(n){"function"==typeof define&&define.amd?define(["jquery"],n):"object"==typeof module&&module.exports?module.exports=function(e,t){return void 0===t&&(t="undefined"!=typeof window?require("jquery"):require("jquery")(e)),n(t),t}:n(jQuery)}(function(u){var e=function(){if(u&&u.fn&&u.fn.select2&&u.fn.select2.amd)var e=u.fn.select2.amd;var t,n,r,h,o,s,f,g,m,v,y,_,i,a,b;function w(e,t){return i.call(e,t)}function l(e,t){var n,r,i,o,s,a,l,c,u,d,p,h=t&&t.split("/"),f=y.map,g=f&&f["*"]||{};if(e){for(s=(e=e.split("/")).length-1,y.nodeIdCompat&&b.test(e[s])&&(e[s]=e[s].replace(b,"")),"."===e[0].charAt(0)&&h&&(e=h.slice(0,h.length-1).concat(e)),u=0;u":">",'"':""","'":"'","/":"/"};return"string"!=typeof e?e:String(e).replace(/[&<>"'\/\\]/g,function(e){return t[e]})},i.appendMany=function(e,t){if("1.7"===o.fn.jquery.substr(0,3)){var n=o();o.map(t,function(e){n=n.add(e)}),t=n}e.append(t)},i.__cache={};var n=0;return i.GetUniqueElementId=function(e){var t=e.getAttribute("data-select2-id");return null==t&&(e.id?(t=e.id,e.setAttribute("data-select2-id",t)):(e.setAttribute("data-select2-id",++n),t=n.toString())),t},i.StoreData=function(e,t,n){var r=i.GetUniqueElementId(e);i.__cache[r]||(i.__cache[r]={}),i.__cache[r][t]=n},i.GetData=function(e,t){var n=i.GetUniqueElementId(e);return t?i.__cache[n]&&null!=i.__cache[n][t]?i.__cache[n][t]:o(e).data(t):i.__cache[n]},i.RemoveData=function(e){var t=i.GetUniqueElementId(e);null!=i.__cache[t]&&delete i.__cache[t],e.removeAttribute("data-select2-id")},i}),e.define("select2/results",["jquery","./utils"],function(h,f){function r(e,t,n){this.$element=e,this.data=n,this.options=t,r.__super__.constructor.call(this)}return f.Extend(r,f.Observable),r.prototype.render=function(){var e=h('
          ');return this.options.get("multiple")&&e.attr("aria-multiselectable","true"),this.$results=e},r.prototype.clear=function(){this.$results.empty()},r.prototype.displayMessage=function(e){var t=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var n=h(''),r=this.options.get("translations").get(e.message);n.append(t(r(e.args))),n[0].className+=" select2-results__message",this.$results.append(n)},r.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},r.prototype.append=function(e){this.hideLoading();var t=[];if(null!=e.results&&0!==e.results.length){e.results=this.sort(e.results);for(var n=0;n",{class:"select2-results__options select2-results__options--nested"});p.append(l),s.append(a),s.append(p)}else this.template(e,t);return f.StoreData(t,"data",e),t},r.prototype.bind=function(t,e){var l=this,n=t.id+"-results";this.$results.attr("id",n),t.on("results:all",function(e){l.clear(),l.append(e.data),t.isOpen()&&(l.setClasses(),l.highlightFirstItem())}),t.on("results:append",function(e){l.append(e.data),t.isOpen()&&l.setClasses()}),t.on("query",function(e){l.hideMessages(),l.showLoading(e)}),t.on("select",function(){t.isOpen()&&(l.setClasses(),l.options.get("scrollAfterSelect")&&l.highlightFirstItem())}),t.on("unselect",function(){t.isOpen()&&(l.setClasses(),l.options.get("scrollAfterSelect")&&l.highlightFirstItem())}),t.on("open",function(){l.$results.attr("aria-expanded","true"),l.$results.attr("aria-hidden","false"),l.setClasses(),l.ensureHighlightVisible()}),t.on("close",function(){l.$results.attr("aria-expanded","false"),l.$results.attr("aria-hidden","true"),l.$results.removeAttr("aria-activedescendant")}),t.on("results:toggle",function(){var e=l.getHighlightedResults();0!==e.length&&e.trigger("mouseup")}),t.on("results:select",function(){var e=l.getHighlightedResults();if(0!==e.length){var t=f.GetData(e[0],"data");"true"==e.attr("aria-selected")?l.trigger("close",{}):l.trigger("select",{data:t})}}),t.on("results:previous",function(){var e=l.getHighlightedResults(),t=l.$results.find("[aria-selected]"),n=t.index(e);if(!(n<=0)){var r=n-1;0===e.length&&(r=0);var i=t.eq(r);i.trigger("mouseenter");var o=l.$results.offset().top,s=i.offset().top,a=l.$results.scrollTop()+(s-o);0===r?l.$results.scrollTop(0):s-o<0&&l.$results.scrollTop(a)}}),t.on("results:next",function(){var e=l.getHighlightedResults(),t=l.$results.find("[aria-selected]"),n=t.index(e)+1;if(!(n>=t.length)){var r=t.eq(n);r.trigger("mouseenter");var i=l.$results.offset().top+l.$results.outerHeight(!1),o=r.offset().top+r.outerHeight(!1),s=l.$results.scrollTop()+o-i;0===n?l.$results.scrollTop(0):ithis.$results.outerHeight()||o<0)&&this.$results.scrollTop(i)}},r.prototype.template=function(e,t){var n=this.options.get("templateResult"),r=this.options.get("escapeMarkup"),i=n(e,t);null==i?t.style.display="none":"string"==typeof i?t.innerHTML=r(i):h(t).append(i)},r}),e.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),e.define("select2/selection/base",["jquery","../utils","../keys"],function(n,r,i){function o(e,t){this.$element=e,this.options=t,o.__super__.constructor.call(this)}return r.Extend(o,r.Observable),o.prototype.render=function(){var e=n('');return this._tabindex=0,null!=r.GetData(this.$element[0],"old-tabindex")?this._tabindex=r.GetData(this.$element[0],"old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),e.attr("title",this.$element.attr("title")),e.attr("tabindex",this._tabindex),e.attr("aria-disabled","false"),this.$selection=e},o.prototype.bind=function(e,t){var n=this,r=e.id+"-results";this.container=e,this.$selection.on("focus",function(e){n.trigger("focus",e)}),this.$selection.on("blur",function(e){n._handleBlur(e)}),this.$selection.on("keydown",function(e){n.trigger("keypress",e),e.which===i.SPACE&&e.preventDefault()}),e.on("results:focus",function(e){n.$selection.attr("aria-activedescendant",e.data._resultId)}),e.on("selection:update",function(e){n.update(e.data)}),e.on("open",function(){n.$selection.attr("aria-expanded","true"),n.$selection.attr("aria-owns",r),n._attachCloseHandler(e)}),e.on("close",function(){n.$selection.attr("aria-expanded","false"),n.$selection.removeAttr("aria-activedescendant"),n.$selection.removeAttr("aria-owns"),n.$selection.trigger("focus"),n._detachCloseHandler(e)}),e.on("enable",function(){n.$selection.attr("tabindex",n._tabindex),n.$selection.attr("aria-disabled","false")}),e.on("disable",function(){n.$selection.attr("tabindex","-1"),n.$selection.attr("aria-disabled","true")})},o.prototype._handleBlur=function(e){var t=this;window.setTimeout(function(){document.activeElement==t.$selection[0]||n.contains(t.$selection[0],document.activeElement)||t.trigger("blur",e)},1)},o.prototype._attachCloseHandler=function(e){n(document.body).on("mousedown.select2."+e.id,function(e){var t=n(e.target).closest(".select2");n(".select2.select2-container--open").each(function(){this!=t[0]&&r.GetData(this,"element").select2("close")})})},o.prototype._detachCloseHandler=function(e){n(document.body).off("mousedown.select2."+e.id)},o.prototype.position=function(e,t){t.find(".selection").append(e)},o.prototype.destroy=function(){this._detachCloseHandler(this.container)},o.prototype.update=function(e){throw new Error("The `update` method must be defined in child classes.")},o.prototype.isEnabled=function(){return!this.isDisabled()},o.prototype.isDisabled=function(){return this.options.get("disabled")},o}),e.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(e,t,n,r){function i(){i.__super__.constructor.apply(this,arguments)}return n.Extend(i,t),i.prototype.render=function(){var e=i.__super__.render.call(this);return e.addClass("select2-selection--single"),e.html(''),e},i.prototype.bind=function(t,e){var n=this;i.__super__.bind.apply(this,arguments);var r=t.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",r).attr("role","textbox").attr("aria-readonly","true"),this.$selection.attr("aria-labelledby",r),this.$selection.on("mousedown",function(e){1===e.which&&n.trigger("toggle",{originalEvent:e})}),this.$selection.on("focus",function(e){}),this.$selection.on("blur",function(e){}),t.on("focus",function(e){t.isOpen()||n.$selection.trigger("focus")})},i.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},i.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},i.prototype.selectionContainer=function(){return e("")},i.prototype.update=function(e){if(0!==e.length){var t=e[0],n=this.$selection.find(".select2-selection__rendered"),r=this.display(t,n);n.empty().append(r);var i=t.title||t.text;i?n.attr("title",i):n.removeAttr("title")}else this.clear()},i}),e.define("select2/selection/multiple",["jquery","./base","../utils"],function(i,e,l){function n(e,t){n.__super__.constructor.apply(this,arguments)}return l.Extend(n,e),n.prototype.render=function(){var e=n.__super__.render.call(this);return e.addClass("select2-selection--multiple"),e.html('
            '),e},n.prototype.bind=function(e,t){var r=this;n.__super__.bind.apply(this,arguments),this.$selection.on("click",function(e){r.trigger("toggle",{originalEvent:e})}),this.$selection.on("click",".select2-selection__choice__remove",function(e){if(!r.isDisabled()){var t=i(this).parent(),n=l.GetData(t[0],"data");r.trigger("unselect",{originalEvent:e,data:n})}})},n.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},n.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},n.prototype.selectionContainer=function(){return i('
          • ×
          • ')},n.prototype.update=function(e){if(this.clear(),0!==e.length){for(var t=[],n=0;n×');a.StoreData(r[0],"data",t),this.$selection.find(".select2-selection__rendered").prepend(r)}},e}),e.define("select2/selection/search",["jquery","../utils","../keys"],function(r,a,l){function e(e,t,n){e.call(this,t,n)}return e.prototype.render=function(e){var t=r('');this.$searchContainer=t,this.$search=t.find("input");var n=e.call(this);return this._transferTabIndex(),n},e.prototype.bind=function(e,t,n){var r=this,i=t.id+"-results";e.call(this,t,n),t.on("open",function(){r.$search.attr("aria-controls",i),r.$search.trigger("focus")}),t.on("close",function(){r.$search.val(""),r.$search.removeAttr("aria-controls"),r.$search.removeAttr("aria-activedescendant"),r.$search.trigger("focus")}),t.on("enable",function(){r.$search.prop("disabled",!1),r._transferTabIndex()}),t.on("disable",function(){r.$search.prop("disabled",!0)}),t.on("focus",function(e){r.$search.trigger("focus")}),t.on("results:focus",function(e){e.data._resultId?r.$search.attr("aria-activedescendant",e.data._resultId):r.$search.removeAttr("aria-activedescendant")}),this.$selection.on("focusin",".select2-search--inline",function(e){r.trigger("focus",e)}),this.$selection.on("focusout",".select2-search--inline",function(e){r._handleBlur(e)}),this.$selection.on("keydown",".select2-search--inline",function(e){if(e.stopPropagation(),r.trigger("keypress",e),r._keyUpPrevented=e.isDefaultPrevented(),e.which===l.BACKSPACE&&""===r.$search.val()){var t=r.$searchContainer.prev(".select2-selection__choice");if(0this.maximumInputLength?this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:t.term,params:t}}):e.call(this,t,n)},e}),e.define("select2/data/maximumSelectionLength",[],function(){function e(e,t,n){this.maximumSelectionLength=n.get("maximumSelectionLength"),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var r=this;e.call(this,t,n),t.on("select",function(){r._checkIfMaximumSelected()})},e.prototype.query=function(e,t,n){var r=this;this._checkIfMaximumSelected(function(){e.call(r,t,n)})},e.prototype._checkIfMaximumSelected=function(e,n){var r=this;this.current(function(e){var t=null!=e?e.length:0;0=r.maximumSelectionLength?r.trigger("results:message",{message:"maximumSelected",args:{maximum:r.maximumSelectionLength}}):n&&n()})},e}),e.define("select2/dropdown",["jquery","./utils"],function(t,e){function n(e,t){this.$element=e,this.options=t,n.__super__.constructor.call(this)}return e.Extend(n,e.Observable),n.prototype.render=function(){var e=t('');return e.attr("dir",this.options.get("dir")),this.$dropdown=e},n.prototype.bind=function(){},n.prototype.position=function(e,t){},n.prototype.destroy=function(){this.$dropdown.remove()},n}),e.define("select2/dropdown/search",["jquery","../utils"],function(o,e){function t(){}return t.prototype.render=function(e){var t=e.call(this),n=o('');return this.$searchContainer=n,this.$search=n.find("input"),t.prepend(n),t},t.prototype.bind=function(e,t,n){var r=this,i=t.id+"-results";e.call(this,t,n),this.$search.on("keydown",function(e){r.trigger("keypress",e),r._keyUpPrevented=e.isDefaultPrevented()}),this.$search.on("input",function(e){o(this).off("keyup")}),this.$search.on("keyup input",function(e){r.handleSearch(e)}),t.on("open",function(){r.$search.attr("tabindex",0),r.$search.attr("aria-controls",i),r.$search.trigger("focus"),window.setTimeout(function(){r.$search.trigger("focus")},0)}),t.on("close",function(){r.$search.attr("tabindex",-1),r.$search.removeAttr("aria-controls"),r.$search.removeAttr("aria-activedescendant"),r.$search.val(""),r.$search.trigger("blur")}),t.on("focus",function(){t.isOpen()||r.$search.trigger("focus")}),t.on("results:all",function(e){null!=e.query.term&&""!==e.query.term||(r.showSearch(e)?r.$searchContainer.removeClass("select2-search--hide"):r.$searchContainer.addClass("select2-search--hide"))}),t.on("results:focus",function(e){e.data._resultId?r.$search.attr("aria-activedescendant",e.data._resultId):r.$search.removeAttr("aria-activedescendant")})},t.prototype.handleSearch=function(e){if(!this._keyUpPrevented){var t=this.$search.val();this.trigger("query",{term:t})}this._keyUpPrevented=!1},t.prototype.showSearch=function(e,t){return!0},t}),e.define("select2/dropdown/hidePlaceholder",[],function(){function e(e,t,n,r){this.placeholder=this.normalizePlaceholder(n.get("placeholder")),e.call(this,t,n,r)}return e.prototype.append=function(e,t){t.results=this.removePlaceholder(t.results),e.call(this,t)},e.prototype.normalizePlaceholder=function(e,t){return"string"==typeof t&&(t={id:"",text:t}),t},e.prototype.removePlaceholder=function(e,t){for(var n=t.slice(0),r=t.length-1;0<=r;r--){var i=t[r];this.placeholder.id===i.id&&n.splice(r,1)}return n},e}),e.define("select2/dropdown/infiniteScroll",["jquery"],function(n){function e(e,t,n,r){this.lastParams={},e.call(this,t,n,r),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return e.prototype.append=function(e,t){this.$loadingMore.remove(),this.loading=!1,e.call(this,t),this.showLoadingMore(t)&&(this.$results.append(this.$loadingMore),this.loadMoreIfNeeded())},e.prototype.bind=function(e,t,n){var r=this;e.call(this,t,n),t.on("query",function(e){r.lastParams=e,r.loading=!0}),t.on("query:append",function(e){r.lastParams=e,r.loading=!0}),this.$results.on("scroll",this.loadMoreIfNeeded.bind(this))},e.prototype.loadMoreIfNeeded=function(){var e=n.contains(document.documentElement,this.$loadingMore[0]);if(!this.loading&&e){var t=this.$results.offset().top+this.$results.outerHeight(!1);this.$loadingMore.offset().top+this.$loadingMore.outerHeight(!1)<=t+50&&this.loadMore()}},e.prototype.loadMore=function(){this.loading=!0;var e=n.extend({},{page:1},this.lastParams);e.page++,this.trigger("query:append",e)},e.prototype.showLoadingMore=function(e,t){return t.pagination&&t.pagination.more},e.prototype.createLoadingMore=function(){var e=n('
          • '),t=this.options.get("translations").get("loadingMore");return e.html(t(this.lastParams)),e},e}),e.define("select2/dropdown/attachBody",["jquery","../utils"],function(f,a){function e(e,t,n){this.$dropdownParent=f(n.get("dropdownParent")||document.body),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var r=this;e.call(this,t,n),t.on("open",function(){r._showDropdown(),r._attachPositioningHandler(t),r._bindContainerResultHandlers(t)}),t.on("close",function(){r._hideDropdown(),r._detachPositioningHandler(t)}),this.$dropdownContainer.on("mousedown",function(e){e.stopPropagation()})},e.prototype.destroy=function(e){e.call(this),this.$dropdownContainer.remove()},e.prototype.position=function(e,t,n){t.attr("class",n.attr("class")),t.removeClass("select2"),t.addClass("select2-container--open"),t.css({position:"absolute",top:-999999}),this.$container=n},e.prototype.render=function(e){var t=f(""),n=e.call(this);return t.append(n),this.$dropdownContainer=t},e.prototype._hideDropdown=function(e){this.$dropdownContainer.detach()},e.prototype._bindContainerResultHandlers=function(e,t){if(!this._containerResultsHandlersBound){var n=this;t.on("results:all",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("results:append",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("results:message",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("select",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("unselect",function(){n._positionDropdown(),n._resizeDropdown()}),this._containerResultsHandlersBound=!0}},e.prototype._attachPositioningHandler=function(e,t){var n=this,r="scroll.select2."+t.id,i="resize.select2."+t.id,o="orientationchange.select2."+t.id,s=this.$container.parents().filter(a.hasScroll);s.each(function(){a.StoreData(this,"select2-scroll-position",{x:f(this).scrollLeft(),y:f(this).scrollTop()})}),s.on(r,function(e){var t=a.GetData(this,"select2-scroll-position");f(this).scrollTop(t.y)}),f(window).on(r+" "+i+" "+o,function(e){n._positionDropdown(),n._resizeDropdown()})},e.prototype._detachPositioningHandler=function(e,t){var n="scroll.select2."+t.id,r="resize.select2."+t.id,i="orientationchange.select2."+t.id;this.$container.parents().filter(a.hasScroll).off(n),f(window).off(n+" "+r+" "+i)},e.prototype._positionDropdown=function(){var e=f(window),t=this.$dropdown.hasClass("select2-dropdown--above"),n=this.$dropdown.hasClass("select2-dropdown--below"),r=null,i=this.$container.offset();i.bottom=i.top+this.$container.outerHeight(!1);var o={height:this.$container.outerHeight(!1)};o.top=i.top,o.bottom=i.top+o.height;var s=this.$dropdown.outerHeight(!1),a=e.scrollTop(),l=e.scrollTop()+e.height(),c=ai.bottom+s,d={left:i.left,top:o.bottom},p=this.$dropdownParent;"static"===p.css("position")&&(p=p.offsetParent());var h={top:0,left:0};(f.contains(document.body,p[0])||p[0].isConnected)&&(h=p.offset()),d.top-=h.top,d.left-=h.left,t||n||(r="below"),u||!c||t?!c&&u&&t&&(r="below"):r="above",("above"==r||t&&"below"!==r)&&(d.top=o.top-h.top-s),null!=r&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+r),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+r)),this.$dropdownContainer.css(d)},e.prototype._resizeDropdown=function(){var e={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(e.minWidth=e.width,e.position="relative",e.width="auto"),this.$dropdown.css(e)},e.prototype._showDropdown=function(e){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},e}),e.define("select2/dropdown/minimumResultsForSearch",[],function(){function e(e,t,n,r){this.minimumResultsForSearch=n.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),e.call(this,t,n,r)}return e.prototype.showSearch=function(e,t){return!(function e(t){for(var n=0,r=0;r');return e.attr("dir",this.options.get("dir")),this.$container=e,this.$container.addClass("select2-container--"+this.options.get("theme")),u.StoreData(e[0],"element",this.$element),e},d}),e.define("jquery-mousewheel",["jquery"],function(e){return e}),e.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults","./select2/utils"],function(i,e,o,t,s){if(null==i.fn.select2){var a=["open","close","destroy"];i.fn.select2=function(t){if("object"==typeof(t=t||{}))return this.each(function(){var e=i.extend(!0,{},t);new o(i(this),e)}),this;if("string"!=typeof t)throw new Error("Invalid arguments for Select2: "+t);var n,r=Array.prototype.slice.call(arguments,1);return this.each(function(){var e=s.GetData(this,"select2");null==e&&window.console&&console.error&&console.error("The select2('"+t+"') method was called on an element that is not using Select2."),n=e[t].apply(e,r)}),-1simba_tfa = $simba_tfa; + $this->file_path = path_join($this->get_mu_plugin_dir(), 'simba-tfa-encryption-key.php'); + } + + /** + * Returns full path to mu-plugin directory + * + * @return string - the mu-plugin directory path + */ + public function get_mu_plugin_dir() { + return WPMU_PLUGIN_DIR; + } + + /** + * Returns the full path to the mu-plugin file + * + * @return string - the mu-plugin path + */ + public function get_file_path() { + return $this->file_path; + } + + /** + * This function checks if our mu-plugin exists + * + * @return boolean - true if the file exists otherwise false + */ + public function muplugin_exists() { + return file_exists($this->file_path); + } + + /** + * Inserts our code into our mu-plugin. + * + * The mu-plugin and the mu-plugin directory will be created if they don't already exists + * + * @return boolean|WP_Error - true on success or WP_Error on failure + */ + public function insert_contents() { + + $info = pathinfo($this->file_path); + + if (!isset($info['dirname'])) { + return new WP_Error( + 'file_no_directory', + /* translators: %s: Multi user plugin directory */ + __('Encrypt secrets feature not enabled: no directory has been set.', 'all-in-one-wp-security-and-firewall') . ' ' . sprintf(__('Please check your %s constant is valid', 'all-in-one-wp-security-and-firewall'), 'WPMU_PLUGIN_DIR'), + $this->file_path + ); + } + + if (false === wp_mkdir_p($info['dirname'])) { + return new WP_Error( + 'file_no_directory_created', + /* translators: %s: Multi user plugin directory */ + sprintf(__('The encrypt secrets feature was not enabled: your mu-plugins directory could not be automatically created; therefore, please use your web hosting file manager or FTP to manually create this folder and then try again: %s', 'all-in-one-wp-security-and-firewall'), $this->get_mu_plugin_dir()), + $info['dirname'] + ); + } + + if (false === @file_put_contents($this->file_path, $this->get_contents())) { // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore this as it is handled by the caller + return new WP_Error( + 'file_no_contents', + /* translators: %s: File path. */ + __('The encrypt secrets feature was not enabled: attempting to write the mu-plugin file contents failed; therefore, please create the file manually.', 'all-in-one-wp-security-and-firewall') . "

            " . sprintf(__('Add the following code to the file %s', 'all-in-one-wp-security-and-firewall'), $this->get_file_path()) . "\n" . '

            ' . nl2br(esc_html($this->get_contents())) . '

            ' . __('Once you have added the above code then press the button to turn on encryption again', 'all-in-one-wp-security-and-firewall'), + $info['dirname'] + ); + } + + return true; + } + + /** + * This function creates the contents for the mu-plugin + * + * @return string - the contents of the mu-plugin + */ + public function get_contents() { + $encryption_key = base64_encode($this->simba_tfa->random_bytes(16)); + $code = "0) { + styling = 'margin-left: 4px; position: relative; top: 4px; width: 20px; height: 20px; border:0px; box-shadow:none;'; + } + $submit_button.after(''); + } + + $.ajax({ + url: simba_tfasettings.ajaxurl, + type: 'POST', + data: { + action: 'simbatfa-init-otp', + user: username + }, + dataType: 'text', + success: function(resp) { + try { + var json_begins = resp.search('{"jsonstarter":"justhere"'); + if (json_begins > -1) { + if (json_begins > 0) { + console.log("Expected JSON marker found at position: "+json_begins); + resp = resp.substring(json_begins); + } + } else { + console.log("Expected JSON marker not found"); + console.log(resp); + } + + response = JSON.parse(resp); + + if (response.hasOwnProperty('php_output')) { + console.log("PHP output was returned (follows)"); + console.log(response.php_output); + } + + if (response.hasOwnProperty('extra_output')) { + console.log("Extra output was returned (follows)"); + console.log(response.extra_output); + } + + if (only_cache_the_results) { + // Save the result for later processing + username_requires_otp[username] = response; + $('.simbaotp_spinner').remove(); + } else { + process_user_tfa_enabled_check_results($(form), response); + } + + } catch(err) { + $('#login').html(resp); + console.log("Simba TFA: Error when processing response"); + console.log(err); + console.log(resp); + } + }, + error: function(jq_xhr, text_status, error_thrown) { + console.log("Simba TFA: AJAX error: "+error_thrown+": "+text_status); + console.log(jq_xhr); + if (jq_xhr.hasOwnProperty('responseText')) { + console.log(jq_xhr.responseText); + $(form).append('

            '+simba_tfasettings.error+'

            '); + } + } + }); + return true; + } + + // Parameters: see check_and_possibly_show_otp_field + function show_otp_field(form, user_can_trust, user_already_trusted) { + + var $submit_button; + + user_can_trust = ('undefined' == typeof user_can_trust) ? false : user_can_trust; + user_already_trusted = ('undefined' == typeof user_already_trusted) ? false : user_already_trusted; + + if ('https:' != window.location.protocol && 'localhost' !== location.hostname && '127.0.0.1' !== location.hostname && /^\.localdomain$/.test(location.hostname)) { + user_can_trust = false; + } + + if (!user_can_trust) { user_already_trusted = false; } + + var form_is_gravity_forms = ('object' == typeof window['gform_gravityforms'] && 'undefined' !== typeof $(form).attr('id') && 'gform_' === $(form).attr('id').substring(0, 6)); + + // This is used just for applying similar styling (via adding structure/CSS classes) + var form_is_ultimate_member = ($(form).find('.um-row').length > 0) ? true : false; + + // This is used just for applying styling if .js-login-form class exists inside form + var form_is_login_form = ($(form).find('.js-login-form').length > 0) ? true : false; + + // Gravity Forms won't submit if the elements are hidden + var form_retain_existing_elements = form_is_gravity_forms ? true : false; + + // name="Submit" is WP-Members. 'submit' is Theme My Login starting from 7.x + $submit_button = $(form).find('input[name="wp-submit"], input[name="Submit"], input[name="submit"]'); + // This hasn't been needed for anything yet (Jul 2018), but is a decent back-stop that would have prevented some breakage in the past that needed manual attention: + if (0 == $submit_button.length) { + $submit_button = $(form).find('input[type="submit"], button[type="submit"]').first(); + } + + if (!form_retain_existing_elements) { + // Hide all elements in a browser-safe way + // .user-pass-wrap is the wrapper used (instead of a paragraph) on wp-login.php from WP 5.3 + // .um-row : Ultimate Member + // .rmrow : RegistrationMagic + $submit_button.parents('form').first().find('p, .impu-form-line-fr, .tml-field-wrap, .user-pass-wrap, .elementor-field-type-text, .elementor-field-type-submit, .elementor-remember-me, .bbp-username, .bbp-password, .bbp-submit-wrapper, .gform_body, .um-row, .um-button, .js-login-form, .rmrow').each(function(i) { + $(this).css('visibility', 'hidden').css('position', 'absolute'); + // On the WooCommerce form, the 'required' asterisk in the child still shows without this + $(this).find('span').css('visibility', 'hidden').css('position', 'absolute'); + }); + + // WP-Members + $submit_button.parents('#wpmem_login').find('fieldset').css('visibility', 'hidden').css('position', 'absolute'); + + } + + // Add new field and controls + var html = ''; + + if (form_is_ultimate_member) { + html += '
            '; + } + + if (user_already_trusted) { + + html += '
            '+simba_tfasettings.is_trusted+''; + + } else { + + if (form_is_ultimate_member) { html += '
            '; } + + html += '
            '; + } + + if (user_can_trust) { + + html += ''; + + } + } + + html += '

            '; + + var submit_button_text; + var submit_button_name; + + // Gravity forms doesn't like its button being disabled + if (!form_is_gravity_forms) { + + if ('button' == $submit_button.prop('nodeName').toLowerCase()) { + submit_button_text = $submit_button.text().trim(); + submit_button_name = $submit_button.attr('name'); + } else { + submit_button_text = $submit_button.val(); + submit_button_name = $submit_button.attr('name'); + } + + html += '

            '; + + $submit_button.prop('disabled', true).hide(); + + } + + if (form_retain_existing_elements && form_is_gravity_forms) { + // $submit_button.parents('form').first().append(html); + //$('
            '+html+'
            ').insertBefore($submit_button); + $(form).find('#gform_fields_login').append(html); + } else { + $submit_button.parents('form').first().prepend(html); + } + + $('#login_error').hide(); + + if (user_already_trusted) { + if (form_retain_existing_elements) { + $submit_button.trigger('click'); + } else { + $('#tfa_login_btn').trigger('click'); + } + } else { + + $('#simba_two_factor_auth').trigger('focus'); + + // Hide extra boxes of third party plugins + jQuery('.hide-when-displaying-tfa-input').hide(); + } + + } + + /** + * This function gets attached to a form submission handler and decides whether to add an OTP field or not. + * + * @param Object e - submission event + * + * @return Boolean - whether to proceed with the submission or not + */ + var form_submit_handler = function(e) { + + console.log('Simba TFA: form submit request'); + + var form = e.target; + + var form_is_gravity_forms = ('object' == typeof window['gform_gravityforms'] && 'undefined' !== typeof $(form).attr('id') && 'gform_' === $(form).attr('id').substring(0, 6)); + + // Turn off everything + $(form).off(); + + if (0 == $(form).find('#simba_two_factor_auth').length && check_and_possibly_show_otp_field(form)) { + + if (form_is_gravity_forms) { + var form_id = $(form).attr('id').substring(6); + // Gravity Forms won't allow the form to submit if this is already true + window['gf_submitting_'+form_id] = false; + } + + e.preventDefault(); + return false; + + } + + return true; + + }; + + if (simba_tfasettings.login_form_off_selectors) { + $(simba_tfasettings.login_form_off_selectors).off('submit'); + } + + $(simba_tfasettings.login_form_selectors).on('submit', form_submit_handler); + + $(simba_tfasettings.login_form_selectors).find(get_username_identifiers()).on('blur', function() { + var $form = $(this).parents('form').first(); + check_and_possibly_show_otp_field($form, true); + }); + +}); diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/tfa_admin_icon_16x16.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/tfa_admin_icon_16x16.png new file mode 100755 index 0000000000000000000000000000000000000000..7605cc449ed434a39d525dd84c93db3a6e8a8987 GIT binary patch literal 3829 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 zmother = $mother; + add_action('wp_ajax_tfa_frontend', array($this, 'ajax')); + add_shortcode('twofactor_user_settings', array($this, 'tfa_user_settings_front')); + + if (!WP_Block_Type_Registry::get_instance()->is_registered('twofactor/user-settings')) { + register_block_type('twofactor/user-settings', array( + 'editor_script' => 'twofactor-gutenberg-blocks', + 'render_callback' => array($this, 'tfa_user_settings_front'), + )); + } + } + + /** + * Runs upon the WP action wp_ajax_tfa_frontend + * + * @uses die() + */ + public function ajax() { + $totp_controller = $this->mother->get_controller('totp'); + global $current_user; + + $return_array = array(); + + if (empty($_POST) || empty($_POST['subaction']) || !isset($_POST['nonce']) || !is_user_logged_in() || !wp_verify_nonce($_POST['nonce'], 'tfa_frontend_nonce')) die('Security check'); + + if ('savesettings' == $_POST['subaction']) { + if (empty($_POST['settings']) || !is_string($_POST['settings'])) die; + + parse_str(stripslashes($_POST['settings']), $posted_settings); + + if (isset($posted_settings['tfa_algorithm_type'])) { + $old_algorithm = $totp_controller->get_user_otp_algorithm($current_user->ID); + + if ($old_algorithm != $posted_settings['tfa_algorithm_type']) + $totp_controller->changeUserAlgorithmTo($current_user->ID, $posted_settings['tfa_algorithm_type']); + + //Re-fetch the algorithm type, url and private string + $variables = $this->tfa_fetch_assort_vars(); + + $return_array['qr'] = $totp_controller->tfa_qr_code_url($variables['algorithm_type'], $variables['url'], $variables['tfa_priv_key']); + $return_array['al_type_disp'] = $this->tfa_algorithm_info($variables['algorithm_type']); + } + + if (isset($posted_settings['tfa_enable_tfa'])) { + + $allow_enable_or_disable = false; + + if (empty($posted_settings['require_current']) || !$posted_settings['tfa_enable_tfa']) { + $allow_enable_or_disable = true; + } else { + + if (!isset($posted_settings['tfa_enable_current']) || '' == $posted_settings['tfa_enable_current']) { + $return_array['message'] = __('To enable TFA, you must enter the current code.', 'all-in-one-wp-security-and-firewall'); + $return_array['error'] = 'code_absent'; + } else { + // Third parameter: don't allow emergency codes + if ($totp_controller->check_code_for_user($current_user->ID, $posted_settings['tfa_enable_current'], false)) { + $allow_enable_or_disable = true; + } else { + $return_array['error'] = 'code_wrong'; + $return_array['message'] = apply_filters('simba_tfa_message_code_incorrect', __('The TFA code you entered was incorrect.', 'all-in-one-wp-security-and-firewall')); + } + } + + } + + if ($allow_enable_or_disable) $this->mother->change_tfa_enabled_status($current_user->ID, $posted_settings['tfa_enable_tfa']); + } + + $return_array['result'] = 'saved'; + + echo json_encode($return_array); + } + + die; + } + + /** + * Make the algorithm information string easier to update + * + * @param String $algorithm_type - totp|hotp + */ + public function tfa_algorithm_info($algorithm_type) { + $al_type_disp = strtoupper($algorithm_type); + $al_type_desc = ($algorithm_type == 'totp' ? __('a time based', 'all-in-one-wp-security-and-firewall') : __('an event based', 'all-in-one-wp-security-and-firewall')); + + return array('disp' => $al_type_disp, 'desc' => $al_type_desc); + } + + /** + * Make the assorted required variables more accessible for ajax + * + * Returns: Site URL, private key, emergency codes, algorithm type + * + * @return Array + */ + public function tfa_fetch_assort_vars() { + global $current_user; + $totp_controller = $this->mother->get_controller('totp'); + + $url = preg_replace('/^https?:\/\//i', '', site_url()); + + $tfa_priv_key_64 = get_user_meta($current_user->ID, 'tfa_priv_key_64', true); + + if (!$tfa_priv_key_64) $tfa_priv_key_64 = $totp_controller->addPrivateKey($current_user->ID); + + $tfa_priv_key = trim($totp_controller->getPrivateKeyPlain($tfa_priv_key_64, $current_user->ID)); + + $algorithm_type = $totp_controller->get_user_otp_algorithm($current_user->ID); + + return apply_filters('simba_tfa_fetch_assort_vars', array( + 'url' => $url, + 'tfa_priv_key_64' => $tfa_priv_key_64, + 'tfa_priv_key' => $tfa_priv_key, + 'emergency_str' => ''.__('No emergency codes left. Sorry.', 'all-in-one-wp-security-and-firewall').'', + 'algorithm_type' => $algorithm_type + ), $totp_controller, $current_user); + } + + /** + * Paints out the 'save settings' button + */ + public function save_settings_button() { + echo ''; + } + + /** + * Paint output for the TFA on/off radio + * + * @param String $style - valid values are 'show_current' and 'require_current' + */ + public function settings_enable_or_disable_output($style = 'show_current') { + $this->save_settings_javascript_output(); + global $current_user; + ?> +
            +

            mother->paint_enable_tfa_radios($current_user->ID, true, $style); ?>

            + +
            + mother->includes_url().'/jquery.blockUI' . $suffix . '.js', array('jquery'), '2.60'); + + $script_ver = (defined('WP_DEBUG') && WP_DEBUG) ? time() : filemtime($this->mother->includes_dir().'/frontend-settings.js'); + + wp_enqueue_script('simba-tfa-frontend-settings', $this->mother->includes_url().'/frontend-settings.js', array('jquery-blockui'), $script_ver); + + $ajax_url = admin_url('admin-ajax.php'); + // It's possible that FORCE_ADMIN_SSL will make that SSL, whilst the user is on the front-end having logged in over non-SSL - and as a result, their login cookies won't get sent, and they're not registered as logged in. + if (!is_admin() && substr(strtolower($ajax_url), 0, 6) == 'https:' && !is_ssl()) { + $also_try = 'http:'.substr($ajax_url, 6); + } else { + $also_try = ''; + } + + $localize = array( + 'ask' => __('You have unsaved settings.', 'all-in-one-wp-security-and-firewall'), + 'saving' => __('Saving...', 'all-in-one-wp-security-and-firewall'), + 'ajax_url' => $ajax_url, + 'also_try' => $also_try, + 'nonce' => wp_create_nonce('tfa_frontend_nonce'), + 'response' => __('Response:', 'all-in-one-wp-security-and-firewall'), + ); + + wp_localize_script('simba-tfa-frontend-settings', 'simba_tfa_frontend', $localize); + + } + + /** + * Shortcode function for twofactor_user_settings + * + * @param Array $atts - shortcode attributes + * + * @return String + */ + public function tfa_user_settings_front($atts = array()) { + + if (!is_user_logged_in()) return ''; + + $atts = array_change_key_case((array)$atts, CASE_LOWER); + + $atts = shortcode_atts(array('show_algorithm_selector' => 'no'), $atts); + + $show_algorithm_selector = ('yes' === $atts['show_algorithm_selector']); + + global $current_user; + + return $this->mother->include_template('shortcode-tfa-user-settings.php', array('is_activated_for_user' => $current_user->ID, 'tfa_frontend' => $this, 'show_algorithm_selector' => $show_algorithm_selector), true); + + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/totp.js b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/totp.js new file mode 100755 index 00000000..98bb4171 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/totp.js @@ -0,0 +1,101 @@ +jQuery(function($) { + + // Render any QR codes on the page + $('.simbaotp_qr_container').qrcode({ + 'render': 'image', + 'text': $('.simbaotp_qr_container:first').data('qrcode'), + }); + + function update_otp_code() { + + $('.simba_current_otp').html(''+simbatfa_totp.updating+''); + + var got_code = ''; + + $.post(simbatfa_totp.ajax_url, { + action: 'simbatfa_shared_ajax', + subaction: 'refreshotp', + nonce: simbatfa_totp.tfa_shared_nonce + }, function(response) { + + try { + var resp = JSON.parse(response); + got_code = resp.code; + } catch(err) { + if ('' !== simbatfa_totp.also_try) { + alert(simbatfa_totp.response+" "+response); + } + console.log(response); + console.log(err); + } + + if ('' === got_code && '' !== simbatfa_totp.also_try) { + $.post(simbatfa_totp.also_try, { + action: 'simbatfa_shared_ajax', + subaction: 'refreshotp', + nonce: simbatfa_totp.tfa_shared_nonce + }, function(response) { + try { + var resp = JSON.parse(response); + if (resp.code) { + $('.simba_current_otp').html(resp.code); + } else { + console.log(response); + console.log("TFA: no code found"); + } + } catch(err) { + alert(simbatfa_totp.response+" "+response); + console.log(response); + console.log(err); + } + }); + } else if ('' != got_code) { + $('.simba_current_otp').html(got_code); + } else { + console.log("TFA: no code found"); + } + }); + } + + var min_refresh_after = 30; + + if (0 == $('body.settings_page_two-factor-auth').length) { + $('.simba_current_otp').each(function(ind, obj) { + var refresh_after = $(obj).data('refresh_after'); + if (refresh_after > 0 && refresh_after < min_refresh_after) { + min_refresh_after = refresh_after; + } + }); + + // Update after the given seconds, and then every 30 seconds + setTimeout(function() { + setInterval(update_otp_code, 30000) + update_otp_code(); + }, min_refresh_after * 1000); + } + + // Handle clicks on the 'refresh' link + $('.simbaotp_refresh').on('click', function(e) { + e.preventDefault(); + update_otp_code(); + }); + + $('#tfa_trusted_devices_box').on('click', '.simbatfa-trust-remove', function(e) { + e.preventDefault(); + var device_id = $(this).data('trusted-device-id'); + $(this).parents('.simbatfa_trusted_device').css('opacity', '0.5'); + if ('undefined' !== typeof device_id) { + $.post(simbatfa_totp.ajax_url, { + action: 'simbatfa_shared_ajax', + subaction: 'untrust_device', + nonce: simbatfa_totp.tfa_shared_nonce, + device_id: device_id + }, function(response) { + var resp = JSON.parse(response); + if (resp.hasOwnProperty('trusted_list')) { + $('#tfa_trusted_devices_box_inner').html(resp.trusted_list); + } + }); + } + }); +}); diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/users.css b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/users.css new file mode 100755 index 00000000..ca7d3f04 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/includes/users.css @@ -0,0 +1,13 @@ +/* TFA users list column */ +th.column-tfa-status, +td.column-tfa-status { + text-align: center; +} + +td.column-tfa-status span.dashicons-no { + color: red; +} + +td.column-tfa-status span.dashicons-yes { + color: green; +} \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/Base32/Base32.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/Base32/Base32.php new file mode 100755 index 00000000..02a3d533 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/Base32/Base32.php @@ -0,0 +1,225 @@ + + * @link http://christianriesen.com + * @license MIT License see LICENSE file + */ +class Base32 +{ + /** + * Table for encoding base32 + * + * @var array + */ + private static $encode = array( + 0 => 'A', + 1 => 'B', + 2 => 'C', + 3 => 'D', + 4 => 'E', + 5 => 'F', + 6 => 'G', + 7 => 'H', + 8 => 'I', + 9 => 'J', + 10 => 'K', + 11 => 'L', + 12 => 'M', + 13 => 'N', + 14 => 'O', + 15 => 'P', + 16 => 'Q', + 17 => 'R', + 18 => 'S', + 19 => 'T', + 20 => 'U', + 21 => 'V', + 22 => 'W', + 23 => 'X', + 24 => 'Y', + 25 => 'Z', + 26 => 2, + 27 => 3, + 28 => 4, + 29 => 5, + 30 => 6, + 31 => 7, + 32 => '=', + ); + + /** + * Table for decoding base32 + * + * @var array + */ + private static $decode = array( + 'A' => 0, + 'B' => 1, + 'C' => 2, + 'D' => 3, + 'E' => 4, + 'F' => 5, + 'G' => 6, + 'H' => 7, + 'I' => 8, + 'J' => 9, + 'K' => 10, + 'L' => 11, + 'M' => 12, + 'N' => 13, + 'O' => 14, + 'P' => 15, + 'Q' => 16, + 'R' => 17, + 'S' => 18, + 'T' => 19, + 'U' => 20, + 'V' => 21, + 'W' => 22, + 'X' => 23, + 'Y' => 24, + 'Z' => 25, + 2 => 26, + 3 => 27, + 4 => 28, + 5 => 29, + 6 => 30, + 7 => 31, + '=' => 32, + ); + + /** + * Creates an array from a binary string into a given chunk size + * + * @param string $binaryString String to chunk + * @param integer $bits Number of bits per chunk + * @return array + */ + private static function chunk($binaryString, $bits) + { + $binaryString = chunk_split($binaryString, $bits, ' '); + + if (substr($binaryString, (strlen($binaryString)) - 1) == ' ') { + $binaryString = substr($binaryString, 0, strlen($binaryString)-1); + } + + return explode(' ', $binaryString); + } + + /** + * Encodes into base32 + * + * @param string $string Clear text string + * @return string Base32 encoded string + */ + public static function encode($string) + { + if (strlen($string) == 0) { + // Gives an empty string + return ''; + } + + // Convert string to binary + $binaryString = ''; + + foreach (str_split($string) as $s) { + // Return each character as an 8-bit binary string + $s = decbin(ord($s)); + $binaryString .= str_pad($s, 8, 0, STR_PAD_LEFT); + } + + // Break into 5-bit chunks, then break that into an array + $binaryArray = self::chunk($binaryString, 5); + + // Pad array to be divisible by 8 + while (count($binaryArray) % 8 !== 0) { + $binaryArray[] = null; + } + + $base32String = ''; + + // Encode in base32 + foreach ($binaryArray as $bin) { + $char = 32; + + if (!is_null($bin)) { + // Pad the binary strings + $bin = str_pad($bin, 5, 0, STR_PAD_RIGHT); + $char = bindec($bin); + } + + // Base32 character + $base32String .= self::$encode[$char]; + } + + return $base32String; + } + + /** + * Decodes base32 + * + * @param string $base32String Base32 encoded string + * @return string Clear text string + */ + public static function decode($base32String) + { + if (strlen($base32String) == 0) { + // Gives an empty string + return ''; + } + + // Only work in upper cases + $base32String = strtoupper($base32String); + + // Remove anything that is not base32 alphabet + $pattern = '/[^A-Z2-7]/'; + $replacement = ''; + + $base32String = preg_replace($pattern, '', $base32String); + + $base32Array = str_split($base32String); + + $binaryArray = array(); + $string = ''; + + foreach ($base32Array as $str) { + $char = self::$decode[$str]; + + // Ignore the padding character + if ($char !== 32) { + $char = decbin($char); + $string .= str_pad($char, 5, 0, STR_PAD_LEFT); + } + } + + while (strlen($string) %8 !== 0) { + $string = substr($string, 0, strlen($string)-1); + } + + $binaryArray = self::chunk($string, 8); + + $realString = ''; + + foreach ($binaryArray as $bin) { + // Pad each value to 8 bits + $bin = str_pad($bin, 8, 0, STR_PAD_RIGHT); + // Convert binary strings to ascii + $realString .= chr(bindec($bin)); + } + + return $realString; + } +} + diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/hotp-php-master/LICENSE b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/hotp-php-master/LICENSE new file mode 100755 index 00000000..0b10fd2e --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/hotp-php-master/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2008, Jakob Heuser +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of HOTP-PHP nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY Jakob Heuser ''AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/hotp-php-master/README.markdown b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/hotp-php-master/README.markdown new file mode 100755 index 00000000..59b2b416 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/hotp-php-master/README.markdown @@ -0,0 +1,27 @@ +HOTP - PHP Based HMAC One Time Passwords +======================================== + +**What is HOTP**: +HOTP is a class that simplifies One Time Password systems for PHP Authentication. The HOTP/TOTP Algorithms have been around for a bit, so this is a straightforward class to meet the test vector requirements. + +**What works with HOTP/TOTP**: +It's been tested to the test vectors, and I've verified the time-sync hashes against the following: + +* Android: Mobile-OTP +* iPhone: OATH Token + +**Why would I use this**: +Who wouldn't love a simple drop-in class for HMAC Based One Time Passwords? It's a great extra layer of security (creating two-factor auth) and it's pretty darn zippy. + +**Okay you sold me. Give me some docs**: + +* $result = HOTP::generateByCounter($key, $counter); // event based +* $result = HOTP::generateByTime($key, $window); // time based within a "window" of time +* $result = HOTP::generateByTimeWindow($key, $window, $min, $max); // same as generateByTime, but for $min windows before and $max windows after + +with $result, you can do all sorts of neat things... + +* $result->toString(); +* $result->toHex(); +* $result->doDec(); +* $result->toHotp($length); // how many digits in your OTP? \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/hotp-php-master/example.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/hotp-php-master/example.php new file mode 100755 index 00000000..44c05753 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/hotp-php-master/example.php @@ -0,0 +1,160 @@ + array( + 0 => array( + 'HMAC' => 'cc93cf18508d94934c64b65d8ba7667fb7cde4b0', + 'hex' => '4c93cf18', + 'dec' => '1284755224', + 'hotp' => '755224', + ), + 1 => array( + 'HMAC' => '75a48a19d4cbe100644e8ac1397eea747a2d33ab', + 'hex' => '41397eea', + 'dec' => '1094287082', + 'hotp' => '287082', + ), + 2 => array( + 'HMAC' => '0bacb7fa082fef30782211938bc1c5e70416ff44', + 'hex' => '82fef30', + 'dec' => '137359152', + 'hotp' => '359152', + ), + 3 => array( + 'HMAC' => '66c28227d03a2d5529262ff016a1e6ef76557ece', + 'hex' => '66ef7655', + 'dec' => '1726969429', + 'hotp' => '969429', + ), + 4 => array( + 'HMAC' => 'a904c900a64b35909874b33e61c5938a8e15ed1c', + 'hex' => '61c5938a', + 'dec' => '1640338314', + 'hotp' => '338314', + ), + 5 => array( + 'HMAC' => 'a37e783d7b7233c083d4f62926c7a25f238d0316', + 'hex' => '33c083d4', + 'dec' => '868254676', + 'hotp' => '254676', + ), + 6 => array( + 'HMAC' => 'bc9cd28561042c83f219324d3c607256c03272ae', + 'hex' => '7256c032', + 'dec' => '1918287922', + 'hotp' => '287922', + ), + 7 => array( + 'HMAC' => 'a4fb960c0bc06e1eabb804e5b397cdc4b45596fa', + 'hex' => '4e5b397', + 'dec' => '82162583', + 'hotp' => '162583', + ), + 8 => array( + 'HMAC' => '1b3c89f65e6c9e883012052823443f048b4332db', + 'hex' => '2823443f', + 'dec' => '673399871', + 'hotp' => '399871', + ), + 9 => array( + 'HMAC' => '1637409809a679dc698207310c8c7fc07290d9e5', + 'hex' => '2679dc69', + 'dec' => '645520489', + 'hotp' => '520489', + ), + ), + 'TOTP' => array( + '59' => array( + 'totp' => '94287082', + ), + '1111111109' => array( + 'totp' => '07081804', + ), + '1111111111' => array( + 'totp' => '14050471', + ), + '1234567890' => array( + 'totp' => '89005924', + ), + '2000000000' => array( + 'totp' => '69279037', + ), + ), + ); + +echo <<
            +http://www.ietf.org/rfc/rfc4226.txt
            +http://tools.ietf.org/html/draft-mraihi-totp-timebased-06
            +
            +TEST VECTOR VERIFICATION
            +
            +HOTP Tests:
            +
            +DOCBLOCK;
            +  
            +echo "Count Method Value                                           Pass/Fail\n";
            +echo "----------------------------------------------------------------------\n";
            +
            +// loop over all HOTP table results, and calculate the matching value
            +foreach ($table['HOTP'] as $seed => $results) {
            +    $hotp = HOTP::generateByCounter($key, $seed);
            +    $first = true;
            +    foreach ($results as $type => $calc) {
            +        if ($first) {
            +            echo str_pad($seed, 4, ' ', STR_PAD_LEFT);
            +            $first = false;
            +        }
            +        else {
            +            echo '    ';
            +        }
            +        echo '  ';
            +        echo str_pad($type, 5, ' ', STR_PAD_RIGHT);
            +        echo '  ';
            +        echo str_pad($calc, 47, ' ', STR_PAD_RIGHT);
            +        echo '  ';
            +        $method = 'to'.(ucfirst(str_replace('HMAC', 'string', $type)));
            +        echo str_pad(($calc == $hotp->$method(6)) ? '[OK]' : '[FAIL]', 9, ' ', STR_PAD_LEFT);
            +        echo "\n";
            +    }
            +}
            +
            +echo << $results) {
            +    $totp = HOTP::generateByTime($key, 30, $seed);
            +    $first = true;
            +    foreach ($results as $type => $calc) {
            +        if ($first) {
            +            echo str_pad($seed, 10, ' ', STR_PAD_LEFT);
            +            $first = false;
            +        }
            +        else {
            +            echo '          ';
            +        }
            +        echo '   ';
            +        echo str_pad($calc, 47, ' ', STR_PAD_RIGHT);
            +        echo '  ';
            +        $method = 'to'.(ucfirst(str_replace('totp', 'hotp', $type)));
            +        echo str_pad(($calc == $totp->$method(8)) ? '[OK]' : '[FAIL]', 9, ' ', STR_PAD_LEFT);
            +        echo "\n";
            +    }
            +}
            +
            +echo '
            '; + diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/hotp-php-master/hotp.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/hotp-php-master/hotp.php new file mode 100755 index 00000000..090e7599 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/hotp-php-master/hotp.php @@ -0,0 +1,174 @@ += 0; $i--) { + $cur_counter[$i] = pack ('C*', $counter); + $counter = $counter >> 8; + } + + $bin_counter = implode($cur_counter); + + // Pad to 8 chars + if (strlen($bin_counter) < 8) { + $bin_counter = str_repeat (chr(0), 8 - strlen ($bin_counter)) . $bin_counter; + } + + // HMAC + $hash = hash_hmac('sha1', $bin_counter, $key); + + return new HOTPResult($hash); + } + + /** + * Generate a HOTP key based on a timestamp and window size + * @param string $key the key to use for hashing + * @param int $window the size of the window a key is valid for in seconds + * @param int $timestamp a timestamp to calculate for, defaults to time() + * @return HOTPResult a HOTP Result which can be truncated or output + */ + public static function generateByTime($key, $window, $timestamp = false) { + if (!$timestamp && $timestamp !== 0) { + $timestamp = HOTP::getTime(); + } + + $counter = intval($timestamp / $window); + + return HOTP::generateByCounter($key, $counter); + } + + /** + * Generate a HOTP key collection based on a timestamp and window size + * all keys that could exist between a start and end time will be included + * in the returned array + * @param string $key the key to use for hashing + * @param int $window the size of the window a key is valid for in seconds + * @param int $min the minimum window to accept before $timestamp + * @param int $max the maximum window to accept after $timestamp + * @param int $timestamp a timestamp to calculate for, defaults to time() + * @return array of HOTPResult + */ + public static function generateByTimeWindow($key, $window, $min = -1, $max = 1, $timestamp = false) { + if (!$timestamp && $timestamp !== 0) { + $timestamp = HOTP::getTime(); + } + + $counter = intval($timestamp / $window); + $window = range($min, $max); + + $out = array(); + for ($i = 0; $i < count($window); $i++) { + $shift_counter = $window[$i]; + $out[$shift_counter] = HOTP::generateByCounter($key, $counter + $shift_counter); + } + + return $out; + } + + /** + * Gets the current time + * Ensures we are operating in UTC for the entire framework + * Restores the timezone on exit. + * @return int the current time + */ + public static function getTime() { + return time(); // PHP's time is always UTC + } +} + +/** + * The HOTPResult Class converts an HOTP item to various forms + * Supported formats include hex, decimal, string, and HOTP + * @author Jakob Heuser (firstname)@felocity.com + */ +class HOTPResult { + protected $hash; + protected $binary; + protected $decimal; + + /** + * Build an HOTP Result + * @param string $value the value to construct with + */ + public function __construct($value) { + // store raw + $this->hash = $value; + } + + /** + * Returns the string version of the HOTP + * @return string + */ + public function toString() { + return $this->hash; + } + + /** + * Returns the hex version of the HOTP + * @return string + */ + public function toHex() { + if( !$this->hex ) + { + $this->hex = dechex($this->toDec()); + } + return $this->hex; + } + + /** + * Returns the decimal version of the HOTP + * @return int + */ + public function toDec() { + if( !$this->decimal ) + { + // store calculate decimal + $hmac_result = array(); + + // Convert to decimal + foreach(str_split($this->hash,2) as $hex) + { + $hmac_result[] = hexdec($hex); + } + + $offset = $hmac_result[19] & 0xf; + + $this->decimal = ( + (($hmac_result[$offset+0] & 0x7f) << 24 ) | + (($hmac_result[$offset+1] & 0xff) << 16 ) | + (($hmac_result[$offset+2] & 0xff) << 8 ) | + ($hmac_result[$offset+3] & 0xff) + ); + } + return $this->decimal; + } + + /** + * Returns the truncated decimal form of the HOTP + * @param int $length the length of the HOTP to return + * @return string + */ + public function toHOTP($length) { + $str = str_pad($this->toDec(), $length, "0", STR_PAD_LEFT); + $str = substr($str, (-1 * $length)); + return $str; + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/loader.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/loader.php new file mode 100755 index 00000000..b322ec6f --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/providers/totp/loader.php @@ -0,0 +1,1034 @@ +tfa = $tfa; + + $this->otp_helper = new HOTP(); + + add_action('plugins_loaded', array($this, 'plugins_loaded')); + + add_action('admin_init', array($this, 'admin_init')); + + if (!is_admin()) { + add_action('init', array($this, 'check_possible_reset')); + } + + // Potentially show off-sync message for hotp + add_action('admin_notices', array($this, 'tfa_show_hotp_off_sync_message')); + } + + /** + * Return whether or not this class detected and saved new settings + * + * @return Boolean + */ + public function were_settings_saved() { + return $this->settings_saved; + } + + /** + * Runs upon the WP action admin_init + */ + public function admin_init() { + + $this->check_possible_reset(); + + global $current_user; + + if (!empty($_REQUEST['_tfa_activate_nonce']) && !empty($_POST['tfa_enable_tfa']) && wp_verify_nonce($_REQUEST['_tfa_activate_nonce'], 'tfa_activate') && !empty($_GET['settings-updated'])) { + $this->tfa->change_tfa_enabled_status($current_user->ID, $_POST['tfa_enable_tfa']); + $this->settings_saved = true; + } + + if (!empty($_REQUEST['_tfa_algorithm_nonce']) && !empty($_POST['tfa_algorithm_type']) && !empty($_GET['settings-updated']) && wp_verify_nonce($_REQUEST['_tfa_algorithm_nonce'], 'tfa_algorithm')) { + + $old_algorithm = $this->get_user_otp_algorithm($current_user->ID); + + if ($old_algorithm != $_POST['tfa_algorithm_type']) { + $this->changeUserAlgorithmTo($current_user->ID, $_POST['tfa_algorithm_type']); + } + + $this->settings_saved = true; + } + + if (!empty($_GET['warning_button_clicked']) && !empty($_REQUEST['resyncnonce']) && wp_verify_nonce($_REQUEST['resyncnonce'], 'tfaresync')) { + delete_user_meta($current_user->ID, 'tfa_hotp_off_sync'); + } + + } + + /** + * Enqueue adding of JavaScript for footer + */ + public function add_footer() { + + static $added_footer = false; + if ($added_footer) return; + $added_footer = true; + + $qr_script_file = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? 'jquery-qrcode.js' : 'jquery-qrcode.min.js'; + + $qr_script_ver = (defined('WP_DEBUG') && WP_DEBUG) ? time() : filemtime($this->tfa->includes_dir()."/jquery-qrcode/$qr_script_file"); + + wp_register_script('jquery-qrcode', $this->tfa->includes_url()."/jquery-qrcode/$qr_script_file", array('jquery'), $qr_script_ver); + + $script_ver = (defined('WP_DEBUG') && WP_DEBUG) ? time() : filemtime($this->tfa->includes_dir()."/totp.js"); + + // Adds the necessary JavaScript for rendering and updating QR codes, and handling trusted devices removal in the admin area + wp_enqueue_script('simba-tfa-totp', $this->tfa->includes_url()."/totp.js", array('jquery-qrcode'), $script_ver); + + wp_localize_script('simba-tfa-totp', 'simbatfa_totp', $this->translation_strings()); + + } + + /** + * Get textual strings used from JavaScript + * + * @return Array + */ + private function translation_strings() { + + // It's possible that FORCE_ADMIN_SSL will make that SSL, whilst the user is on the front-end having logged in over non-SSL - and as a result, their login cookies won't get sent, and they're not registered as logged in. + $ajax_url = admin_url('admin-ajax.php'); + $also_try = ''; + if (!is_admin() && substr(strtolower($ajax_url), 0, 6) == 'https:' && !is_ssl()) { + $also_try = 'http:'.substr($ajax_url, 6); + } + + return apply_filters('simba_tfa_totp_translation_strings', array( + 'ajax_url' => $ajax_url, + 'updating' => __('Updating...', 'all-in-one-wp-security-and-firewall'), + 'tfa_shared_nonce' => wp_create_nonce('tfa_shared_nonce'), + 'also_try' => $also_try, + 'response' => __('Response:', 'all-in-one-wp-security-and-firewall'), + )); + } + + /** + * Return a link to refresh the current OTP code + * + * @return String + */ + public function refresh_current_otp_link() { + return '
            '.__('(update)', 'all-in-one-wp-security-and-firewall').''; + } + + /** + * Echo the radio buttons for changing between TOTP/HOTP + * + * TODO: Hide this choice on new installs (TOTP only) + * + * @param Integer $user_id + */ + protected function print_algorithm_choice_radios($user_id) { + if (!$user_id) return; + + $types = array( + 'totp' => __('TOTP (time based - most common algorithm; used by Google Authenticator)', 'all-in-one-wp-security-and-firewall'), + 'hotp' => __('HOTP (event based)', 'all-in-one-wp-security-and-firewall') + ); + + $setting = $this->get_user_otp_algorithm($user_id); + + foreach ($types as $id => $name) { + print '
            \n"; + } + } + + /** + * Print out the advanced settings box - choice of algorithm + * + * @param Boolean|Callable $submit_button_callback - if not a callback, then
            tags will be added + */ + public function advanced_settings_box($submit_button_callback = false) { + + global $current_user; + $algorithm_type = $this->get_user_otp_algorithm($current_user->ID); + + ?> +

            + +
            + + + + + + + +

            + print_algorithm_choice_radios($current_user->ID); + if ('hotp' == $algorithm_type) { + $counter = $this->getUserCounter($current_user->ID); + print '
            '.__('Your counter on the server is currently on', 'all-in-one-wp-security-and-firewall').': '.$counter; + } + ?> + +

            + '; } else { call_user_func($submit_button_callback); } ?> + +
            + ID; + $tfa_priv_key_64 = get_user_meta($user_id, 'tfa_priv_key_64', true); + if (!$tfa_priv_key_64) $tfa_priv_key_64 = $this->addPrivateKey($user_id); + $time_now = time(); + $refresh_after = 30 - ($time_now % 30); + return ''.$this->generateOTP($user_id, $tfa_priv_key_64).''; + } + + /** + * Runs upon the WP 'init' action - check for possible private key reset request from the user + */ + public function check_possible_reset() { + if (!empty($_GET['simbatfa_priv_key_reset']) && !empty($_REQUEST['nonce']) && wp_verify_nonce($_REQUEST['nonce'], 'simbatfa_reset_private_key')) { + $this->reset_private_key_and_emergency_codes(); + exit; + } + } + + /** + * Remove private key and emergency codes for the specified (or logged-in) user + * + * @param Boolean|Integer $user_id - WP user ID, or false for the currently logged-in user + * @param Boolean $redirect - if this is not false, then a redirection will occur - where to depends upon the value of $_REQUEST['noredirect'] + */ + public function reset_private_key_and_emergency_codes($user_id = false, $redirect = true) { + + if (!$user_id) { + global $current_user; + $user_id = $current_user->ID; + } + + delete_user_meta($user_id, 'tfa_priv_key_64'); + delete_user_meta($user_id, 'simba_tfa_emergency_codes_64'); + + if (!$redirect) return; + + if (empty($_REQUEST['noredirect'])) { + // TODO: Re-factoring + wp_safe_redirect(admin_url('admin.php').'?page='. $this->tfa->get_user_settings_page_slug() .'&settings-updated=1'); + } else { + $url = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . remove_query_arg(array('simbatfa_priv_key_reset', 'noredirect', 'nonce')); + wp_redirect(esc_url_raw($url)); + } + } + + /** + * Return HTML for a link to reset the current user's private key + * + * @return String + */ + public function reset_link() { + + // TODO: Refactoring + $url_base = is_admin() ? admin_url('admin.php').'?page='. $this->tfa->get_user_settings_page_slug() .'&settings-updated=1' : (( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST']); + + $add_query_args = array('simbatfa_priv_key_reset' => 1); + + if (!is_admin()) $add_query_args['noredirect'] = 1; + + $url = $url_base.add_query_arg($add_query_args); + + $url = wp_nonce_url($url, 'simbatfa_reset_private_key', 'nonce'); + + return ''.__('Reset private key', 'all-in-one-wp-security-and-firewall').''; + + } + + /** + * Output the current codes box + * + * @param Boolean|Integer $user_id + */ + public function current_codes_box($user_id = false) { + + global $current_user; + if (false == $user_id) $user_id = $current_user->ID; + + $admin = is_admin(); + + $this->add_footer(); + + $url = preg_replace('/^https?:\/\//i', '', site_url()); + + // TODO Replace this with an appropriate method + $tfa_priv_key_64 = get_user_meta($user_id, 'tfa_priv_key_64', true); + if (!$tfa_priv_key_64) $tfa_priv_key_64 = $this->addPrivateKey($user_id); + + $tfa_priv_key = trim($this->getPrivateKeyPlain($tfa_priv_key_64, $user_id), "\x00..\x1F"); + + $tfa_priv_key_32 = Base32::encode($tfa_priv_key); + + $algorithm_type = $this->get_user_otp_algorithm($user_id); + + if ($admin && $current_user->ID != $user_id) { + $user = get_user_by('id', $user_id); + $user_descrip = htmlspecialchars($user->user_nicename.' - '.$user->user_email); + echo '

            '.sprintf(__('Current codes (login: %s)', 'all-in-one-wp-security-and-firewall'), $user_descrip).'

            '; + } + + ?> +
            + + +

            + ID == $user_id) { echo $this->refresh_current_otp_link(); } ?> + +
            +

            current_otp_code($user_id); ?>

            +
            +

            + + +
            +

            + refresh_current_otp_link(); ?> : + + generateOTP($user_id, $tfa_priv_key_64); ?> + +

            +
            + + + + +

            + +

            + +

            + + +
            +

            + + + . +

            + + tfa_qr_code_url($algorithm_type, $url, $tfa_priv_key, $user_id); ?> +
            + +

            + print_private_keys('full', $user_id); + if ($current_user->ID == $user_id) { + echo $this->reset_link($admin); + } else { + echo ''.__('Reset private key', 'all-in-one-wp-security-and-firewall').''; + } + ?> +

            + + + +
            +

            + tfa->get_premium_version_url()).'">'.__('One-time emergency codes are a feature of the Premium version of this plugin.', 'all-in-one-wp-security-and-firewall').''; + echo apply_filters('simba_tfa_emergency_codes_user_settings', $default_text, $user_id); + ?> +
            + + +
            + +
            + ID; + + $tfa_priv_key_64 = get_user_meta($user_id, 'tfa_priv_key_64', true); + if (!$tfa_priv_key_64) $tfa_priv_key_64 = $this->addPrivateKey($user_id); + + $tfa_priv_key = trim($this->getPrivateKeyPlain($tfa_priv_key_64, $user_id), "\x00..\x1F"); + + $tfa_priv_key_32 = Base32::encode($tfa_priv_key); + + // The first (base32) private key used to have the description "base 32 - used by Google Authenticator and Authy", and the base64 version was just described as "private key". But basically the former is what everything uses. + //Private key: htmlspecialchars($tfa_priv_key) + if ('full' == $type) { + ?> + '.htmlspecialchars($tfa_priv_key_32); ?>
            + user_login).'?secret='.Base32::encode($tfa_priv_key).'&issuer='.$url.'&counter='.$this->getUserCounter($user->ID); + + return $encode; + } + + /** + * See if HOTP is off sync, and if show, print out a message + */ + public function tfa_show_hotp_off_sync_message() { + + global $current_user; + $is_off_sync = get_user_meta($current_user->ID, 'tfa_hotp_off_sync', true); + if (!$is_off_sync) return; + + ?> +
            +

            +

            + +
            + +

            + +

            +
            + + time_window_size = apply_filters('simbatfa_time_window_size', 30); + $this->check_back_time_windows = apply_filters('simbatfa_check_back_time_windows', 2); + $this->check_forward_time_windows = apply_filters('simbatfa_check_forward_time_windows', 1); + $this->check_forward_counter_window = apply_filters('simbatfa_check_forward_counter_window', 20); + + $this->salt_prefix = defined('AUTH_SALT') ? AUTH_SALT : wp_salt('auth'); + $this->pw_prefix = defined('AUTH_KEY') ? AUTH_KEY : get_site_option('auth_key'); + } + + /** + * Generate the current code for a specified user + * + * @param $user_id Integer - WordPress user ID + * + * @return String|Boolean - false if not set up + */ + public function get_current_code($user_id) { + + $tfa_priv_key_64 = get_user_meta($user_id, 'tfa_priv_key_64', true); + + if (!$tfa_priv_key_64) return false; + + return $this->generateOTP($user_id, $tfa_priv_key_64); + + } + + public function print_default_hmac_radios() { + + $setting = $this->tfa->get_option('tfa_default_hmac'); + if (!$setting) $setting = $this->default_hmac; + + $types = array('totp' => __('TOTP (time based - most common algorithm; used by Google Authenticator)', 'all-in-one-wp-security-and-firewall'), 'hotp' => __('HOTP (event based)', 'all-in-one-wp-security-and-firewall')); + + foreach ($types as $id => $name) { + print ' '.'
            \n"; + } + } + + public function generateOTP($user_ID, $key_b64, $length = 6, $counter = false) { + + $length = $length ? (int)$length : 6; + + $key = $this->decryptString($key_b64, $user_ID); + $alg = $this->get_user_otp_algorithm($user_ID); + + if ('hotp' == $alg) { + $db_counter = $this->getUserCounter($user_ID); + + $counter = $counter ? $counter : $db_counter; + $otp_res = $this->otp_helper->generateByCounter($key, $counter); + } else { + //time() is supposed to be UTC + $time = $counter ? $counter : time(); + $otp_res = $this->otp_helper->generateByTime($key, $this->time_window_size, $time); + } + $code = $otp_res->toHotp($length); + + return $code; + } + + /** + * Generate a list of OTP codes based on the user, key and time window + * + * @param Integer $user_ID - user ID + * @param String $key_b64 - the user's private key, in base64 format + * + * @return Array + */ + private function generate_otps_for_login_check($user_ID, $key_b64) { + $key = trim($this->decryptString($key_b64, $user_ID)); + $alg = $this->get_user_otp_algorithm($user_ID); + + if ('totp' == $alg) { + $otp_res = $this->otp_helper->generateByTimeWindow($key, $this->time_window_size, -1*$this->check_back_time_windows, $this->check_forward_time_windows); + } elseif ('hotp' == $alg) { + + $counter = $this->getUserCounter($user_ID); + + $otp_res = array(); + + for ($i = 0; $i < $this->check_forward_counter_window; $i++) { + $otp_res[] = $this->otp_helper->generateByCounter($key, $counter+$i); + } + } + return $otp_res; + } + + + /** + * Generate a private key for the user. + * + * @param Integer $user_id - WordPress user ID + * @param Boolean|String $key + * + * @return String + */ + public function addPrivateKey($user_id, $key = false) { + + // To work with Google Authenticator it has to be 10 bytes = 16 chars in base32 + $code = $key ? $key : strtoupper($this->randString(10)); + + // Encrypt the key + $code = $this->encryptString($code, $user_id); + + // Add private key to usermeta + update_user_meta($user_id, 'tfa_priv_key_64', $code); + + $alg = $this->get_user_otp_algorithm($user_id); + + // This hook is used for generation of emergency codes to accompany the key + do_action('simba_tfa_adding_private_key', $alg, $user_id, $code, $this); + + $this->changeUserAlgorithmTo($user_id, $alg); + + return $code; + } + + /** + * Port over keys that were encrypted with mcrypt and its non-compliant padding scheme, so that if the site is ever migrated to a server without mcrypt, they can still be decrypted + */ + public function potentially_port_private_keys() { + + $simba_tfa_priv_key_format = get_site_option('simba_tfa_priv_key_format', false); + + if ($simba_tfa_priv_key_format >= 1 || !function_exists('openssl_encrypt')) return; + + $attempts = 0; + $successes = 0; + + error_log("TFA: Beginning attempt to port private key encryption over to openssl"); + + global $wpdb; + + $sql = "SELECT user_id, meta_value FROM ".$wpdb->usermeta." WHERE meta_key = 'tfa_priv_key_64'"; + + $user_results = $wpdb->get_results($sql); + + foreach ($user_results as $u) { + $dec_openssl = $this->decryptString($u->meta_value, $u->user_id, true); + + $ported = false; + if ('' == $dec_openssl) { + + $attempts++; + + $dec_default = $this->decryptString($u->meta_value, $u->user_id); + + if ('' != $dec_default) { + + $enc = $this->encryptString($dec_default, $u->user_id); + + if ($enc) { + + $ported = true; + $successes++; + update_user_meta($u->user_id, 'tfa_priv_key_64', $enc); + } + } + + } + + if ($ported) { + error_log("TFA: Successfully ported the key for user with ID ".$u->user_id." over to openssl"); + } else { + error_log("TFA: Failed to port the key for user with ID ".$u->user_id." over to openssl"); + } + } + + if ($attempts == 0 || $successes > 0) update_site_option('simba_tfa_priv_key_format', 1); + + } + + /** + * This function will attempt to encrypt all the users private keys and emergency codes + * + * @return boolean|WP_Error - true on success or WP_Error on failure + */ + public function potentially_encrypt_private_keys() { + + error_log("TFA: Beginning attempt to encrypt private keys"); + + global $wpdb; + + $sql = "SELECT user_id, meta_value FROM ".$wpdb->usermeta." WHERE meta_key = 'tfa_priv_key_64' AND meta_value != ''"; + + $user_results = $wpdb->get_results($sql); + + if (null === $user_results) { + return new WP_Error( + 'failed_to_get_priv_keys', + __('Encrypt secrets feature not enabled: unable to get private keys from the database.', 'all-in-one-wp-security-and-firewall') + ); + } + + $number_ported = 0; + $number_failed = 0; + + foreach ($user_results as $u) { + $ported = false; + + $key = $this->decryptString($u->meta_value, $u->user_id); + $enc = $this->encryptString($key, $u->user_id, true); + + if ($enc) { + $ported = true; + update_user_meta($u->user_id, 'tfa_priv_key_64', $enc); + } + + $codes = get_user_meta($u->user_id, 'simba_tfa_emergency_codes_64', true); + if (!is_array($codes)) $codes = array(); + $enc_codes = array(); + + foreach ($codes as $code) { + $plain_code = $this->decryptString($code, $u->user_id); + $enc_codes[] = $this->encryptString($plain_code, $u->user_id, true); + } + + if (!empty($enc_codes)) update_user_meta($u->user_id, 'simba_tfa_emergency_codes_64', $enc_codes); + + if ($ported) { + $number_ported++; + } else { + $number_failed++; + error_log("TFA: Failed to encrypt the key for user with ID ".$u->user_id); + } + } + + error_log("TFA: Number of user keys successfully encrypted: ".$number_ported.", number which failed to encrypt: ".$number_failed); + + return true; + } + + public function getPrivateKeyPlain($enc, $user_ID) { + $dec = $this->decryptString($enc, $user_ID); + $this->potentially_port_private_keys(); + return $dec; + } + + /** + * @param Integer $user_id - WP user ID + * @param Boolean $generate_if_empty - generate some new codes if the list is empty + * + * @return String - human-usable codes, separated by ', ' (or a human-readable message, if there were none) + */ + public function get_emergency_codes_as_string($user_id, $generate_if_empty = false) { + + $codes = get_user_meta($user_id, 'simba_tfa_emergency_codes_64', true); + if (!is_array($codes)) $codes = array(); + + if ($generate_if_empty && empty($codes)) { + $tfa_priv_key = get_user_meta($user_id, 'tfa_priv_key_64', true); + $algorithm = get_user_meta($user_id, 'tfa_algorithm_type', true); + do_action('simba_tfa_emergency_codes_empty', $algorithm, $user_id, $tfa_priv_key, $this); + $codes = get_user_meta($user_id, 'simba_tfa_emergency_codes_64', true); + if (!is_array($codes)) $codes = array(); + } + + $emergency_str = ''; + + foreach ($codes as $p_code) { + $emergency_str .= $this->decryptString($p_code, $user_id).', '; + } + + $emergency_str = rtrim($emergency_str, ', '); + + $emergency_str = $emergency_str ? $emergency_str : ''.__('There are no emergency codes left. You will need to reset your private key to generate new ones.', 'all-in-one-wp-security-and-firewall').''; + + return $emergency_str; + } + + /** + * Check a code for a user (checks the code only - does not check activation status etc.) + * + * @param Integer $user_id - WP user ID + * @param String $user_code - the code to check + * @param Boolean $allow_emergency_code - whether to check against emergency codes + * + * @return Boolean + */ + public function check_code_for_user($user_id, $user_code, $allow_emergency_code = true) { + + $tfa_priv_key = get_user_meta($user_id, 'tfa_priv_key_64', true); + // $tfa_last_login = get_user_meta($user_id, 'tfa_last_login', true); // Unused + $tfa_last_pws_arr = get_user_meta($user_id, 'tfa_last_pws', true); + $tfa_last_pws = @$tfa_last_pws_arr ? $tfa_last_pws_arr : array(); + $alg = $this->get_user_otp_algorithm($user_id); + + $current_time_window = intval(time()/30); + + //Give the user 1,5 minutes time span to enter/retrieve the code + //Or check $this->check_forward_counter_window number of events if hotp + $codes = $this->generate_otps_for_login_check($user_id, $tfa_priv_key); + + //A recently used code was entered; that's not OK. + if (in_array($this->hash($user_code, $user_id), $tfa_last_pws)) return false; + + $match = false; + foreach ($codes as $index => $code) { + if (hash_equals(trim($code->toHotp(6)), trim($user_code))) { + $match = true; + $found_index = $index; + break; + } + } + + // Check emergency codes + if (!$match) { + $emergency_codes = $allow_emergency_code ? get_user_meta($user_id, 'simba_tfa_emergency_codes_64', true) : array(); + + if (!$emergency_codes) return $match; + + foreach ($emergency_codes as $key => $emergency_code) { + $dec = trim($this->decryptString(trim($emergency_code), $user_id)); + if (hash_equals($dec, trim($user_code))) { + $match = true; + // Remove emergency code + unset($emergency_codes[$key]); + break; + } + } + + // Update emergency codes array + if ($match) { + update_user_meta($user_id, 'simba_tfa_emergency_codes_64', $emergency_codes); + do_action('simba_tfa_emergency_code_used', $user_id, $emergency_codes); + } + + } else { + //Add the used code as well so it cant be used again + //Keep the two last codes + $tfa_last_pws[] = $this->hash($user_code, $user_id); + $nr_of_old_to_save = $alg == 'hotp' ? $this->check_forward_counter_window : $this->check_back_time_windows; + + if (count($tfa_last_pws) > $nr_of_old_to_save) array_splice($tfa_last_pws, 0, 1); + + update_user_meta($user_id, 'tfa_last_pws', $tfa_last_pws); + } + + if ($match) { + //Save the time window when the last successful login took place + update_user_meta($user_id, 'tfa_last_login', $current_time_window); + + //Update the counter if HOTP was used + if ($alg == 'hotp') { + $counter = $this->getUserCounter($user_id); + + $enc_new_counter = $this->encryptString($counter+1, $user_id); + update_user_meta($user_id, 'tfa_hotp_counter', $enc_new_counter); + + if ($found_index > 10) update_user_meta($user_id, 'tfa_hotp_off_sync', 1); + } + } + + return $match; + + } + + public function getUserCounter($user_ID) { + $enc_counter = get_user_meta($user_ID, 'tfa_hotp_counter', true); + return $enc_counter ? trim($this->decryptString(trim($enc_counter), $user_ID)) : ''; + } + + public function changeUserAlgorithmTo($user_id, $new_algorithm) { + update_user_meta($user_id, 'tfa_algorithm_type', $new_algorithm); + delete_user_meta($user_id, 'tfa_hotp_off_sync'); + + $counter_start = rand(13, 999999999); + $enc_counter_start = $this->encryptString($counter_start, $user_id); + + if ('hotp' == $new_algorithm) { + update_user_meta($user_id, 'tfa_hotp_counter', $enc_counter_start); + } else { + delete_user_meta($user_id, 'tfa_hotp_counter'); + } + } + + /** + * Whether HOTP or TOTP is being used + * + * @param Integer|Boolean $user_id - WordPress user ID, or false for the site-wide default + * + * @return String - 'hotp' or 'totp' + */ + public function get_user_otp_algorithm($user_id = false) { + + $setting = $user_id ? get_user_meta($user_id, 'tfa_algorithm_type', true) : false; + + $default_hmac = $this->tfa->get_option('tfa_default_hmac'); + if (!$default_hmac) $default_hmac = $this->default_hmac; + + return $setting ? $setting : $default_hmac; + } + + private function get_iv_size() { + // mcrypt first, for backwards compatibility + if (function_exists('mcrypt_get_iv_size')) { + return $GLOBALS['simba_two_factor_authentication']->is_mcrypt_deprecated() ? @mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC) : mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); + } elseif (function_exists('openssl_cipher_iv_length')) { + return openssl_cipher_iv_length('AES-128-CBC'); + } + throw new Exception('One of the mcrypt or openssl PHP modules needs to be installed'); + } + + private function encrypt($key, $string, $iv) { + // Prefer OpenSSL, because it uses correct padding, and its output can be decrypted by mcrypt - whereas, the converse is not true + if (function_exists('openssl_encrypt')) { + return openssl_encrypt($string, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv); + } elseif (function_exists('mcrypt_encrypt')) { + return $GLOBALS['simba_two_factor_authentication']->is_mcrypt_deprecated() ? @mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $string, MCRYPT_MODE_CBC, $iv) : mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $string, MCRYPT_MODE_CBC, $iv); + } + throw new Exception('One of the mcrypt or openssl PHP modules needs to be installed'); + } + + private function decrypt($key, $enc, $iv, $force_openssl = false) { + // Prefer mcrypt, because it can decrypt the output of both mcrypt_encrypt() and openssl_decrypt(), whereas (because of mcrypt_encrypt() using bad padding), the converse is not true + if (function_exists('mcrypt_decrypt') && !$force_openssl) { + return $GLOBALS['simba_two_factor_authentication']->is_mcrypt_deprecated() ? @mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $enc, MCRYPT_MODE_CBC, $iv) : mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $enc, MCRYPT_MODE_CBC, $iv); + } elseif (function_exists('openssl_decrypt')) { + $decrypted = openssl_decrypt($enc, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv); + if (false === $decrypted && !$force_openssl) { + $extra = function_exists('wp_debug_backtrace_summary') ? " backtrace: ".wp_debug_backtrace_summary() : ''; + error_log("TFA decryption failure: was your site migrated to a server without mcrypt? You may need to install mcrypt, or disable TFA, in order to successfully decrypt data that was previously encrypted with mcrypt.$extra"); + } + return $decrypted; + } + if ($force_openssl) return false; + throw new Exception('One of the mcrypt or openssl PHP modules needs to be installed'); + } + + public function encryptString($string, $salt_suffix, $force_encrypt = false) { + $key = ($this->tfa->get_option('tfa_encrypt_secrets') && defined('SIMBA_TFA_DB_ENCRYPTION_KEY')) ? base64_decode(SIMBA_TFA_DB_ENCRYPTION_KEY) : $this->hashAndBin($this->pw_prefix.$salt_suffix, $this->salt_prefix.$salt_suffix); + + if ($force_encrypt && defined('SIMBA_TFA_DB_ENCRYPTION_KEY')) $key = base64_decode(SIMBA_TFA_DB_ENCRYPTION_KEY); + + $iv_size = $this->get_iv_size(); + $iv = $GLOBALS['simba_two_factor_authentication']->random_bytes($iv_size); + + $enc = $this->encrypt($key, $string, $iv); + + if (false === $enc) return false; + + $enc = $iv.$enc; + $enc_b64 = base64_encode($enc); + return $enc_b64; + } + + private function decryptString($enc_b64, $salt_suffix, $force_openssl = false) { + $key = ($this->tfa->get_option('tfa_encrypt_secrets') && defined('SIMBA_TFA_DB_ENCRYPTION_KEY')) ? base64_decode(SIMBA_TFA_DB_ENCRYPTION_KEY) : $this->hashAndBin($this->pw_prefix.$salt_suffix, $this->salt_prefix.$salt_suffix); + + $iv_size = $this->get_iv_size(); + $enc_conc = bin2hex(base64_decode($enc_b64)); + + $iv = hex2bin(substr($enc_conc, 0, $iv_size*2)); + $enc = hex2bin(substr($enc_conc, $iv_size*2)); + + $string = $this->decrypt($key, $enc, $iv, $force_openssl); + + // Remove padding bytes + return rtrim($string, "\x00..\x1F"); + } + + private function hashAndBin($pw, $salt) { + $key = $this->hash($pw, $salt); + $key = pack('H*', $key); + // Yes: it's a null encryption key. See: https://wordpress.org/support/topic/warning-mcrypt_decrypt-key-of-size-0-not-supported-by-this-algorithm-only-k?replies=5#post-6806922 + // Basically: the original plugin had a bug here, which caused a null encryption key. This fails on PHP 5.6+. But, fixing it would break backwards compatibility for existing installs - and note that the only unknown once you have access to the encrypted data is the AUTH_SALT and AUTH_KEY constants... which means that actually the intended encryption was non-portable, + problematic if you lose your wp-config.php or try to migrate data to another site, or changes these values. (Normally changing these values only causes a compulsory re-log-in - but with the intended encryption in the original author's plugin, it'd actually cause a permanent lock-out until you disabled his plugin). If someone has read-access to the database, then it'd be reasonable to assume they have read-access to wp-config.php too: or at least, the number of attackers who can do one and not the other would be small. The "encryption's" not worth it. + // In summary: this isn't encryption, and is not intended to be. + return str_repeat(chr(0), 16); + } + + private function hash($pw, $salt) { + //$hash = hash_pbkdf2('sha256', $pw, $salt, 10); + //$hash = crypt($pw, '$5$'.$salt.'$'); + $hash = md5($salt.$pw); + return $hash; + } + + private function randString($len = 10) { + $chars = '23456789QWERTYUPASDFGHJKLZXCVBNM'; + $chars = str_split($chars); + shuffle($chars); + if (function_exists('random_int')) { + $code = ''; + for ($i = 1; $i <= $len; $i++) { + $code .= $chars[random_int(0, count($chars)-1)]; + } + } else { + $code = implode('', array_splice($chars, 0, $len)); + } + return $code; + } + +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/simba-tfa.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/simba-tfa.php new file mode 100755 index 00000000..4e0a8f0c --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/simba-tfa.php @@ -0,0 +1,1722 @@ +controllers[$provider_id] = new $class_name($this); + } + + // Process login form AJAX events + add_action('wp_ajax_nopriv_simbatfa-init-otp', array($this, 'tfaInitLogin')); + add_action('wp_ajax_simbatfa-init-otp', array($this, 'tfaInitLogin')); + + add_action('wp_ajax_simbatfa_shared_ajax', array($this, 'shared_ajax')); + + if (!class_exists('Simba_TFA_Login_Form_Integrations')) require_once($this->includes_dir().'/login-form-integrations.php'); + new Simba_TFA_Login_Form_Integrations($this); + + if (!class_exists('Simba_TFA_Encryption_Muplugin')) require_once($this->includes_dir().'/tfa-encryption-muplugin.php'); + $this->tfa_muplugin = new Simba_TFA_Encryption_Muplugin($this); + + // Add TFA column on admin users list + add_action('manage_users_columns', array($this, 'manage_users_columns_tfa')); + add_action('wpmu_users_columns', array($this, 'manage_users_columns_tfa')); + add_action('manage_users_custom_column', array($this, 'manage_users_custom_column_tfa'), 10, 3); + + // CSS for admin users screen + add_action('admin_print_styles-users.php', array($this, 'load_users_css'), 10, 0); + + add_action('admin_menu', array($this, 'admin_menu'), 9); + + add_action('admin_init', array($this, 'register_two_factor_auth_settings')); + add_action('init', array($this, 'init_parent')); + + if (!defined('TWO_FACTOR_DISABLE') || !TWO_FACTOR_DISABLE) { + + add_filter('application_password_did_authenticate', array($this, 'application_password_did_authenticate')); + + add_filter('authenticate', array($this, 'tfaVerifyCodeAndUser'), 99999999999, 3); + } + + add_action('show_user_profile', array($this, 'show_user_profile'), 1); + + add_action('enqueue_block_assets', array($this, 'enqueue_gutenberg_block_scripts')); + + add_filter('pre_update_option', array($this, 'setup_secret_encryption'), 10, 2); + + if (defined('DOING_AJAX') && DOING_AJAX && defined('WP_ADMIN') && WP_ADMIN && !empty($_REQUEST['action']) && 'simbatfa-init-otp' == $_REQUEST['action']) { + // Try to prevent PHP notices breaking the AJAX conversation + $this->output_buffering = true; + $this->logged = array(); + set_error_handler(array($this, 'get_php_errors'), E_ALL & ~E_STRICT); + ob_start(); + } + } + + /** + * Runs upon the WP action application_password_did_authenticate when a user successfully authenticates with an application password + * + * @param WP_User $user + */ + public function application_password_did_authenticate($user) { + + // This case is handled elsewhere + if (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) return; + + if (!in_array($user->ID, $this->application_passwords_authenticated)) { + $this->application_passwords_authenticated[] = $user->ID; + } + + } + + /** + * Runs upon the WP action show_user_profile + * + * @param WP_User $user - the user that the profile is for + */ + final public function show_user_profile($user) { + if ($user->ID !== get_current_user_id() || !$this->is_activated_for_user($user->ID)) return; + echo '

            '.__('Two Factor Authentication', 'all-in-one-wp-security-and-firewall').'

            '; + $settings_url = admin_url('admin.php').'?page='.$this->get_user_settings_page_slug(); + printf('%s', $settings_url, __('Go here for your two factor authentication settings...', 'all-in-one-wp-security-and-firewall')); + } + + /** + * Enqueues scripts for Gutenberg blocks. + * + * @return void + */ + public function enqueue_gutenberg_block_scripts() { + global $pagenow; + + if ($pagenow == 'post.php' || has_block('twofactor/user-settings')) { + $script_ver = (defined('WP_DEBUG') && WP_DEBUG) ? time() : filemtime($this->includes_dir() . '/gutenberg-blocks.js'); + wp_enqueue_script('twofactor-gutenberg-blocks', $this->includes_url() . '/gutenberg-blocks.js', array('wp-blocks', 'wp-element', 'wp-server-side-render'), $script_ver); + + wp_localize_script('twofactor-gutenberg-blocks', 'tfa_trans', + array( + 'block_title' => __('Two Factor Authentication Settings', 'two-factor-authentication'), + ) + ); + } + } + + /** + * This function is called via the filter `pre_update_option` if the option being saved is `tfa_encrypt_secrets` then we will proceed to setup the encryption + * + * @param mixed $value - the value of the option + * @param string $option_name - the option name + * + * @return mixed - returns 0 on error to prevent the feature from being turned on otherwise returns the value passed in + */ + public function setup_secret_encryption($value, $option_name) { + if ('tfa_encrypt_secrets' !== $option_name) return $value; + + if (!$this->tfa_muplugin->muplugin_exists() || !defined('SIMBA_TFA_DB_ENCRYPTION_KEY') || '' === SIMBA_TFA_DB_ENCRYPTION_KEY) { + $result = $this->tfa_muplugin->insert_contents(); + + if (is_wp_error($result)) { + add_settings_error('tfa_encrypt_secrets', $result->get_error_code(), $result->get_error_message()); + return 0; + } + + // We now need to include the file as it won't be loaded until WordPress refreshes but we want to use it now + include_once($this->tfa_muplugin->get_file_path()); + } + + $result = $this->get_controller('totp')->potentially_encrypt_private_keys(); + + if (is_wp_error($result)) { + add_settings_error('tfa_encrypt_secrets', $result->get_error_code(), $result->get_error_message()); + return 0; + } + + return $value; + } + + /** + * Runs upon the WP filter admin_menu + */ + final public function admin_menu() { + $this->get_controller('totp')->potentially_port_private_keys(); + } + + /** + * Give the filesystem path to the plugin's includes directory + * + * @return String + */ + public function includes_dir() { + return __DIR__.'/includes'; + } + + /** + * Give the URL for the plugin's includes directory + * + * @return String + */ + public function includes_url() { + return plugins_url('', __FILE__).'/includes'; + } + + /** + * Set URL slug for the plugin's option page. + * + * @param String Setting page URL slug. + * @return Void + */ + public function set_user_settings_page_slug($user_settings_page_slug) { + $this->user_settings_page_slug = $user_settings_page_slug; + } + + /** + * Get URL slug for the plugin's option page. + * + * @return String Setting page URL slug. + */ + public function get_user_settings_page_slug() { + return $this->user_settings_page_slug; + } + + /** + * Set settings page heading for plugin's option page + * + * @param String $settings_page_heading String. + * + * @return String + */ + public function set_settings_page_heading($settings_page_heading) { + $this->settings_page_heading = $settings_page_heading; + } + + /** + * Get settings page heading for plugin's option page. + * + * @return String Setting page heading. + */ + public function get_settings_page_heading() { + return $this->settings_page_heading; + } + + /** + * Set plugin translate url + * + * @param String $plugin_translate_url Plugin translation URL. + * @return Void + */ + public function set_plugin_translate_url($plugin_translate_url) { + $this->plugin_translate_url = $plugin_translate_url; + } + + /** + * Get plugin translate url + * + * @return String Plugin translate URL + */ + public function get_plugin_translate_url() { + return $this->plugin_translate_url; + } + + /** + * Set plugin premium version url + * + * @param String $premium_version_url Plugin premium version url. + * @return Void + */ + public function set_premium_version_url($premium_version_url) { + $this->premium_version_url = $premium_version_url; + } + + /** + * Get plugin premium version URL. + * + * @return String Plugin premium version URL. + */ + public function get_premium_version_url() { + return $this->premium_version_url; + } + + /** + * Set plugin FAQ URL + * + * @param String $faq_url Plugin FAQ URL. + * @return Void + */ + public function set_faq_url($faq_url) { + $this->faq_url = $faq_url; + } + + /** + * Get plugin FAQ URL. + * + * @return String Plugin FAQ URL. + */ + public function get_faq_url() { + return $this->faq_url; + } + + /** + * Set plugin site wide administration URL + * + * @param String $site_wide_administration_url Plugin site wide administration URL. + * @return Void + */ + public function set_site_wide_administration_url($site_wide_administration_url) { + $this->site_wide_administration_url = $site_wide_administration_url; + } + + /** + * Get plugin site wide administration URL. + * + * @return String Plugin site wide administration URL + */ + public function get_site_wide_administration_url() { + return $this->site_wide_administration_url; + } + + /** + * Give the filesystem path to the plugin's templates directory + * + * @return String + */ + public function templates_dir() { + return __DIR__.'/templates'; + } + + /** + * Include the user settings page code + */ + public function show_dashboard_user_settings_page() { + $this->include_template('user-settings.php'); + } + + /** + * Enqueue CSS styling on the users page + */ + public function load_users_css() { + $css_version = (defined('WP_DEBUG') && WP_DEBUG) ? time() : filemtime($this->includes_dir().'/users.css'); + wp_enqueue_style( + 'tfa-users-css', + $this->includes_url().'/users.css', + array(), + $css_version, + 'screen' + ); + } + + /** + * Add the 2FA label to the users list table header. + * + * @param Array $columns Table columns. + * + * @return Array + */ + public function manage_users_columns_tfa($columns = array()) { + $columns['tfa-status'] = __('2FA', 'all-in-one-wp-security-and-firewall'); + return $columns; + } + + /** + * Add status into TFA column. + * + * @param String $value String. + * @param String $column_name Column name. + * @param Integer $user_id User ID. + * + * @return String + */ + public function manage_users_custom_column_tfa($value = '', $column_name = '', $user_id = 0) { + + // Only for this column name. + if ('tfa-status' === $column_name) { + + if (!$this->is_activated_for_user($user_id)) { + $value = '—'; + } elseif ($this->is_activated_by_user($user_id)) { + // Use value. + $value = ''; + } else { + // No group. + $value = ''; + } + } + + return $value; + } + + /** + * Paint out an admin notice + * + * @param String $message - the caller should already have taken care of any escaping + * @param String $class + */ + public function show_admin_warning($message, $class = 'updated') { + echo '
            '."

            $message

            "; + } + + /** + * Returns all two factor authentication setting name => group pairs. + * + * @return Array + */ + private function get_config_keys() { + global $wp_roles; + + if (!isset($wp_roles)) $wp_roles = new WP_Roles(); + + $keys = array( + 'tfa_requireafter' => 'tfa_user_roles_required_group', + 'tfa_require_enforce_after' => 'tfa_user_roles_required_group', + 'tfa_if_required_redirect_to' => 'tfa_user_roles_required_group', + 'tfa_hide_turn_off' => 'tfa_user_roles_required_group', + 'tfa_trusted_for' => 'tfa_user_roles_trusted_group', + 'tfa_wc_add_section' => 'simba_tfa_woocommerce_group', + 'tfa_bot_protection' => 'simba_tfa_woocommerce_group', + 'tfa_default_hmac' => 'simba_tfa_default_hmac_group', + 'tfa_encrypt_secrets' => 'simba_tfa_encrypt_secrets_group', + 'tfa_xmlrpc_on' => 'tfa_xmlrpc_status_group', + ); + + foreach ($wp_roles->role_names as $id => $name) { + $keys['tfa_'.$id] = 'tfa_user_roles_group'; + $keys['tfa_trusted_'.$id] = 'tfa_user_roles_trusted_group'; + $keys['tfa_required_'.$id] = 'tfa_user_roles_required_group'; + } + + if (is_multisite()) { + $keys['tfa__super_admin'] = 'tfa_user_roles_group'; + $keys['tfa_trusted__super_admin'] = 'tfa_user_roles_trusted_group'; + $keys['tfa_required__super_admin'] = 'tfa_user_roles_required_group'; + } + + return $keys; + } + + /** + * Registers all two factor authentication settings. Runs upon the WP action admin_init. + */ + public function register_two_factor_auth_settings() { + $config_keys = $this->get_config_keys(); + + foreach ($config_keys as $name => $group) { + register_setting($group, $name); + } + } + + /** + * Returns all two factor authentication options from the WP database. + * + * @return Array + */ + public function get_configs() { + $config_keys = $this->get_config_keys(); + + $configs = array(); + + foreach (array_keys($config_keys) as $name) { + if (false !== $this->get_option($name)) { + $configs[$name] = $this->get_option($name); + } + } + + return $configs; + } + + /** + * Sets two factor authentication options from array. + * + * @param Array $configs + * + * @return Boolean + */ + public function set_configs($configs) { + $result = false; + + foreach ($configs as $key => $value) { + $result = $this->update_option($key, $value) ? true : $result; + } + + return $result; + } + + /** + * Deletes all two factor authentication options from the WP database. + * + * @return Void + */ + public function delete_configs() { + $config_keys = $this->get_config_keys(); + + foreach (array_keys($config_keys) as $name) { + $this->delete_option($name); + } + } + + /** + * See whether TFA is available or not for a particular user - i.e. whether the administrator has permitted it for their user level + * + * @param Integer $user_id - WordPress user ID + * + * @return Boolean + */ + public function is_activated_for_user($user_id) { + + if (empty($user_id)) return false; + + // Super admin is not a role (they are admins with an extra attribute); needs separate handling + if (is_multisite() && is_super_admin($user_id)) { + // This is always a final decision - we don't want it to drop through to the 'admin' role's setting + $role = '_super_admin'; + $db_val = $this->get_option('tfa_'.$role); + // Defaults to true if no setting has been saved + return (false === $db_val || $db_val) ? true : false; + } + + $roles = $this->get_user_roles($user_id); + + // N.B. This populates with roles on the current site within a multisite + foreach ($roles as $role) { + $db_val = $this->get_option('tfa_'.$role); + if (false === $db_val || $db_val) return true; + } + + return false; + + } + + /** + * Get all user roles for a given user (if on multisite, amalgamates all roles from all sites) + * + * @param Integer $user_id - WordPress user ID + * + * @return Array + */ + protected function get_user_roles($user_id) { + + // Get roles on the main site + $user = new WP_User($user_id); + $roles = (array) $user->roles; + + // On multisite, also check roles on non-main sites + if (is_multisite()) { + global $wpdb, $table_prefix; + $roles_db = $wpdb->get_results($wpdb->prepare("SELECT meta_key, meta_value FROM {$wpdb->usermeta} WHERE user_id=%d AND meta_key LIKE '".esc_sql($table_prefix)."%_capabilities'", $user_id)); + if (is_array($roles_db)) { + foreach ($roles_db as $role_info) { + if (empty($role_info->meta_key) || !preg_match('/^'.$table_prefix.'\d+_capabilities$/', $role_info->meta_key) || empty($role_info->meta_value) || !preg_match('/^a:/', $role_info->meta_value)) continue; + $site_roles = $this->unserialize($role_info->meta_value); + if (!is_array($site_roles)) continue; + foreach ($site_roles as $role => $active) { + if ($active && !in_array($role, $roles)) $roles[] = $role; + } + } + } + } + + return $roles; + } + + /** + * Check if TFA is required for a specified user + * + * N.B. - This doesn't check is_activated_for_user() - the caller would normally want to do that first + * + * @param $user_id Integer - the WP user ID + * + * @return Boolean + */ + public function is_required_for_user($user_id) { + return apply_filters('simba_tfa_required_for_user', $this->user_property_active($user_id, 'required_'), $user_id); + } + + /** + * See if a particular user property is active + * + * @param Integer $user_id + * @param String $prefix - e.g. "required_", "trusted_" + * + * @return Boolean + */ + public function user_property_active($user_id, $prefix = 'required_') { + + if (empty($user_id)) return false; + + // Super admin is not a role (they are admins with an extra attribute); needs separate handling + if (is_multisite() && is_super_admin($user_id)) { + // This is always a final decision - we don't want it to drop through to the 'admin' role's setting + $role = '_super_admin'; + $db_val = $this->get_option('tfa_'.$prefix.$role); + return $db_val ? true : false; + } + + $roles = $this->get_user_roles($user_id); + + foreach ($roles as $role) { + $db_val = $this->get_option('tfa_'.$prefix.$role); + if ($db_val) return true; + } + + return false; + + } + + /** + * Whether TFA is activated by a specific user. Note that this doesn't check if TFA is enabled for the user's role; the caller should check that first. + * + * @param Integer $user_id + * + * @return Boolean + */ + public function is_activated_by_user($user_id) { + $enabled = get_user_meta($user_id, 'tfa_enable_tfa', true); + return !empty($enabled); + } + + /** + * Get a list of trusted devices for the user + * + * @param Integer|Boolean $user_id - WordPress user ID, or false for the current user + * + * @return Array + */ + public function user_get_trusted_devices($user_id = false) { + + if (false === $user_id) { + global $current_user; + $user_id = $current_user->ID; + } + + $trusted_devices = get_user_meta($user_id, 'tfa_trusted_devices', true); + + if (!is_array($trusted_devices)) $trusted_devices = array(); + + return $trusted_devices; + } + + /** + * Trust the current device + * + * @param Integer $user_id - WordPress user ID + * @param Integer $trusted_for - time to trust for, in days + */ + public function trust_device($user_id, $trusted_for) { + + $trusted_devices = $this->user_get_trusted_devices($user_id); + + $time_now = time(); + + foreach ($trusted_devices as $k => $device) { + if (empty($device['until']) || $device['until'] <= $time_now) unset($trusted_devices[$k]); + } + + $until = $time_now + $trusted_for * 86400; + + $token = bin2hex($this->random_bytes(40)); + + $trusted_devices[] = array( + 'ip' => $_SERVER['REMOTE_ADDR'], + 'until' => $until, + 'user_agent' => empty($_SERVER['HTTP_USER_AGENT']) ? '' : (string) $_SERVER['HTTP_USER_AGENT'], + 'token' => $token + ); + + $this->user_set_trusted_devices($user_id, $trusted_devices); + + $this->set_cookie('simbatfa_trust_token', $token, $until); + } + + /** + * Returns true if running on a PHP version on which mcrypt has been deprecated + * + * @return Boolean + */ + public function is_mcrypt_deprecated() { + return (7 == PHP_MAJOR_VERSION && PHP_MINOR_VERSION >= 1); + } + + /** + * Return the specified number of bytes + * + * @param Integer $bytes + * + * @throws Exception + * + * @return String + */ + public function random_bytes($bytes) { + if (function_exists('random_bytes')) { + return random_bytes($bytes); + } elseif (function_exists('mcrypt_create_iv')) { + return $this->is_mcrypt_deprecated() ? @mcrypt_create_iv($bytes, MCRYPT_RAND) : mcrypt_create_iv($bytes, MCRYPT_RAND); + } elseif (function_exists('openssl_random_pseudo_bytes')) { + return openssl_random_pseudo_bytes($bytes); + } + throw new Exception('One of the mcrypt or openssl PHP modules needs to be installed'); + } + + /** + * Set a cookie so that, however we logged in, it can be found + * + * @param String $name - the cookie name + * @param String $value - the cookie value + * @param Integer $expires - when the cookie expires, in epoch time. Defaults to 24 hours' time. Values in the past cause cookie deletion. + */ + protected function set_cookie($name, $value, $expires = null) { + if (null === $expires) $expires = time() + 86400; + $secure = is_ssl(); + $secure_logged_in_cookie = ($secure && 'https' === parse_url(get_option('home'), PHP_URL_SCHEME)); + $secure = apply_filters('secure_auth_cookie', $secure, get_current_user_id()); + $secure_logged_in_cookie = apply_filters('secure_logged_in_cookie', $secure_logged_in_cookie, get_current_user_id(), $secure); + + setcookie($name, $value, $expires, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, $secure, true); + setcookie($name, $value, $expires, COOKIEPATH, COOKIE_DOMAIN, $secure_logged_in_cookie, true); + if (COOKIEPATH != SITECOOKIEPATH) { + setcookie($name, $value, $expires, SITECOOKIEPATH, COOKIE_DOMAIN, $secure_logged_in_cookie, true); + } + } + + /** + * Get a list of trusted devices for the user + * + * @param Integer $user_id - WordPress user ID + * @param Array $trusted_devices - the list of devices + */ + public function user_set_trusted_devices($user_id, $trusted_devices) { + update_user_meta($user_id, 'tfa_trusted_devices', $trusted_devices); + } + + /** + * Get the user capability needed for managing TFA users. + * You'll want to think carefully about changing this to a non-admin, as it can give the ability to lock admins out (though, if you have FTP/files access, you can always disable TFA or any plugin) + * + * @return String + */ + public function get_management_capability() { + return apply_filters('simba_tfa_management_capability', 'manage_options'); + } + + /** + * Used with set_error_handler() + * + * @param Integer $errno + * @param String $errstr + * @param String $errfile + * @param Integer $errline + * + * @return Boolean + */ + final public function get_php_errors($errno, $errstr, $errfile, $errline) { + if (0 == error_reporting()) return true; + $logline = $this->php_error_to_logline($errno, $errstr, $errfile, $errline); + $this->logged[] = $logline; + # Don't pass it up the chain (since it's going to be output to the user always) + return true; + } + + public function php_error_to_logline($errno, $errstr, $errfile, $errline) { + switch ($errno) { + case 1: $e_type = 'E_ERROR'; break; + case 2: $e_type = 'E_WARNING'; break; + case 4: $e_type = 'E_PARSE'; break; + case 8: $e_type = 'E_NOTICE'; break; + case 16: $e_type = 'E_CORE_ERROR'; break; + case 32: $e_type = 'E_CORE_WARNING'; break; + case 64: $e_type = 'E_COMPILE_ERROR'; break; + case 128: $e_type = 'E_COMPILE_WARNING'; break; + case 256: $e_type = 'E_USER_ERROR'; break; + case 512: $e_type = 'E_USER_WARNING'; break; + case 1024: $e_type = 'E_USER_NOTICE'; break; + case 2048: $e_type = 'E_STRICT'; break; + case 4096: $e_type = 'E_RECOVERABLE_ERROR'; break; + case 8192: $e_type = 'E_DEPRECATED'; break; + case 16384: $e_type = 'E_USER_DEPRECATED'; break; + case 30719: $e_type = 'E_ALL'; break; + default: $e_type = "E_UNKNOWN ($errno)"; break; + } + + if (!is_string($errstr)) $errstr = serialize($errstr); + + if (0 === strpos($errfile, ABSPATH)) $errfile = substr($errfile, strlen(ABSPATH)); + + return "PHP event: code $e_type: $errstr (line $errline, $errfile)"; + + } + + /** + * Runs upon the WordPress 'init' action. + */ + final public function init_parent() { + if ((!is_admin() || (defined('DOING_AJAX') && DOING_AJAX)) && is_user_logged_in() && file_exists($this->includes_dir().'/tfa_frontend.php')) { + $this->load_frontend(); + } else { + add_shortcode('twofactor_user_settings', array($this, 'shortcode_when_not_logged_in')); + } + } + + /** + * Return the TOTP provider object. + * + * @param String $controller_id - which controller + * + * @return Simba_TFA_Provider_totp + */ + public function get_controller($controller_id = 'totp') { + return $this->controllers[$controller_id]; + } + + /** + * Return all OTP controllers + * + * @return Array + */ + public function get_controllers() { + return $this->controllers; + } + + /** + * Deprecated synonym for get_controller('totp') + * + * @return Simba_TFA_Provider_totp + */ + public function get_totp_controller() { + trigger_error("Deprecated: Call get_controller('totp'), not get_totp_controller()", E_USER_WARNING); + return $this->get_controller('totp'); + } + + /** + * "Shared" - i.e. could be called from either front-end or back-end + */ + final public function shared_ajax() { + + if (empty($_POST['subaction']) || empty($_POST['nonce']) || !is_user_logged_in() || !wp_verify_nonce($_POST['nonce'], 'tfa_shared_nonce')) die('Security check (3).'); + + global $current_user; + + $subaction = $_POST['subaction']; + + if ('refreshotp' == $subaction) { + + $code = $this->get_controller('totp')->get_current_code($current_user->ID); + + if (false === $code) die(json_encode(array('code' => ''))); + + die(json_encode(array('code' => $code))); + + } elseif ('untrust_device' == $subaction && isset($_POST['device_id'])) { + $this->untrust_device(stripslashes($_POST['device_id'])); + ob_start(); + $this->include_template('trusted-devices-inner-box.php', array('trusted_devices' => $this->user_get_trusted_devices())); + echo json_encode(array('trusted_list' => ob_get_clean())); + } + + exit; + + } + + /** + * Mark a device as untrusted for the current user + * + * @param String $device_id + */ + protected function untrust_device($device_id) { + + $trusted_devices = $this->user_get_trusted_devices(); + + unset($trusted_devices[$device_id]); + + global $current_user; + $current_user_id = $current_user->ID; + + $this->user_set_trusted_devices($current_user_id, $trusted_devices); + + } + + /** + * Called upon the AJAX action simbatfa-init-otp . Will die. + * + * Uses these keys from $_POST: user + */ + public function tfaInitLogin() { + + if (empty($_POST['user'])) die('Security check (2).'); + + if (defined('TWO_FACTOR_DISABLE') && TWO_FACTOR_DISABLE) { + $res = array('result' => false, 'user_can_trust' => false); + } else { + + if (!function_exists('sanitize_user')) require_once ABSPATH.WPINC.'/formatting.php'; + + // WP's password-checking sanitizes the supplied user, so we must do the same to check if TFA is enabled for them + $auth_info = array('log' => sanitize_user(stripslashes((string)$_POST['user']))); + + if (!empty($_COOKIE['simbatfa_trust_token'])) $auth_info['trust_token'] = (string) $_COOKIE['simbatfa_trust_token']; + + $res = $this->pre_auth($auth_info, 'array'); + } + + $results = array( + 'jsonstarter' => 'justhere', + 'status' => $res['result'], + ); + + if (!empty($res['user_can_trust'])) { + $results['user_can_trust'] = 1; + if (!empty($res['user_already_trusted'])) $results['user_already_trusted'] = 1; + } + + + if (!empty($this->output_buffering)) { + if (!empty($this->logged)) { + $results['php_output'] = $this->logged; + } + restore_error_handler(); + $buffered = ob_get_clean(); + if ($buffered) $results['extra_output'] = $buffered; + } + + $results = apply_filters('simbatfa_check_tfa_requirements_ajax_response', $results); + + echo json_encode($results); + + exit; + } + + /** + * Enable or disable TFA for a user + * + * @param Integer $user_id - the WordPress user ID + * @param String $setting - either "true" (to turn on) or "false" (to turn off) + */ + public function change_tfa_enabled_status($user_id, $setting) { + $previously_enabled = $this->is_activated_by_user($user_id) ? 1 : 0; + $setting = ('true' === $setting) ? 1 : 0; + update_user_meta($user_id, 'tfa_enable_tfa', $setting); + do_action('simba_tfa_activation_status_saved', $user_id, $setting, $previously_enabled, $this); + } + + /** + * Here's where the login action happens. Called on the WP 'authenticate' action (which also happens when wp-login.php loads, so parameters need checking). + * + * @param WP_Error|WP_User $user + * @param String $username - this is not necessarily the WP username; it is whatever was typed in the form, so can be an email address + * @param String $password + * + * @return WP_Error|WP_User + */ + public function tfaVerifyCodeAndUser($user, $username, $password) { + + // Do not require a TFA code when authenticating via cookie (or other non-login-form mechanism) + if ('' === $username && is_multisite()) return $user; + + // When both the AIOWPS and Two Factor Authentication plugins are active, this function is called more than once; that should be short-circuited. + if (isset(self::$is_authenticated[$this->authentication_slug]) && self::$is_authenticated[$this->authentication_slug]) { + return $user; + } + + if (is_a($user, 'WP_User') && !empty($user->ID)) { + if (in_array($user->ID, $this->application_passwords_authenticated)) { + // User authenticated via an application password (and thus - see wp_authenticate_application_password - via an API request). Do not require a TFA code. + return $user; + } + } + + $original_user = $user; + $params = stripslashes_deep($_POST); + + // If (only) the error was a wrong password, but it looks like the user appended a TFA code to their password, then have another go + if (is_wp_error($user) && array('incorrect_password') == $user->get_error_codes() && !isset($params['two_factor_code']) && false !== ($from_password = apply_filters('simba_tfa_tfa_from_password', false, $password))) { + // This forces a new password authentication below + $user = false; + } + + if (is_wp_error($user)) { + $ret = $user; + } else { + + if (is_object($user) && isset($user->ID) && isset($user->user_login)) { + $params['log'] = $user->user_login; + // Confirm that this is definitely a username regardless of its format + $may_be_email = false; + } else { + $params['log'] = $username; + $may_be_email = true; + } + + $params['caller'] = $_SERVER['PHP_SELF'] ? $_SERVER['PHP_SELF'] : $_SERVER['REQUEST_URI']; + if (!empty($_COOKIE['simbatfa_trust_token'])) $params['trust_token'] = (string) $_COOKIE['simbatfa_trust_token']; + + if (isset($from_password) && false !== $from_password) { + // Support login forms that can't be hooked via appending to the password + $speculatively_try_appendage = true; + $params['two_factor_code'] = $from_password['tfa_code']; + } + + $code_ok = $this->authorise_user_from_login($params, $may_be_email); + + if (is_wp_error($code_ok)) { + $ret = $code_ok; + } elseif (!$code_ok) { + $encryption_enabled = $this->get_option('tfa_encrypt_secrets'); + $additional = ($encryption_enabled && (!defined('SIMBA_TFA_DB_ENCRYPTION_KEY') || '' === SIMBA_TFA_DB_ENCRYPTION_KEY)) ? ' ' . htmlspecialchars(__('The "encrypt secrets" feature is currently enabled, but no encryption key has been found (set via the SIMBA_TFA_DB_ENCRYPTION_KEY constant).', 'all-in-one-wp-security-and-firewall').' '.__('This indicates that either setup failed, or your WordPress installation has been corrupted.', 'all-in-one-wp-security-and-firewall')) . ' '. __('Go here for the FAQs, which explain how a website owner can de-activate the plugin without needing to login.', 'all-in-one-wp-security-and-firewall') .'' : ''; + $ret = new WP_Error('authentication_failed', ''.__('Error:', 'all-in-one-wp-security-and-firewall').' '.apply_filters('simba_tfa_message_code_incorrect', __('The one-time password (TFA code) you entered was incorrect.', 'all-in-one-wp-security-and-firewall') . $additional)); + if (is_a($user, 'WP_User')) $this->log_incorrect_tfa_code_attempt($user); + } elseif ($user) { + $ret = $user; + } else { + + if (!empty($speculatively_try_appendage) && true === $code_ok) { + $password = $from_password['password']; + } + + $username_is_email = false; + + if (function_exists('wp_authenticate_username_password') && $may_be_email && filter_var($username, FILTER_VALIDATE_EMAIL)) { + global $wpdb; + // This has to match self::authorise_user_from_login() + $response = $wpdb->get_row($wpdb->prepare("SELECT ID, user_registered from ".$wpdb->users." WHERE user_email=%s", $username)); + if (is_object($response)) $username_is_email = true; + } + + $ret = $username_is_email ? wp_authenticate_email_password(null, $username, $password) : wp_authenticate_username_password(null, $username, $password); + } + + } + + $ret = apply_filters('simbatfa_verify_code_and_user_result', $ret, $original_user, $username, $password); + + // If the TFA code was actually validated (not just not required, for example), then $code_ok is (boolean)true + if (isset($code_ok) && true === $code_ok && is_a($ret, 'WP_User')) { + // Though $_SERVER['SERVER_NAME'] can't always be trusted (if the webserver is misconfigured), anyone using this already has password and TFA clearance. + if (!empty($params['simba_tfa_mark_as_trusted']) && $this->user_can_trust($ret->ID) && (is_ssl() || (!empty($_SERVER['SERVER_NAME']) && ('localhost' == $_SERVER['SERVER_NAME'] ||'127.0.0.1' == $_SERVER['SERVER_NAME'] || preg_match('/\.localdomain$/', $_SERVER['SERVER_NAME']))))) { + + $trusted_for = $this->get_option('tfa_trusted_for'); + $trusted_for = (false === $trusted_for) ? 30 : (string) absint($trusted_for); + + $this->trust_device($ret->ID, $trusted_for); + } + } + + self::$is_authenticated[$this->authentication_slug] = true; + + return $ret; + } + + /** + * Save incorrect TFA code attempts in database + * + * @param Array $tfa_incorrect_code_attempts - all user info with incorrect code attempts + * @param Boolean $update - update in option table + * + * @return Void + */ + private function save_incorrect_tfa_code_attempts($tfa_incorrect_code_attempts, $update = false) { + if ($update) { + update_site_option('tfa_incorrect_code_attempts', $tfa_incorrect_code_attempts); + } else { + add_site_option('tfa_incorrect_code_attempts', $tfa_incorrect_code_attempts); + } + } + + /** + * Remove old incorrect TFA code attempts + * + * @param Array $user_info - user invalid attempts + * + * @return Array + */ + private function remove_incorrect_tfa_code_old_attempts($user_info) { + $splice_recs = 0; + foreach ($user_info['attempts'] as $attempt) { + $mins_diff = (time() - $attempt['activity_time']) / 60; + if ($mins_diff >= TFA_INCORRECT_ATTEMPTS_WITHIN_MINUTES_LIMIT) { + $splice_recs++; + } + } + if ($splice_recs > 0) { + array_splice($user_info['attempts'], 0, $splice_recs); // remove all older attempts. + } + return $user_info; + } + + /** + * Log incorrect TFA code attempt and email user if attempt exceeded limit + * + * @param WP_User $user - user object for the user logging in + * + * @return Void + */ + private function log_incorrect_tfa_code_attempt($user) { + $tfa_incorrect_code_attempts = get_site_option('tfa_incorrect_code_attempts'); + if (empty($tfa_incorrect_code_attempts)) $tfa_incorrect_code_attempts = array(); + $userinfo_added = false; + $update = false; + if (count($tfa_incorrect_code_attempts) > 0) { + foreach ($tfa_incorrect_code_attempts as $i => $user_info) { + $user_info = $this->remove_incorrect_tfa_code_old_attempts($user_info); // remove old (before 30 mins) incorrect tfa code attempts by users + if (empty($user_info['attempts'])) { + unset($tfa_incorrect_code_attempts[$i]); + continue; + } + if ($user_info['user_id'] == $user->ID) { + $userinfo_added = true; + if (count($user_info['attempts']) >= TFA_INCORRECT_MAX_ATTEMPTS_ALLOWED_LIMIT && empty($user_info['mailsent'])) { + $this->notify_incorrect_tfa_code_attempts($user_info, $user->user_email); // if incorrect tfa attempts are more than max allowed notify user by email that some one else has your password. + $user_info['mailsent'] = 1; + } else { + if (0 == count($user_info['attempts'])) $user_info['mailsent'] = 0; + $user_info['attempts'][] = $this->get_incorrect_tfa_attempt_info(); //add new incorrect attempt for existing user. + } + } + $tfa_incorrect_code_attempts[$i] = $user_info; + } + $update = true; + } + if (false == $userinfo_added) { + $tfa_incorrect_code_attempts[] = $this->get_incorrect_tfa_user_info($user); //add incorrect attempt with username etc info. + } + $this->save_incorrect_tfa_code_attempts($tfa_incorrect_code_attempts, $update); + } + + /** + * Get incorrect attempt info time and IP address to save in database + * + * @return Array + */ + private function get_incorrect_tfa_attempt_info() { + $ip_address = apply_filters('tfa_user_ip_address', $_SERVER['REMOTE_ADDR']); + return array('activity_time' => time(), 'ip_address' => $ip_address); + } + + /** + * Get incorrect attempt with userinfo to save in database + * + * @param WP_User $user - logging in user object + * + * @return Array + */ + private function get_incorrect_tfa_user_info($user) { + return array('user_id' => $user->ID, 'attempts' => array($this->get_incorrect_tfa_attempt_info())); + } + + /** + * Notify user might be someone else has your possword + * + * @param Array $user_info - user's incorrect attempt information + * @param String $user_email - user email address notification to be sent. + */ + private function notify_incorrect_tfa_code_attempts($user_info, $user_email) { + $subject = __('Incorrect TFA code attempts', 'all-in-one-wp-security-and-firewall'); + $email_msg = sprintf(__('There has been an incorrect TFA code entered for logging in to your account %s.', 'all-in-one-wp-security-and-firewall'), $user_info['username']) . "\n\n" . + __('Attempts', 'all-in-one-wp-security-and-firewall') . "\n\n"; + foreach ($user_info['attempts'] as $index => $attempt) { + $email_msg.= ($index+1) . '. ' . wp_date('F j, Y g:i a', $attempt['activity_time'], wp_timezone()) . ' ' . __('from', 'all-in-one-wp-security-and-firewall') . ' ' . $attempt['ip_address']. "\n"; + } + $email_msg.= "\n" . __('If the above attempts were not by you then someone else has your password.', 'all-in-one-wp-security-and-firewall') . "\n" . + __('TFA codes are checked only after the password has been successfully checked.', 'all-in-one-wp-security-and-firewall') . "\n\n" . + __('Please change your password urgently.', 'all-in-one-wp-security-and-firewall') . "\n"; + $mail_sent = wp_mail($user_email, $subject, $email_msg); + } + + // N.B. - This doesn't check is_activated_for_user() - the caller would normally want to do that first + public function user_can_trust($user_id) { + // Default is false because this is a new feature and we don't want to surprise existing users by granting broader access than they expected upon an upgrade + return apply_filters('simba_tfa_user_can_trust', false, $user_id); + } + + /** + * Should the user be asked for a TFA code? And optionally, is the user allowed to trust devices? + * + * @param Array $params - the key used is 'log', indicating the username or email address + * @param String $response_format - 'simple' (historic format) or 'array' (richer info) + * + * @return Boolean + */ + public function pre_auth($params, $response_format = 'simple') { + global $wpdb; + + $query = filter_var($params['log'], FILTER_VALIDATE_EMAIL) ? $wpdb->prepare("SELECT ID, user_email from ".$wpdb->users." WHERE user_email=%s", $params['log']) : $wpdb->prepare("SELECT ID, user_email from ".$wpdb->users." WHERE user_login=%s", $params['log']); + $user = $wpdb->get_row($query); + + if (!$user && filter_var($params['log'], FILTER_VALIDATE_EMAIL)) { + // Corner-case: login looks like an email, but is a username rather than email address + $user = $wpdb->get_row($wpdb->prepare("SELECT ID, user_email from ".$wpdb->users." WHERE user_login=%s", $params['log'])); + } + + $is_activated_for_user = true; + $is_activated_by_user = false; + + $result = false; + + $totp_controller = $this->get_controller('totp'); + + if ($user) { + $tfa_priv_key = get_user_meta($user->ID, 'tfa_priv_key_64', true); + $is_activated_for_user = $this->is_activated_for_user($user->ID); + $is_activated_by_user = $this->is_activated_by_user($user->ID); + + if ($is_activated_for_user && $is_activated_by_user) { + + // No private key yet, generate one. This shouldn't really be possible. + if (!$tfa_priv_key) $tfa_priv_key = $totp_controller->addPrivateKey($user->ID); + + $code = $totp_controller->generateOTP($user->ID, $tfa_priv_key); + + $result = true; + } + } + + if ('array' != $response_format) return $result; + + $ret = array('result' => $result); + + if ($result) { + $ret['user_can_trust'] = $this->user_can_trust($user->ID); + if (!empty($params['trust_token']) && $this->user_trust_token_valid($user->ID, $params['trust_token'])) { + $ret['user_already_trusted'] = 1; + } + } + + return $ret; + } + + /** + * Print the radio buttons for enabling/disabling TFA + * + * @param Integer $user_id - the WordPress user ID + * @param Boolean $long_label - whether to use a long label rather than a short one + * @param String $style - valid values are "show_current" and "require_current" + */ + public function paint_enable_tfa_radios($user_id, $long_label = false, $style = 'show_current') { + + if (!$user_id) return; + + if ('require_current' != $style) $style = 'show_current'; + + $is_required = $this->is_required_for_user($user_id); + $is_activated = $this->is_activated_by_user($user_id); + + if ($is_required) { + $require_after = absint($this->get_option('tfa_requireafter')); + echo '

            '.sprintf(__('N.B. This site is configured to forbid you to log in if you disable two-factor authentication after your account is %d days old', 'all-in-one-wp-security-and-firewall'), $require_after).'

            '; + } + + $tfa_enabled_label = $long_label ? __('Enable two-factor authentication', 'all-in-one-wp-security-and-firewall') : __('Enabled', 'all-in-one-wp-security-and-firewall'); + + if ('show_current' == $style) { + $tfa_enabled_label .= ' '.sprintf(__('(Current code: %s)', 'all-in-one-wp-security-and-firewall'), $this->get_controller('totp')->current_otp_code($user_id)); + } elseif ('require_current' == $style) { + $tfa_enabled_label .= ' '.sprintf(__('(you must enter the current code: %s)', 'all-in-one-wp-security-and-firewall'), ''); + } + + $show_disable = ((is_multisite() && is_super_admin()) || (!is_multisite() && current_user_can($this->get_management_capability())) || false == $is_activated || !$is_required || !$this->get_option('tfa_hide_turn_off')) ? true : false; + + $tfa_disabled_label = $long_label ? __('Disable two-factor authentication', 'all-in-one-wp-security-and-firewall') : __('Disabled', 'all-in-one-wp-security-and-firewall'); + + if ('require_current' == $style) echo ''."\n"; + + echo '
            '; + + // Show the 'disabled' option if the user is an admin, or if it is currently set, or if TFA is not compulsory, or if the site owner doesn't require it to be hidden + // Note that this just hides the option in the UI. The user could POST to turn off TFA, but, since it's required, they won't be able to log in. + if ($show_disable) { + echo '
            '; + } + } + + /** + * Retrieve a saved option + * + * @param String $key - option key + * + * @return Mixed + */ + public function get_option($key) { + if (!is_multisite()) return get_option($key); + $main_site_id = function_exists('get_main_site_id') ? get_main_site_id() : 1; + $get_option_site_id = apply_filters('simba_tfa_get_option_site_id', $main_site_id); + switch_to_blog($get_option_site_id); + $value = get_option($key); + restore_current_blog(); + return $value; + } + + /** + * Updates an option. + * + * @param String $key - option key + * @param Mixed $value - option value + * + * @return Boolean + */ + public function update_option($key, $value) { + if (!is_multisite()) return update_option($key, $value); + + $main_site_id = function_exists('get_main_site_id') ? get_main_site_id() : 1; + $update_option_site_id = apply_filters('simba_tfa_update_option_site_id', $main_site_id); + + switch_to_blog($update_option_site_id); + $result = update_option($key, $value); + restore_current_blog(); + + return $result; + } + + /** + * Deletes an option. + * + * @param String $key - option key + * + * @return Boolean + */ + public function delete_option($key) { + if (!is_multisite()) return delete_option($key); + + $main_site_id = function_exists('get_main_site_id') ? get_main_site_id() : 1; + $delete_option_site_id = apply_filters('simba_tfa_delete_option_site_id', $main_site_id); + + switch_to_blog($delete_option_site_id); + $result = delete_option($key); + restore_current_blog(); + + return $result; + } + + /** + * Paint a list of checkboxes, one for each role + * + * @param String $prefix + * @param Integer $default - default value (0 or 1) + */ + public function list_user_roles_checkboxes($prefix = '', $default = 1) { + if (is_multisite()) { + // Not a real WP role; needs separate handling + $id = '_super_admin'; + $name = __('Multisite Super Admin', 'all-in-one-wp-security-and-firewall'); + $setting = $this->get_option('tfa_'.$prefix.$id); + $setting = ($setting === false) ? $default : ($setting ? 1 : 0); + + echo '
            \n"; + } + + global $wp_roles; + if (!isset($wp_roles)) $wp_roles = new WP_Roles(); + + foreach ($wp_roles->role_names as $id => $name) { + $setting = $this->get_option('tfa_'.$prefix.$id); + $setting = ($setting === false) ? $default : ($setting ? 1 : 0); + + echo '
            \n"; + } + + } + + public function tfa_list_xmlrpc_status_radios() { + + $setting = $this->get_option('tfa_xmlrpc_on'); + $setting = $setting ? 1 : 0; + + $types = array( + '0' => __('Do not require 2FA over XMLRPC (best option if you must use XMLRPC and your client does not support 2FA)', 'all-in-one-wp-security-and-firewall'), + '1' => __('Do require 2FA over XMLRPC (best option if you do not use XMLRPC or are unsure)', 'all-in-one-wp-security-and-firewall') + ); + + foreach($types as $id => $name) { + print '
            \n"; + } + } + + protected function is_caller_active() { + + if (!defined('XMLRPC_REQUEST') || !XMLRPC_REQUEST) return true; + + $saved_data = $this->get_option('tfa_xmlrpc_on'); + + return $saved_data ? true : false; + + } + + /** + * @param Array $params + * @param Boolean $may_be_email + * + * @return WP_Error|Boolean|Integer - WP_Error or false means failure; true or 1 means success, but true means the TFA code was validated + */ + public function authorise_user_from_login($params, $may_be_email = false) { + + $params = apply_filters('simbatfa_auth_user_from_login_params', $params); + + global $wpdb; + + if (!$this->is_caller_active()) return 1; + + $query = ($may_be_email && filter_var($params['log'], FILTER_VALIDATE_EMAIL)) ? $wpdb->prepare("SELECT ID, user_registered from ".$wpdb->users." WHERE user_email=%s", $params['log']) : $wpdb->prepare("SELECT ID, user_registered from ".$wpdb->users." WHERE user_login=%s", $params['log']); + $response = $wpdb->get_row($query); + + if (!$response && $may_be_email && filter_var($params['log'], FILTER_VALIDATE_EMAIL)) { + // Corner-case: login looks like an email, but is a username rather than email address + $response = $wpdb->get_row($wpdb->prepare("SELECT ID, user_registered from ".$wpdb->users." WHERE user_login=%s", $params['log'])); + } + + $user_id = is_object($response) ? $response->ID : false; + $user_registered = is_object($response) ? $response->user_registered : false; + + $user_code = isset($params['two_factor_code']) ? str_replace(' ', '', trim($params['two_factor_code'])) : ''; + + // This condition in theory should not be possible + if (!$user_id) return new WP_Error('tfa_user_not_found', apply_filters('simbatfa_tfa_user_not_found', ''.__('Error:', 'all-in-one-wp-security-and-firewall').' '.__('The indicated user could not be found.', 'all-in-one-wp-security-and-firewall'))); + + if (!$this->is_activated_for_user($user_id)) return 1; + + if (!empty($params['trust_token']) && $this->user_trust_token_valid($user_id, $params['trust_token'])) { + return 1; + } + + if (!$this->is_activated_by_user($user_id)) { + + if (!$this->is_required_for_user($user_id)) return 1; + + $enforce_require_after_check = true; + + $require_enforce_after = $this->get_option('tfa_require_enforce_after'); + + // Don't enforce if the setting has never been saved + if (is_string($require_enforce_after) && preg_match('#^(\d+)-(\d+)-(\d+)$#', $require_enforce_after, $enforce_matches)) { + + // wp_date() is WP 5.3+, but performs translation into the site locale + $current_date = function_exists('wp_date') ? wp_date('Y-m-d') : get_date_from_gmt(gmdate('Y-m-d H:i:s'), 'Y-m-d'); + + if (preg_match('#^(\d+)-(\d+)-(\d+)$#', $current_date, $current_date_matches)) { + if ($current_date_matches[0] < $enforce_matches[0] || ($current_date_matches[0] == $enforce_matches[0] && ($current_date_matches[1] < $enforce_matches[1] || ($current_date_matches[1] == $enforce_matches[1] && $current_date_matches[2] < $enforce_matches[2])))) { + // Enforcement not yet begun; skip + $enforce_require_after_check = false; + } + } + + } + + $require_after = absint($this->get_option('tfa_requireafter')) * 86400; + + $account_age = time() - strtotime($user_registered); + + if ($account_age > $require_after && apply_filters('simbatfa_enforce_require_after_check', $enforce_require_after_check, $user_id, $require_after, $account_age)) { + + return new WP_Error('tfa_required', apply_filters('simbatfa_notfa_forbidden_login', ''.__('Error:', 'all-in-one-wp-security-and-firewall').' '.__('The site owner has forbidden you to login without two-factor authentication. Please contact the site owner to re-gain access.', 'all-in-one-wp-security-and-firewall'))); + } + + return 1; + } + + $tfa_creds_user_id = !empty($params['creds_user_id']) ? $params['creds_user_id'] : $user_id; + + if ($tfa_creds_user_id != $user_id) { + + // Authenticating using a different user's credentials (e.g. https://wordpress.org/plugins/use-administrator-password/) + // In this case, we require that different user to have TFA active - so that this mechanism can't be used to avoid TFA + + if (!$this->is_activated_for_user($tfa_creds_user_id) || !$this->is_activated_by_user($tfa_creds_user_id)) { + return new WP_Error('tfa_required', apply_filters('simbatfa_notfa_forbidden_login_altuser', ''.__('Error:', 'all-in-one-wp-security-and-firewall').' '.__('You are attempting to log in to an account that has two-factor authentication enabled; this requires you to also have two-factor authentication enabled on the account whose credentials you are using.', 'all-in-one-wp-security-and-firewall'))); + } + + } + + return $this->get_controller('totp')->check_code_for_user($tfa_creds_user_id, $user_code); + + } + + /** + * Evaluate whether a trust token is valid for a user + * + * @param Integer $user_id - WP user ID + * @param String $trust_token - trust token + * + * @return Boolean + */ + protected function user_trust_token_valid($user_id, $trust_token) { + + if (!is_string($trust_token) || strlen($trust_token) < 30) return false; + + $trusted_devices = $this->user_get_trusted_devices($user_id); + + $time_now = time(); + + foreach ($trusted_devices as $device) { + if (empty($device['until']) || $device['until'] <= $time_now) continue; + if (!empty($device['token']) && $device['token'] === $trust_token) { + return true; + } + } + + return false; + } + + /** + * This deals with the issue that wp-login.php does not redirect to a canonical URL. As a result, if a website is available under more than one host, then admin_url('admin-ajax.php') might return a different one than the visitor is using, resulting in AJAX failing due to CORS errors. + * + * @return String + */ + protected function get_ajax_url() { + $ajax_url = admin_url('admin-ajax.php'); + $parsed_url = parse_url($ajax_url); + if (strtolower($parsed_url['host']) !== strtolower($_SERVER['HTTP_HOST']) && !empty($parsed_url['path'])) { + // Mismatch - return the relative URL only + $ajax_url = $parsed_url['path']; + } + return $ajax_url; + } + + /** + * Called not only upon the WP action login_enqueue_scripts, but potentially upon the action 'init' and various others from other plugins too. It can handle being called multiple times. + */ + public function login_enqueue_scripts() { + if (!$this->should_enqueue_login_scripts()) { + return; + } + + if (isset($_GET['action']) && 'logout ' != $_GET['action'] && 'login' != $_GET['action']) return; + + static $already_done = false; + if ($already_done) return; + $already_done = true; + + // Prevent caching when in debug mode + $script_ver = (defined('WP_DEBUG') && WP_DEBUG) ? time() : filemtime($this->includes_dir().'/tfa.js'); + + wp_enqueue_script('tfa-ajax-request', $this->includes_url().'/tfa.js', array('jquery'), $script_ver); + + $trusted_for = $this->get_option('tfa_trusted_for'); + $trusted_for = (false === $trusted_for) ? 30 : (string) absint($trusted_for); + + $localize = array( + 'ajaxurl' => $this->get_ajax_url(), + 'click_to_enter_otp' => __("Click to enter One Time Password", 'all-in-one-wp-security-and-firewall'), + 'enter_username_first' => __('You have to enter a username first.', 'all-in-one-wp-security-and-firewall'), + 'otp' => __('One Time Password (i.e. 2FA)', 'all-in-one-wp-security-and-firewall'), + 'otp_login_help' => __('(check your OTP app to get this password)', 'all-in-one-wp-security-and-firewall'), + 'mark_as_trusted' => sprintf(_n('Trust this device (allow login without 2FA for %d day)', 'Trust this device (allow login without TFA for %d days)', $trusted_for, 'all-in-one-wp-security-and-firewall'), $trusted_for), + 'is_trusted' => __('(Trusted device - no OTP code required)', 'all-in-one-wp-security-and-firewall'), + 'nonce' => wp_create_nonce('simba_tfa_loginform_nonce'), + 'login_form_selectors' => '', + 'login_form_off_selectors' => '', + 'error' => __('An error has occurred. Site owners can check the JavaScript console for more details.', 'all-in-one-wp-security-and-firewall'), + ); + + // Spinner exists since WC 3.8. Use the proper functions to avoid SSL warnings. + if (file_exists(ABSPATH.'wp-admin/images/spinner-2x.gif')) { + $localize['spinnerimg'] = admin_url('images/spinner-2x.gif'); + } elseif (file_exists(ABSPATH.WPINC.'/images/spinner-2x.gif')) { + $localize['spinnerimg'] = includes_url('images/spinner-2x.gif'); + } + + $localize = apply_filters('simba_tfa_login_enqueue_localize', $localize); + + wp_localize_script('tfa-ajax-request', 'simba_tfasettings', $localize); + + } + + /** + * Check whether TFA login scripts should be enqueued or not. + * + * @return boolean True if the TFA login script should be enqueued, otherwise false. + */ + private function should_enqueue_login_scripts() { + if (defined('TWO_FACTOR_DISABLE') && TWO_FACTOR_DISABLE) { + return apply_filters('simbatfa_enqueue_login_scripts', false); + } + + global $wpdb; + $sql = $wpdb->prepare('SELECT COUNT(user_id) FROM ' . $wpdb->usermeta . ' WHERE meta_key = %s AND meta_value = %d LIMIT 1', 'tfa_enable_tfa', 1); + $count_user_id = $wpdb->get_var($sql); + + if (is_null($count_user_id)) { // Error in query. + return apply_filters('simbatfa_enqueue_login_scripts', true); + } elseif ($count_user_id > 0) { // A user exists with TFA enabled. + return apply_filters('simbatfa_enqueue_login_scripts', true); + } + + // No user exists with TFA enabled. + return apply_filters('simbatfa_enqueue_login_scripts', false); + } + + + /** + * Return or output view content + * + * @param String $path - path to template, usually relative to templates/ within the plugin directory + * @param Array $extract_these - key/value pairs for substitution into the scope of the template + * @param Boolean $return_instead_of_echo - what to do with the results + * + * @return String|Void + */ + public function include_template($path, $extract_these = array(), $return_instead_of_echo = false) { + + if ($return_instead_of_echo) ob_start(); + + $template_file = apply_filters('simatfa_template_file', $this->templates_dir().'/'.$path, $path, $extract_these, $return_instead_of_echo); + + do_action('simbatfa_before_template', $path, $return_instead_of_echo, $extract_these, $template_file); + + if (!file_exists($template_file)) { + error_log("TFA: template not found: $template_file (from $path)"); + echo __('Error:', 'all-in-one-wp-security-and-firewall').' '.__('Template path not found:', 'all-in-one-wp-security-and-firewall')." (".htmlspecialchars($path).")"; + } else { + extract($extract_these); + // The following are useful variables which can be used in the template. + // They appear as unused, but may be used in the $template_file. + $wpdb = $GLOBALS['wpdb'];// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- $wpdb might be used in the included template + $simba_tfa = $this;// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- $wp_optimize might be used in the included template + $totp_controller = $this->get_controller('totp');// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- $wp_optimize might be used in the included template + include $template_file; + } + + do_action('simbatfa_after_template', $path, $return_instead_of_echo, $extract_these, $template_file); + + if ($return_instead_of_echo) return ob_get_clean(); + } + + /** + * Make sure that self::$frontend is the instance of Simba_TFA_Frontend, and return it + * + * @return Simba_TFA_Frontend + */ + public function load_frontend() { + if (!class_exists('Simba_TFA_Frontend')) require_once($this->includes_dir().'/tfa_frontend.php'); + if (empty($this->frontend)) $this->frontend = new Simba_TFA_Frontend($this); + return $this->frontend; + } + + // __return_empty_string() does not exist until WP 3.7 + public function shortcode_when_not_logged_in() { + return ''; + } + + /** + * Set authentication slug. + * + * @param String $authentication_slug - Authentication slug. Verify that two-factor authentication should not be repeated for the same slug. + */ + public function set_authentication_slug($authentication_slug) { + $this->authentication_slug = $authentication_slug; + } + + /** + * Unserialize data while maintaining compatibility across PHP versions due to different number of arguments required by PHP's "unserialize" function + * + * @param string $serialized_data Data to be unserialized, should be one that is already serialized + * @param boolean|array $allowed_classes Either an array of class names which should be accepted, false to accept no classes, or true to accept all classes + * @param integer $max_depth The maximum depth of structures permitted during unserialization, and is intended to prevent stack overflows + * + * @return mixed Unserialized data can be any of types (integer, float, boolean, string, array or object) + */ + private static function unserialize($serialized_data, $allowed_classes = false, $max_depth = 0) { + if (version_compare(PHP_VERSION, '7.0', '<')) { + $result = unserialize($serialized_data); + } else { + $result = unserialize($serialized_data, array('allowed_classes' => $allowed_classes, 'max_depth' => $max_depth)); // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctionParameters.unserialize_optionsFound -- This is the method used to unserialize data instead of the default unserialize method + } + return $result; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/templates/admin-settings.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/templates/admin-settings.php new file mode 100755 index 00000000..ba387783 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/templates/admin-settings.php @@ -0,0 +1,214 @@ +
            + +
            +

            + ' . esc_html($val['title']) . ''; + }, $admin_settings_links)); + echo '
            '; + } + ?> +
            + + get_option('tfa_encrypt_secrets'); ?> + + +
            +

            +

            + +

            +
            + + +
            + + +

            + +

            + + + + +

            + +

            + list_user_roles_checkboxes(); ?> +

            + + + +
            + +
            +

            + + ' . esc_html__('Requiring users to use two-factor authentication is a feature of the Premium version of this plugin.', 'all-in-one-wp-security-and-firewall').'

            '; + echo apply_filters('simba_tfa_after_user_roles', $output); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- already escaped (and not suitable for kses since non-wordpress.org add-on adds HTML lists) + + ?> + +


            +

            + +
            + + + + ' . esc_html__('Allowing users to mark a device as trusted so that a two-factor code is only needed once in a specified number of days (instead of every login) is a feature of the Premium version of this plugin.', 'all-in-one-wp-security-and-firewall').'

            '; + echo apply_filters('simba_tfa_trusted_devices_config', $output); //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Contains checkboxes, and content is already escaped during construction. + + ?> +

            +
            + + +
            +
            +
            + +

            + '; + echo esc_html__("XMLRPC is a feature within WordPress allowing other computers to talk to your WordPress install. For example, it could be used by an app on your tablet that allows you to blog directly from the app (instead of needing the WordPress dashboard).", 'all-in-one-wp-security-and-firewall'); + echo '

            '; + + echo esc_html__("Unfortunately, XMLRPC also provides a way for attackers to perform actions on your WordPress site, using only a password (i.e. without a two-factor password). More unfortunately, authors of legitimate programmes using XMLRPC have not yet added two-factor support to their code.", 'all-in-one-wp-security-and-firewall'); + echo '

            '; + + echo esc_html__("i.e. XMLRPC requests coming in to WordPress (whether from a legitimate app, or from an attacker) can only be verified using the password - not with a two-factor code. As a result, there not be an ideal option to pick below. You may have to choose between the convenience of using your apps, or the security of two factor authentication.", 'all-in-one-wp-security-and-firewall'); + echo '

            '; + + ?> +

            + tfa_list_xmlrpc_status_radios(); ?> +

            + +
            +
            + +
            +
            +
            + +

            + +

            + print_default_hmac_radios(); + ?>

            + +
            +
            + +
            +
            + +

            +

            + +

            + +
            + + +

            +

            + +

            +

            + + +

            + +
            + +
            + +
            + + +

            +

            +

            + get_premium_version_url()) . '">' . esc_html__('The Premium version of this plugin allows you to add a configuration tab for users in the WooCommerce "My account" area, and anti-bot protection on the WooCommerce login form.', 'all-in-one-wp-security-and-firewall').''); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- already escaped, and contains checkboxes ?> +

            +
            + + +
            + +
            +
            +

            +

            + + + + + + + + + + + +


            + +

            +

            +
            +

            +

            +

              +
            • -
            • +
            • -
            • +
            • -
            • +
            • -
            • +
            • -
            • +
            • -
            • +
            • -
            • +
            • -
            • +
            • -
            • +
            +

            +
            + +
            + +

            +

            + + get_plugin_translate_url()) . '">' . esc_html__('the wordpress.org translation website.', 'all-in-one-wp-security-and-firewall').'') . ' ' . esc_html__("Don't send us the translation file directly - plugin authors do not have access to the wordpress.org translation system (local language teams do).", 'all-in-one-wp-security-and-firewall'); ?> +
            +

            + +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/templates/settings-intro-notices.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/templates/settings-intro-notices.php new file mode 100755 index 00000000..b6285bac --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/templates/settings-intro-notices.php @@ -0,0 +1,30 @@ +

            +get_management_capability())) { + echo esc_html(apply_filters('simba_tfa_message_personal_settings', __('These are your personal settings.', 'all-in-one-wp-security-and-firewall') . ' ' . __('Nothing you change here will have any effect on other users.', 'all-in-one-wp-security-and-firewall'))); +} + +if (is_multisite()) { + if (is_super_admin()) { + // Since WP 4.9 + $main_site_id = function_exists('get_main_site_id') ? get_main_site_id() : 1; + $switched = switch_to_blog($main_site_id); + echo ' ' . esc_html__('The site-wide administration options are here.', 'all-in-one-wp-security-and-firewall').''; + if ($switched) restore_current_blog(); + } +} elseif (current_user_can($simba_tfa->get_management_capability())) { + echo ' ' . esc_html__('The site-wide administration options are here.', 'all-in-one-wp-security-and-firewall').''; +} + +?> +

            + +

            + + + + get_management_capability())) { ?> + + +

            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/templates/shortcode-tfa-user-settings.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/templates/shortcode-tfa-user-settings.php new file mode 100755 index 00000000..dbedfd82 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/templates/shortcode-tfa-user-settings.php @@ -0,0 +1,29 @@ +ID) ? '(' . esc_html__('Not logged in.', 'all-in-one-wp-security-and-firewall').')' : esc_html__('Two factor authentication is not available for your user.', 'all-in-one-wp-security-and-firewall'); + +} else { + + ?> + +
            + + include_template('settings-intro-notices.php'); ?> + + settings_enable_or_disable_output(); ?> + + get_controller('totp')->current_codes_box(); ?> + + get_controller('totp')->advanced_settings_box(array($tfa_frontend, 'save_settings_button')); ?> + +
            + + save_settings_javascript_output(); ?> + + + +
            + +

            + + user_get_trusted_devices($current_user->ID); + + if (empty($trusted_devices)) { + echo ''.__('(none)', 'all-in-one-wp-security-and-firewall').''; + } + + foreach ($trusted_devices as $device_id => $device) { + + if (!isset($device['token']) || '' == $device['token']) continue; + + $user_agent = empty($device['user_agent']) ? __('(unspecified)', 'all-in-one-wp-security-and-firewall'): $device['user_agent']; + + echo ''.sprintf(__('User agent %s logged in from IP address %s and is trusted until %s', 'all-in-one-wp-security-and-firewall'), ''.htmlspecialchars($user_agent).'', ''.htmlspecialchars($device['ip']).'', ''.date_i18n(get_option('time_format').' '.get_option('date_format'), $device['until']).'').' - '.__('Remove trust', 'all-in-one-wp-security-and-firewall').'
            '; + + } + + ?> + +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/templates/user-settings.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/templates/user-settings.php new file mode 100755 index 00000000..139b37b4 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/includes/simba-tfa/templates/user-settings.php @@ -0,0 +1,62 @@ +get_controller('totp'); + +?> + +
            + +

            + + were_settings_saved())) { + echo '
            ' . "

            " . esc_html__('Settings saved.', 'all-in-one-wp-security-and-firewall') . "

            "; + } + + $simba_tfa->include_template('settings-intro-notices.php'); + + ?> + +
            + + + +

            +

            + +

            +

            + paint_enable_tfa_radios($current_user->ID); + ?>

            + +
            + + current_codes_box(); + + $totp_controller->advanced_settings_box(); + + do_action('simba_tfa_user_settings_after_advanced_settings'); + + ?> + +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/index.html b/wp-content/plugins/all-in-one-wp-security-and-firewall/index.html new file mode 100755 index 00000000..e69de29b diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/js/index.html b/wp-content/plugins/all-in-one-wp-security-and-firewall/js/index.html new file mode 100755 index 00000000..e69de29b diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/js/password-strength-tool.js b/wp-content/plugins/all-in-one-wp-security-and-firewall/js/password-strength-tool.js new file mode 100755 index 00000000..628dd761 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/js/password-strength-tool.js @@ -0,0 +1,137 @@ +(function($) { + $.fn.extend({ + pwdstr: function(crack_time_calculation, crack_time_message, hibp_message) { + return this.each(function() { + const check_interval = 500; + var last_check_time = 0; + $(this).keyup(function() { + $(crack_time_calculation).html(getTime($(this).val())); + $(crack_time_message).show(); + $(hibp_message).hide(); + + setTimeout(() => { + if (Date.now() - last_check_time > check_interval) { + last_check_time = Date.now(); + aios_send_command('hibp_check_password', {password: $(this).val()}, function(response) { + if (response.pwned) { + $(crack_time_message).hide(); + $(hibp_message).show(); + } + }) + } + }, check_interval); + }); + + function getTime(str) { + var chars = 0; + var rate = 2800000000; + + if ((/[a-z]/).test(str)) chars += 26; + if ((/[A-Z]/).test(str)) chars += 26; + if ((/[0-9]/).test(str)) chars += 10; + if ((/[^a-zA-Z0-9]/).test(str)) chars += 32; + + var pos = Math.pow(chars,str.length); + var s = pos/rate; + var decimalYears = s/(3600*24*365); + var years = Math.floor(decimalYears); + + var decimalMonths = (decimalYears-years)*12; + var months = Math.floor(decimalMonths); + + var decimalDays = (decimalMonths-months)*30; + var days = Math.floor(decimalDays); + + var decimalHours = (decimalDays-days)*24; + var hours = Math.floor(decimalHours); + + var decimalMinutes = (decimalHours-hours)*60; + var minutes = Math.floor(decimalMinutes); + + var decimalSeconds = (decimalMinutes-minutes)*60; + var seconds = Math.floor(decimalSeconds); + + var time = []; + + if (years > 0) { + time.push(years + " " + aios_pwtool_trans.years + ", "); + } + if (months > 0) { + time.push(months + " " + aios_pwtool_trans.months + ", "); + } + if (days > 0) { + time.push(days + " " + aios_pwtool_trans.days + ", "); + } + if (hours > 0) { + time.push(hours + " " + aios_pwtool_trans.hours + ", "); + } + if (minutes > 0) { + time.push(minutes + " " + aios_pwtool_trans.minutes + ", "); + } + if (seconds > 0) { + time.push(seconds + " " + aios_pwtool_trans.seconds + ", "); + } + + if (time.length <= 0) + time = "" + aios_pwtool_trans.less_than_one_second + ", "; + else if (time.length == 1) + time = time[0]; + else time = time[0] + time[1]; + + var field = $('#aiowps_password_test'); + if (s <= 1 || !field.val()) { + //Time to crack < 1 sec + complexity = 0; + } else if (s > 1 && s <= 43200) { + //1 sec < Time to crack < 12hrs + complexity = 1; + } else if (s > 43200 && s <= 86400) { + //12 hrs < Time to crack < 1day + complexity = 2; + } else if (s > 86400 && s <= 604800) { + //1 day < Time to crack < 1wk + complexity = 3; + } else if (s > 604800 && s <= 2678400) { + //1wk < Time to crack < 1mth + complexity = 4; + } else if (s > 2678400 && s <= 15552000) { + //1mth < Time to crack < 6mths + complexity = 5; + } else if (s > 31536000 && s <= 31536000) { + //6mths < Time to crack < 1yrs + complexity = 6; + } else if (s > 31536000 && s <= 315360000) { + //1yrs < Time to crack < 10yrs + complexity = 7; + } else if (s > 315360000 && s <= 3153600000) { + //10yrs < Time to crack < 100yrs + complexity = 8; + } else if (s > 3153600000 && s <= 31536000000) { + //100yrs < Time to crack < 1000yrs + complexity = 9; + } else if (s > 31536000000) { + //1000yrs < Time to crack + complexity = 10; + } + // Rotate the arrow + var meterFill = $('#aios_meter_fill'); + if (str.length === 0) { + meterFill.css('width', '0').css('background-color', 'transparent'); + } else if (complexity < 3) { + meterFill.css('width', (complexity * 10) + '%').css('background-color', 'red'); + } else if (complexity < 6) { + meterFill.css('width', (complexity * 10) + '%').css('background-color', 'orange'); + } else { + meterFill.css('width', (complexity * 10) + '%').css('background-color', 'green'); + } + + return time.substring(0,time.length-2); + } + }); + } + }); + $(document).ready(function() { + $('#aiowps_password_test').pwdstr('#aiowps_password_crack_time_calculation', '#aiowps_password_crack_info_text', '#aiowps_password_hibp_info_text'); + }); +})(jQuery); + diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/js/remove-weak-pw.js b/wp-content/plugins/all-in-one-wp-security-and-firewall/js/remove-weak-pw.js new file mode 100755 index 00000000..f43a9f32 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/js/remove-weak-pw.js @@ -0,0 +1,4 @@ +jQuery(document).ready(function($) { + $('#pw-weak').remove(); + $('.pw-weak').remove(); +}); \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/js/wp-security-admin-script.js b/wp-content/plugins/all-in-one-wp-security-and-firewall/js/wp-security-admin-script.js new file mode 100755 index 00000000..1455953e --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/js/wp-security-admin-script.js @@ -0,0 +1,1846 @@ +/** + * Send an action over AJAX. A wrapper around jQuery.ajax. In future, all consumers can be reviewed to simplify some of the options, where there is historical cruft. + * + * @param {string} action - the action to send + * @param {*} data - data to send + * @param {Function} callback - will be called with the results + * @param {object} options -further options. Relevant properties include: + * - [json_parse=true] - whether to JSON parse the results + * - [alert_on_error=true] - whether to show an alert box if there was a problem (otherwise, suppress it) + * - [action='aios_ajax'] - what to send as the action parameter on the AJAX request (N.B. action parameter to this function goes as the 'subaction' parameter on the AJAX request) + * - [nonce=aios_ajax_nonce] - the nonce value to send. + * - [nonce_key='nonce'] - the key value for the nonce field + * - [timeout=null] - set a timeout after this number of seconds (or if null, none is set) + * - [async=true] - control whether the request is asynchronous (almost always wanted) or blocking (would need to have a specific reason) + * - [type='POST'] - GET or POST + */ +function aios_send_command(action, data, callback, options) { + + var default_options = { + json_parse: true, + alert_on_error: true, + action: 'aios_ajax', + nonce: aios_data.ajax_nonce, + nonce_key: 'nonce', + timeout: null, + async: true, + type: 'POST' + }; + + if ('undefined' === typeof options) options = {}; + + for (var opt in default_options) { + if (!options.hasOwnProperty(opt)) { options[opt] = default_options[opt]; } + } + + var ajax_data = { + action: options.action, + subaction: action + }; + + ajax_data[options.nonce_key] = options.nonce; + ajax_data.data = data; + + var ajax_opts = { + type: options.type, + url: ajaxurl, + data: ajax_data, + success: function(response, status) { + if (options.json_parse) { + try { + var resp = aios_parse_json(response); + } catch (e) { + if ('function' == typeof options.error_callback) { + return options.error_callback(response, e, 502, resp); + } else { + console.log(e); + console.log(response); + if (options.alert_on_error) { alert(aios_trans.unexpected_response+' '+response); } + return; + } + } + if (resp.hasOwnProperty('fatal_error')) { + if ('function' == typeof options.error_callback) { + // 500 is internal server error code + return options.error_callback(response, status, 500, resp); + } else { + console.error(resp.fatal_error_message); + if (options.alert_on_error) { alert(resp.fatal_error_message); } + return false; + } + } + if ('function' == typeof callback) callback(resp, status, response); + } else { + if ('function' == typeof callback) callback(response, status); + } + }, + error: function(response, status, error_code) { + if ('function' == typeof options.error_callback) { + options.error_callback(response, status, error_code); + } else { + console.log("aios_send_command: error: "+status+" ("+error_code+")"); + console.log(response); + } + }, + dataType: 'text', + async: options.async + }; + + if (null != options.timeout) { ajax_opts.timeout = options.timeout; } + + jQuery.ajax(ajax_opts); + +} + +/** + * Parse JSON string, including automatically detecting unwanted extra input and skipping it + * + * @param {string} json_mix_str - JSON string which need to parse and convert to object + * @param {boolean} analyse - if true, then the return format will contain information on the parsing, and parsing will skip attempting to JSON.parse() the entire string (will begin with trying to locate the actual JSON) + * + * @throws SyntaxError|String (including passing on what JSON.parse may throw) if a parsing error occurs. + * + * @returns Mixed parsed JSON object. Will only return if parsing is successful (otherwise, will throw). If analyse is true, then will rather return an object with properties (mixed)parsed, (integer)json_start_pos and (integer)json_end_pos + */ +function aios_parse_json(json_mix_str, analyse) { + + analyse = ('undefined' === typeof analyse) ? false : true; + + // Just try it - i.e. the 'default' case where things work (which can include extra whitespace/line-feeds, and simple strings, etc.). + if (!analyse) { + try { + var result = JSON.parse(json_mix_str); + return result; + } catch (e) { + console.log('AIOS: Exception when trying to parse JSON (1) - will attempt to fix/re-parse based upon first/last curly brackets'); + console.log(json_mix_str); + } + } + + var json_start_pos = json_mix_str.indexOf('{'); + var json_last_pos = json_mix_str.lastIndexOf('}'); + + // Case where some php notice may be added after or before json string + if (json_start_pos > -1 && json_last_pos > -1) { + var json_str = json_mix_str.slice(json_start_pos, json_last_pos + 1); + try { + var parsed = JSON.parse(json_str); + if (!analyse) { console.log('AIOS: JSON re-parse successful'); } + return analyse ? { parsed: parsed, json_start_pos: json_start_pos, json_last_pos: json_last_pos + 1 } : parsed; + } catch (e) { + console.log('AIOS: Exception when trying to parse JSON (2) - will attempt to fix/re-parse based upon bracket counting'); + + var cursor = json_start_pos; + var open_count = 0; + var last_character = ''; + var inside_string = false; + + // Don't mistake this for a real JSON parser. Its aim is to improve the odds in real-world cases seen, not to arrive at universal perfection. + while ((open_count > 0 || cursor == json_start_pos) && cursor <= json_last_pos) { + + var current_character = json_mix_str.charAt(cursor); + + if (!inside_string && '{' == current_character) { + open_count++; + } else if (!inside_string && '}' == current_character) { + open_count--; + } else if ('"' == current_character && '\\' != last_character) { + inside_string = inside_string ? false : true; + } + + last_character = current_character; + cursor++; + } + console.log("Started at cursor="+json_start_pos+", ended at cursor="+cursor+" with result following:"); + console.log(json_mix_str.substring(json_start_pos, cursor)); + + try { + var parsed = JSON.parse(json_mix_str.substring(json_start_pos, cursor)); + console.log('AIOS: JSON re-parse successful'); + return analyse ? { parsed: parsed, json_start_pos: json_start_pos, json_last_pos: cursor } : parsed; + } catch (e) { + // Throw it again, so that our function works just like JSON.parse() in its behaviour. + throw e; + } + } + } + + throw "AIOS: could not parse the JSON"; + +} + +/** + * Updates the content of an HTML element identified by its ID with the provided badge text. + * + * @param {Array} badges - An array of objects representing badges to update. + * @param {string} badges.id - The ID of the HTML element to update. + * @param {string} badges.html - The HTML content to set for the element. + * @returns {void} + */ +function aios_update_badge(badges) { + badges.forEach(function(badge) { + aios_update_content(badge.id, badge.html); + }); +} + +/** + * Update the content of an element with the specified HTML. + * + * @param {string} id - The ID of the element to update. + * @param {string} html - The HTML content to set for the element. + * @returns {void} + */ +function aios_update_content(id, html) { + jQuery(id).html(html); +} + + +/** + * Function to block the UI and display a loading message. + * Uses jQuery blockUI plugin. + * + * @param {string} message - A string to be shown when function is called + * + * @returns {void} + */ +function aios_block_ui(message = aios_trans.saving) { + jQuery.blockUI({ + css: { + width: '500px', + border: 'none', + 'border-radius': '10px', + left: 'calc(50% - 250px)', + top: 'calc(50% - 150px)', + padding: '20px' + }, + message: '

            ' + message + '
            ' + }); +} + +/** + * Display a success modal with optional message and icon. + * + * @param {Object|string} args - Configuration object or message string. + * @param {boolean} close_popup - Optional. If true, the popup will close automatically after 2 seconds. Default is true. + * + * @returns {void} + */ +function aios_show_success_modal(args, close_popup = true) { + if ('string' == typeof args) { + args = { + message: args + }; + } + var data = jQuery.extend( + { + icon: 'yes', + close: aios_trans.close, + message: '', + classes: 'success' + }, + args + ); + + var closeButtonHTML = ''; + if (!close_popup) { + closeButtonHTML = ''; + } + + jQuery.blockUI({ + css: { + width: '500px', + border: 'none', + 'border-radius': '10px', + left: 'calc(50% - 250px)', + top: 'calc(50% - 150px)', + cursor: 'default' + }, + onOverlayClick: jQuery.unblockUI, + message: '
            ' + data.message + '
            ' + closeButtonHTML + '
            ' + }); + + // click the show more for AJAX info + jQuery('.aios_success_popup').on('click', '#aios_ajax_showmoreoptions', function (e) { + e.preventDefault(); + let more_options = jQuery('#aios_ajax_moreoptions'); + more_options.toggle(); + // Toggle text between "Show more" and "Hide" + let new_text = more_options.is(':visible') ? aios_trans.hide_info : aios_trans.show_info; + jQuery(this).text(new_text); + }); + + // close success popup + jQuery('.blockUI .aios-close-overlay').on('click', function() { + jQuery.unblockUI(); + }); + + if (close_popup) { + setTimeout(function () { + jQuery.unblockUI(); + }, 2000); + } +} + +/** + * Submits a form using AJAX and handles the response. + * + * @param {jQuery} form - The jQuery object representing the form element. + * @param {string} action - The action to perform when submitting the form. + * @param {boolean|Object} [use_data=true] - Indicates whether to include form data in the AJAX request. + * @param {string} [block_ui_message="Saving..."] - The message to display while blocking UI during AJAX request. + * @param {Function} [pre_ajax_callback] - Optional callback function to execute before the AJAX request. + * @param {Function} [post_ajax_callback] - Optional callback function to execute after the AJAX request. + */ +function aios_submit_form(form, action, use_data = true, block_ui_message = aios_trans.saving, pre_ajax_callback, post_ajax_callback) { + aios_block_ui(block_ui_message); + var submitButton = form.find(':submit'); + submitButton.prop('disabled', true); + var data = {}; + + if ('function' === typeof pre_ajax_callback) { + pre_ajax_callback(); + } + + if ('object' === typeof use_data) { + data = use_data; // Use custom data object + } else if (use_data) { + var dataArray = form.serializeArray(); + var dataLength = dataArray.length; + for (var i = 0; i < dataLength; i++) { + data[dataArray[i].name] = dataArray[i].value; + } + } + aios_send_command(action, data, function(response) { + aios_handle_ajax_update(response, post_ajax_callback); + submitButton.prop('disabled', false); + }); +} + +/** + * Handle AJAX response and update UI elements accordingly. + * If a callback function is provided, it will be executed. + * + * @param {Object} response - The AJAX response object. + * @param {Function} [callback] - Optional callback function to execute. + * + * @returns {void} + */ +function aios_handle_ajax_update(response, callback) { + + // update contents on the page + if (response.hasOwnProperty('content')) { + jQuery.each(response.content, function(key, value) { + aios_update_content('#' + key, value); + }); + } + + // update fields with new values if changed + if (response.hasOwnProperty('values')) { + jQuery.each(response.values, function(key, value) { + jQuery('#' + key).val(value); + }); + } + + // update badges + if (response.hasOwnProperty('badges')) { + aios_update_badge(response.badges); + } + + if ('function' === typeof callback) { + callback(response); + } + + aios_show_ajax_response_message(response); +} + +/** + * Displays an AJAX response message in a modal or unblocks the UI. + * + * This function processes the response from an AJAX request and displays + * the message or info in a modal. If there is an error in the response, + * it shows a warning modal. If there are additional informational messages, + * it provides a toggle to display them. If no messages are present, it unblocks the UI. + * + * @param {Object} response - The response object returned from the AJAX call. + * @param {string} [response.message] - The main message to be displayed in the modal. + * @param {string} [response.status] - The status of the response ('error' indicates a warning). + * @param {Array} [response.info] - Additional information messages to display. + */ +function aios_show_ajax_response_message(response) { + var update_message = (response.hasOwnProperty('message') && response.message.length > 0) || (response.hasOwnProperty('info') && response.info.length > 0); + + if (update_message) { + var messageContainer = jQuery('
            '); + var close_popup = true; + + // display single message + if (response.hasOwnProperty('message')) { + messageContainer.append(response.message); + messageContainer.append('
            '); + } + + if (response.hasOwnProperty('info') && response.info.length > 0) { + close_popup = false; + // info toggle + let toggle = jQuery('' + aios_trans.show_notices + ' (' + aios_trans.show_info + ')'); + toggle.appendTo(messageContainer); + + + let infoContainer = jQuery(''); + response.info.forEach(function (info) { + infoContainer.append(`${info}`, '
            '); + }); + + infoContainer.appendTo(messageContainer); + } + + + if ('error' === response.status) { + aios_show_success_modal({ + message: messageContainer.html(), + icon: 'no-alt', + classes: 'warning' + }, false); + } else { + aios_show_success_modal(messageContainer.html(), close_popup); + } + } else { + setTimeout(function() { + jQuery.unblockUI(); + }, 1500); + } +} + +jQuery(function($) { + //Add Generic Admin Dashboard JS Code in this file + + //Media Uploader - start + jQuery("#aiowps_restore_htaccess_form").on('submit', function(e) { + e.preventDefault(); + var form = jQuery(this); + + aios_read_restore_file(this, 'htaccess', function () { + aios_submit_form(form, 'perform_restore_htaccess_file', true, aios_trans.processing, null, function (response) { + form[0].reset(); + }) + }); + }); + + jQuery("#aiowps_restore_wp_config_form").on('submit', function(e) { + e.preventDefault(); + var form = jQuery(this); + + aios_read_restore_file(this, 'wp_config', function () { + aios_submit_form(form, 'perform_restore_wp_config_file', true, aios_trans.processing, null, function (response) { + form[0].reset(); + }) + }); + }); + + jQuery("#aiowps_restore_settings_form").on('submit', function(e) { + e.preventDefault(); + var form = jQuery(this); + + aios_read_restore_file(this, 'import_settings', function () { + + aios_submit_form(form, 'perform_restore_aiowps_settings', true, aios_trans.processing, null, function(response) { + form[0].reset(); + if (response.hasOwnProperty('redirect_url')) { + // Redirect to the URL + window.location.href = response.extra_args.redirect_url; + } + }) + }) + }); + + /** + * Reads the contents of a selected file and submits the form after populating a hidden input with the file contents. + * + * @param {HTMLFormElement} form - The form element to submit after reading the file contents. + * @param {string} file - The type of file to read ('htaccess', 'wp_config', 'import_settings'). + * @param {Function} [callback] - Optional. A callback function to execute after reading the file contents. + */ + function aios_read_restore_file(form, file, callback) { + var aios_import_file_input = document.getElementById('aiowps_' + file + '_file'); + if (0 == aios_import_file_input.files.length) { + alert(aios_trans.no_import_file); + return; + } + var aios_import_file_file = aios_import_file_input.files[0]; + var aios_import_file_reader = new FileReader(); + aios_import_file_reader.onload = function() { + jQuery('#aiowps_' + file + '_file_contents').val(this.result); + if ('function' === typeof callback) { + // If callback is provided, execute it + callback(); + } else { + // If callback is not provided, submit the form + form.submit(); + } + }; + aios_import_file_reader.readAsText(aios_import_file_file); + } + //End of Media Uploader + + // Triggers the more info toggle link + jQuery(".aiowps_more_info_body").hide();//hide the more info on page load + function toggleMoreInfo(target = '.aiowps_more_info_anchor') { + jQuery(target).on('click', function () { + jQuery(this).next(".aiowps_more_info_body").animate({"height": "toggle"}); + var toggle_char_ref = jQuery(this).find(".aiowps_more_info_toggle_char"); + var toggle_char_value = toggle_char_ref.text(); + if ("+" === toggle_char_value) { + toggle_char_ref.text("-"); + } else { + toggle_char_ref.text("+"); + } + }); + } + toggleMoreInfo(); + //End of more info toggle + + /** + * This function uses javascript to retrieve a query arg from the current page URL + * + * @param {string} name - The name of the query parameter to retrieve. + * @returns {string|null} The value of the query parameter, or null if the parameter does not exist. + */ + function getParameterByName(name) { + var url = window.location.href; + name = name.replace(/[\[\]]/g, "\\$&"); + var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), + results = regex.exec(url); + if (!results) return null; + if (!results[2]) return ''; + return decodeURIComponent(results[2].replace(/\+/g, " ")); + } + + // Start of brute force attack prevention toggle handling + jQuery('input[name=aiowps_enable_brute_force_attack_prevention]').on('click', function () { + jQuery('input[name=aiowps_brute_force_secret_word]').prop('disabled', !jQuery(this).prop('checked')); + jQuery('input[name=aiowps_cookie_based_brute_force_redirect_url]').prop('disabled', !jQuery(this).prop('checked')); + jQuery('input[name=aiowps_brute_force_attack_prevention_pw_protected_exception]').prop('disabled', !jQuery(this).prop('checked')); + jQuery('input[name=aiowps_brute_force_attack_prevention_ajax_exception]').prop('disabled', !jQuery(this).prop('checked')); + }); + // End of brute force attack prevention toggle handling + + // Start of CAPTCHA handling + jQuery('.wrap').on('change', '#aiowps_default_captcha', function () { + var selected_captcha = jQuery(this).val(); + jQuery('.captcha_settings').hide(); + jQuery('#aios-'+ selected_captcha).show(); + + if ('none' === selected_captcha) { + jQuery('#aios-captcha-options').hide(); + } else { + jQuery('#aios-captcha-options').show(); + } + }); + // End of CAPTCHA handling + + /** + * Take a backup with UpdraftPlus if possible. + * + * @param {String} file_entities + * + * @return void + */ + function take_a_backup_with_updraftplus(file_entities) { + // Set default for file_entities to empty string + if ('undefined' == typeof file_entities) file_entities = ''; + var exclude_files = file_entities ? 0 : 1; + + if ('function' === typeof updraft_backupnow_inpage_go) { + updraft_backupnow_inpage_go(function () { + // Close the backup dialogue. + jQuery('#updraft-backupnow-inpage-modal').dialog('close'); + }, file_entities, 'autobackup', 0, exclude_files, 0); + } + } + + if (jQuery('#aios-manual-db-backup-now').length) { + jQuery('#aios-manual-db-backup-now').on('click', function (e) { + e.preventDefault(); + take_a_backup_with_updraftplus(); + }); + } + + // Hide 2FA premium section (advertisements) for free. + if (jQuery('.tfa-premium').length && 0 == jQuery('#tfa_trusted_for').length) { + jQuery('.tfa-premium').parent().find('hr').first().hide(); + jQuery('.tfa-premium').hide(); + } + + // Start of trash spam comments toggle handling + jQuery('input[name=aiowps_enable_trash_spam_comments]').on('click', function() { + jQuery('input[name=aiowps_trash_spam_comments_after_days]').prop('disabled', !jQuery(this).prop('checked')); + }); + // End of trash spam comments toggle handling + + /** + * Copies text to the clipboard using the deprecated document.execCommand method. + * + * @param {string} text - The text to be copied to the clipboard. + */ + function deprecated_copy(text) { + var $temp = jQuery(''); + jQuery('body').append($temp); + $temp.val(text).select(); + if (document.execCommand('copy')) { + alert(aios_trans.copied); + } + $temp.remove(); + } + + // Start of copy-to-clipboard click handling + jQuery('.copy-to-clipboard').on('click', function(event) { + if (navigator.clipboard) { + navigator.clipboard.writeText(event.target.value).then(function() { + alert(aios_trans.copied); + }, function() { + deprecated_copy(event.target.value); + }); + } else { + deprecated_copy(event.target.value); + } + }); + // End of copy-to-clipboard click handling + + // Start audit log list table handling + var audit_log_table_id = '#audit-log-list-table #tables-filter', + audit_log_elements = '.tablenav-pages a, .manage-column.sortable a, .manage-column.sorted a, .current-page, #search-submit, .action', + audit_log_bulk_action_selector = '#bulk-action-selector-top, #bulk-action-selector-bottom', + audit_log_table_tab = 'render_audit_log_tab', + audit_log_filter_event = '.audit-filter-event', + audit_log_search = '#search_audit_events-search-input', + audit_log_level = '.audit-filter-level'; + detect_table_action(audit_log_table_id, audit_log_elements, audit_log_bulk_action_selector, audit_log_table_tab, audit_log_filter_event, audit_log_search, audit_log_level); + // End of audit log list table handling + + + // Start of list table handling + + /** + * Attaches event handlers to specified table elements for detecting and performing actions, + * then updates the table based on the current state or the clicked element. + * + * @param {string} id - The ID selector of the table element (e.g., '#my-table'). + * @param {string} elements - The elements inside the table to attach event handlers to (e.g., 'input, select'). + * @param {string} action_selector - The selector for the bulk action dropdown element (e.g., '#bulk-action-selector-top'). + * @param {string} tab - The tab or section to update after performing an action (e.g., 'posts', 'comments'). + * @param {string} [filter_event_selector=''] - The selector for filtering by event type (optional). + * @param {string} [search_selector=''] - The selector for the search input element (optional). + * @param {string} [filter_level_selector=''] - The selector for filtering by level (optional). + * @param {boolean} [detect=true] - Whether to detect actions based on the clicked element or to perform an action immediately. + * + * @returns {void} + */ + function detect_table_action(id, elements, action_selector, tab, filter_event_selector = '', search_selector = '', filter_level_selector = '', detect = true) { + + if (true === detect) { + jQuery(id).on('click change', elements, function(e) { + // Check if the event's default action is prevented by the confirm message cancel + if (!e.isDefaultPrevented()) { + e.preventDefault(); + perform_action.call(this); // Ensure the context (this) is correct + } + }); + } else { + perform_action.call(jQuery(id).get(0)); // Use the first element from the selector to maintain context + } + + /** + * Perform the action based on the clicked element or the current sorting state. + * + * @returns {void} + */ + function perform_action() { + aios_block_ui(aios_trans.processing); + var checked_values = jQuery('th.check-column input[type="checkbox"]:checked').map(function() { + return jQuery(this).val(); + }).get(); + + var event_filter = jQuery(filter_event_selector).val(); + + var top_selector = jQuery('#bulk-action-selector-top').val(), + bottom_selector = jQuery('#bulk-action-selector-bottom').val(), + search = jQuery(search_selector).val(), + action; + + if ('-1' !== top_selector) { + action = top_selector; + } else if ('-1' !== bottom_selector) { + action = bottom_selector; + } else { + action = '-1'; + } + + var data = { + 'paged': get_page_number(jQuery(this)), + 'order': get_order(jQuery(this)), + 'orderby': get_order_by(jQuery(this)), + 's': search || '', + 'level-filter': jQuery(filter_level_selector).val() || '-1', + 'event-filter': event_filter || '-1', + 'items': checked_values, + 'action': action + }; + + update_list_table(tab, data); + + jQuery(action_selector).val('-1'); + } + } + + /** + * Remove the message after a set time. + * + * @returns {void} + */ + function remove_aios_message() { + setTimeout(function() { + jQuery('#aios_message').remove(); + }, 5000); + } + + /** + * Get the column ID based on the clicked element or the current sorting state. + * + * @param {jQuery} element - The jQuery object representing the clicked element. + * + * @returns {string} The ID of the column. + */ + function get_order_by(element) { + if (element.is('.manage-column.sortable a')) return element.closest('th').attr('id'); + else if (0 < jQuery('.sorted').length) return jQuery('.sorted').attr('id'); + else return element.closest('th').attr('id'); + } + + /** + * Get the order (ascending or descending) based on the clicked element or the current sorting state. + * + * @param {jQuery} element - The jQuery object representing the clicked element. + * + * @returns {string} The order ('asc' for ascending, 'desc' for descending). + */ + function get_order(element) { + if (element.is('.manage-column.sortable a') || element.is('.manage-column.sorted a')) { + var url = element.attr('href'), + orderMatch = url.match(/[?&]order=([^&]+)/); + return orderMatch[1]; + } else if (0 < jQuery('.sorted').length) { + return jQuery('.sorted').hasClass('asc') ? 'asc' : 'desc'; + } else { + return element.closest('th').hasClass('asc') ? 'asc' : 'desc'; + } + } + + /** + * Get the page number based on the clicked element. + * + * @param {jQuery} element - The jQuery object representing the clicked element. + * + * @returns {number|string} The page number. If the clicked element represents a specific page, returns that page number. If not, returns the current page number. + */ + function get_page_number(element) { + if (element.hasClass('first-page')) + return '1'; + else if (element.hasClass('last-page')) + return find_page_number(jQuery('.last-page')); + else if (element.hasClass('prev-page')) + return find_page_number(jQuery('.prev-page')); + else if (element.hasClass('next-page')) + return find_page_number(jQuery('.next-page')); + else return jQuery('.current-page').val(); + } + + /** + * Finds and returns the page number from the href attribute of the provided element. + * + * @param {jQuery} element - The jQuery object representing the element containing the href attribute. + * + * @returns {number} The page number extracted from the href attribute. + */ + function find_page_number(element) { + return parseInt(element.attr('href').split('paged=')[1]); + } + + /** + * Update the list table with data from an AJAX call. + * If the current page number exceeds the total pages available, + * make a new request for the last available page. + * + * @param {string} table - The table tab. + * @param {object} data - The data object containing table parameters. + */ + function update_list_table(table, data) { + aios_send_command(table, data, function (response) { + // Check if the requested page number exceeds the total pages available + if (data.paged > response.total_pages && 0 < response.total_pages) { + // Update data to request the last available page + data.paged = response.total_pages; + // Make another AJAX call to get the data for the last page + aios_send_command(table, data, function (response) { + render_table(response); + }, { + error_callback: handle_ajax_error + }); + } else { + // Proceed to render the table with the current response + render_table(response); + } + }, { + error_callback: handle_ajax_error + }); + } + // End of list table handling + + /** + * Render the table elements based on the AJAX response. + * + * @param {object} response - The response object from the AJAX call. + */ + function render_table(response) { + // Add the requested rows + if (response.rows.length) jQuery('#the-list').html(response.rows); + // Update column headers for sorting + if (response.column_headers.length) jQuery('thead tr, tfoot tr').html(response.column_headers); + // Update pagination for navigation + if (response.pagination.top.length) jQuery('.tablenav.top .tablenav-pages').html(jQuery(response.pagination.top).html()); + if (response.pagination.bottom.length) jQuery('.tablenav.bottom .tablenav-pages').html(jQuery(response.pagination.bottom).html()); + + // Add/Remove the message + if (response.message && response.message.length) { + aios_show_ajax_response_message(response); + } else { + remove_aios_message(); + setTimeout(function() { + jQuery.unblockUI(); + }, 3000); + } + } + + /** + * Handle errors from the AJAX call. + * + * @param {object} response - The response object from the AJAX call. + * @param {string} status - The status of the AJAX call. + * @param {string} error_code - The error code from the AJAX call. + * @param {object} resp - The response object containing detailed error information. + */ + function handle_ajax_error(response, status, error_code, resp) { + if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) { + console.error(resp.fatal_error_message); + alert(resp.fatal_error_message); + } else { + var error_message = "aios_send_command: error: " + status + " (" + error_code + ")"; + console.log(error_message); + alert(error_message); + } + jQuery.unblockUI(); + } + + // Start of database table prefix handling + jQuery('#aiowps_enable_random_prefix').on('click', function() { + jQuery('#aiowps_new_manual_db_prefix').prop('disabled', jQuery(this).prop('checked')); + }); + + jQuery('#aiowps_new_manual_db_prefix').on('input', function() { + if (jQuery(this).prop('value')) { + jQuery('#aiowps_enable_random_prefix').prop('disabled', true); + } else { + jQuery('#aiowps_enable_random_prefix').prop('disabled', false); + } + }); + // End of database table prefix handling + + // Dashboard menu ajaxify + jQuery("#locked-ip-list-table").on('click', '.aios-unlock-ip-button', function(e) { + e.preventDefault(); + var element = jQuery(this); + if (confirm(element.data('message'))) { + aios_submit_form(element, 'unlock_ip', {ip: element.data('ip')}, aios_trans.processing, null, function(response) { + if ('success' === response.status) jQuery('#locked-ip-list-table').load(' #locked-ip-list-table > *'); + }) + } + }); + + jQuery("#locked-ip-list-table").on('click', '.aios-delete-locked-ip-record', function(e) { + e.preventDefault(); + var element = jQuery(this); + confirm(element.data('message')) ? aios_send_command('delete_locked_ip_record', {id: element.data('id')}, function(response) { + jQuery('#aios_message').remove(); + jQuery('#wpbody-content .wrap h2:first').after(response.message); + if ('success' === response.status) jQuery('#locked-ip-list-table').load(' #locked-ip-list-table > *'); + }) : false; + }); + + jQuery("#permanent-ip-list-table").on('click', '.aios-unblock-permanent-ip', function(e) { + e.preventDefault(); + var element = jQuery(this); + if (confirm(element.data('message'))) { + aios_submit_form(element,'blocked_ip_list_unblock_ip', {id: element.data('id')}, aios_trans.processing, null, function(response) { + if ('success' === response.status) jQuery('#permanent-ip-list-table').load(' #permanent-ip-list-table > *'); + }) + } + }); + + jQuery('#audit-log-list-table').on('click', '.aios-delete-audit-log', function(e) { + e.preventDefault(); + var element = jQuery(this); + + if (confirm(element.data('message'))) { + aios_submit_form(element, 'delete_audit_log', {id: element.data('id')}, aios_trans.processing, null, function(response) { + if ('success' === response.status) detect_table_action(audit_log_table_id, '.aios-delete-audit-log', audit_log_bulk_action_selector, audit_log_table_tab, audit_log_filter_event, audit_log_search, audit_log_level, detect = false); + }) + } + }); + + jQuery('#audit-log-list-table').on('click', '.aios-unlock-ip-button', function(e) { + e.preventDefault(); + var element = jQuery(this); + if (confirm(element.data('message'))) { + aios_submit_form(element, 'unlock_ip', {ip: element.data('ip')}, aios_trans.processing, null, function(response) { + if ('success' === response.status) detect_table_action(audit_log_table_id, '.aios-unlock-ip-button', audit_log_bulk_action_selector, audit_log_table_tab, audit_log_filter_event, audit_log_search, audit_log_level, detect = false); + }) + } + }); + + jQuery('#audit-log-list-table').on('click', '.aios-unblacklist-ip-button', function(e) { + e.preventDefault(); + var element = jQuery(this); + if (confirm(element.data('message'))) { + aios_submit_form(element, 'unblacklist_ip', {ip: element.data('ip')}, aios_trans.processing, null, function(response) { + if ('success' === response.status) detect_table_action(audit_log_table_id, '.aios-unblacklist-ip-button', audit_log_bulk_action_selector, audit_log_table_tab, audit_log_filter_event, audit_log_search, audit_log_level, detect = false); + }) + } + }); + + jQuery('#audit-log-list-table').on('click', '.aios-lock-ip-button', function(e) { + e.preventDefault(); + var element = jQuery(this); + if (confirm(element.data('message'))) { + aios_submit_form(element,'lock_ip', {ip: element.data('ip'), lock_reason: 'audit-log'}, aios_trans.processing, null, function (response) { + if ('success' === response.status) detect_table_action(audit_log_table_id, '.aios-lock-ip-button', audit_log_bulk_action_selector, audit_log_table_tab, audit_log_filter_event, audit_log_search, audit_log_level, false); + }) + } + }); + + jQuery('#audit-log-list-table').on('click', '.aios-blacklist-ip-button', function(e) { + e.preventDefault(); + var element = jQuery(this); + if (confirm(element.data('message'))) { + aios_submit_form(element,'blacklist_ip', {ip: element.data('ip')}, aios_trans.processing, null, function(response) { + if ('success' === response.status) detect_table_action(audit_log_table_id, '.aios-blacklist-ip-button', audit_log_bulk_action_selector, audit_log_table_tab, audit_log_filter_event, audit_log_search, audit_log_level, detect = false); + }) + } + }); + + jQuery('#audit-log-list-table').on('click', '#aiowps_export_audit_event_logs_to_csv', function(e) { + e.preventDefault(); + + aios_submit_form(jQuery(this), 'export_audit_logs', true, aios_trans.processing, null, function (response) { + aios_download_csv_file(response.data, response.title); + }); + }); + + jQuery('#aios-clear-debug-logs').on('click', '.aios-clear-debug-logs', function(e) { + e.preventDefault(); + if (confirm(jQuery(this).data('message'))) { + aios_send_command('clear_debug_logs', {}, function(response) { + jQuery('#aios_message').remove(); + jQuery('#wpbody-content .wrap h2:first').after(response.message); + if ("success" === response.status) jQuery('#debug-list-table').load(' #debug-list-table > *'); + }); + } + }); + // End of dashboard menu ajaxify + + //Start of Spam prevention ajaxify + jQuery('#aios-spam-prevention-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_comment_spam_prevention'); + }) + + jQuery('#aios-auto-spam-block-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_auto_block_spam_ip'); + }) + + jQuery('#aios-spam-ip-search-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_ip_spam_search', true, aios_trans.processing, null, function (response) { + var targetOffset = jQuery('#aios-spammer-list-table').offset().top; + jQuery('html, body').animate({ scrollTop: targetOffset }, 'slow'); + if ("success" === response.status) { + jQuery('#aios-spammer-list-table').load(' #aios-spammer-list-table > *'); + } + }) + }) + + jQuery('#aios-spammer-list-table').on('click', '.aios-block-author-ip', function(e) { + e.preventDefault(); + var ip = jQuery(this).data('ip'); + var data = { + 'ip': ip + } + + if (confirm(jQuery(this).data('message'))) { + aios_submit_form(jQuery(this), 'perform_block_spam_ip', data, aios_trans.processing, null, function (response) { + if ("success" === response.status) { + jQuery('#aios-spammer-list-table').load(' #aios-spammer-list-table > *'); + jQuery('html, body').animate({ scrollTop: 0 }, 'slow'); + } + }); + } + }) + //End of spam prevention ajaxify + + // Start of settings menu ajaxify + jQuery('#aiowpsec-disable-all-features-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_disable_all_features', true, aios_trans.disabling); + }); + + jQuery('#aiowpsec-disable-all-firewall-rules-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_disable_all_firewall_rules', true, aios_trans.disabling); + }); + + jQuery('#aiowpsec-reset-settings-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_reset_all_settings', true, aios_trans.processing); + }); + + jQuery('#aiowps_enable_debug').on('change', function(e) { + e.preventDefault(); + var aiowps_enable_debug = jQuery(this).is(':checked') ? '1' : ''; + var data = { + 'aiowps_enable_debug': aiowps_enable_debug + }; + + aios_submit_form(jQuery(this), 'perform_save_debug_settings', data, aios_trans.processing); + }); + + jQuery('#aiowpsec-save-htaccess-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_backup_htaccess_file', true, aios_trans.processing, null, function (response) { + if ('success' === response.status) { + aios_download_txt_file(response.extra_args.data, response.extra_args.title); + } + }); + }); + + jQuery('#aiowpsec-delete-plugin-settings-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_delete_plugin_settings'); + }); + + jQuery('#aiowpsec-remove-wp-meta-info-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_remove_wp_version_info_settings'); + }); + + jQuery('#aiowpsec-ip-settings-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_save_ip_settings'); + }); + + jQuery('#aiowpsec-save-wp-config-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_save_wp_config', {}, aios_trans.saving, null, function(response) { + aios_download_txt_file(response.extra_args.data, response.extra_args.title); + }); + }); + + jQuery('#aiowpsec-export-settings-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_export_aios_settings', {}, aios_trans.exporting, null, function(response) { + aios_download_txt_file(response.extra_args.data, response.extra_args.title); + }); + }); + // End of settings menu ajaxify + // Start of Filesystem menu ajaxify + jQuery('#aios-file-permissions-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_fix_permissions', true, aios_trans.processing); + }) + + jQuery('#aiowps_delete_default_wp_files').on('click', function(e) { + e.preventDefault(); + var button = jQuery(this); + aios_submit_form(jQuery(this), 'perform_delete_default_wp_files', {'aios-delete_default_wp_files': 1}, aios_trans.deleting, function() { + button.prop('disabled', true); + }, + function(response) { + button.prop('disabled', false); + }); + }) + + jQuery('#aios-file-protection-settings-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_file_protection_settings'); + }) + + jQuery('#aios-host-system-logs-form').on('submit', function(e) { + e.preventDefault(); + + aios_submit_form(jQuery(this), 'perform_host_system_logs', true, aios_trans.processing, function () { + jQuery('#aios-host-system-logs-results').html(''); + jQuery('#aiowps_activejobs_table').html('

            '+ aios_trans.processing + '

            '); + jQuery('#aiowps_activejobs_table .aiowps_spinner').addClass('visible'); + }, + function(response) { + var loading_span = jQuery('#aiowps_activejobs_table'); + loading_span.hide(); + }); + }) + + jQuery('#aios-frame-display-settings-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_save_frame_display_prevent'); + }) + + jQuery('#aios-copy-protection-settings-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this),'perform_save_copy_protection'); + }) + //End of Filesystem menu ajaxify + + // Firewall menu ajaxify + jQuery('#aios-php-firewall-settings-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_php_firewall_settings', true, aios_trans.saving, null, function(response) { + if ("success" === response.status) { + jQuery('.aio_orange_box').remove(); + if (jQuery('#aiowps_enable_6g_firewall').prop('checked')) { + jQuery('.aios-toggle-advanced-options').removeClass('advanced-options-disabled'); + jQuery('.aios-advanced-options-panel .aiowps_more_info_body').hide(); + toggleMoreInfo('.aios-advanced-options-panel .aiowps_more_info_anchor'); + } else { + jQuery('.aios-toggle-advanced-options').addClass('advanced-options-disabled'); + jQuery('.button.button-link.aios-toggle-advanced-options').removeClass('opened'); + } + check_input(); + jQuery('#post-body h2:first').after(response.extra_args.xmlprc_warning); + } + }); + }); + + jQuery('#aios-htaccess-firewall-settings-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this),'perform_htaccess_firewall_settings'); + }); + + jQuery("#aios-blacklist-settings-form").on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this),'perform_save_blacklist_settings'); + }); + + jQuery("#aios-firewall-allowlist-form").on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this),'perform_firewall_allowlist'); + }); + + jQuery("#aios-5g-firewall-settings-form").on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_save_5g_settings') + }); + + jQuery('#aiowps-firewall-status-container').on('submit', "#aiowpsec-firewall-setup-form", function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_setup_firewall', true, aios_trans.setting_up_firewall, null, function (response) { + if (response.extra_args && response.extra_args.info_box) { + jQuery("#aios-firewall-setup-notice").remove(); + jQuery('#wpbody-content .wrap h2:first').after(response.extra_args.info_box); + } + }); + }); + + jQuery('#aiowps-firewall-status-container').on('submit', "#aiowps-firewall-downgrade-form", function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_downgrade_firewall', true, aios_trans.downgrading_firewall, null, function (response) { + if (response.extra_args && response.extra_args.info_box) { + jQuery("#aios-firewall-installed-notice").remove(); + jQuery('#wpbody-content .wrap h2:first').after(response.extra_args.info_box); + } + }); + }); + + jQuery('#aios-upgrade-unsafe-http-calls-settings-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_save_upgrade_unsafe_http_calls_settings'); + }) + // end of firewall menu ajax + + // Start of file scan handling + jQuery('.aiowps_next_scheduled_scan_wrapper').on('click', '.aiowps_view_last_fcd_results', view_scan_results_handler); + jQuery('#aiowps_fcds_change_detected').on('click', '.aiowps_view_last_fcd_results', view_scan_results_handler); + + // start of user security menu ajax + jQuery('#aios-user-accounts-settings-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_save_user_account_settings'); + }); + + jQuery('#aios-change-admin-username-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_change_admin_username', true, aios_trans.saving, null, function (response) { + if (response.hasOwnProperty('logout_user') && true === response.logout_user) { + setTimeout(function() { + // Check if a logout URL is present in the response + if (response.hasOwnProperty('logout_url')) { + // Redirect to the logout URL + window.location.href = response.logout_url; + } else { + // If no logout URL is provided, reload the current page + location.reload(); + } + }, 3000); + } + }); + }); + + jQuery('#aios-user-login-lockdown-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_save_login_lockout_settings'); + }); + + jQuery('#aios-user-login-lockout-whitelist-settings-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_save_login_lockout_whitelist_settings'); + }); + + jQuery('#aios-force-user-logout-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_force_logout', true, aios_trans.saving, null, function (response) { + if (response.hasOwnProperty('logout_user') && true === response.logout_user) { + setTimeout(function() { + // Check if a logout URL is present in the response + if (response.hasOwnProperty('logout_url')) { + // Redirect to the logout URL + window.location.href = response.logout_url; + } else { + // If no logout URL is provided, reload the current page + location.reload(); + } + }, 3000); + } + }); + }); + + jQuery('#aios-hibp-password-settings-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_save_hibp_settings'); + }); + + jQuery('#aios-disable-application-password-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_disable_application_password'); + }); + + jQuery('#aios-enable-salt-postfix-form').submit(function (e) { + e.preventDefault(); + aios_submit_form(jQuery(this),'perform_add_salt_postfix', true, aios_trans.saving, null,function() { + setTimeout(function () { + location.reload(); + }, 3000); + }); + }); + + jQuery('#aios-logged-in-users-table').on('click', '.aios-force-logout-user', function(e) { + e.preventDefault(); + let user_id = jQuery(this).data('user-id'), data = { + logged_in_id: user_id, + action: 'force_user_logout' + }; + if (confirm(jQuery(this).data('message'))) { + aios_submit_form(jQuery(this), 'perform_logged_in_user_action', data, aios_trans.processing, null, function (response) { + if ('success' === response.status) { + jQuery('#aios-logged-in-users-table').load(' #aios-logged-in-users-table > *'); + } + }); + } + }); + + jQuery("#aios-refresh-logged-in-user-list-form").on('submit', function(e) { + e.preventDefault(); + aios_block_ui(aios_trans.refreshing); + var submitButton = jQuery(this).find(':submit'); + submitButton.prop('disabled', true); + jQuery('#aios-logged-in-users-table').load(' #aios-logged-in-users-table > *', function () { + jQuery.unblockUI(); + submitButton.prop('disabled', false); + }); + }); + + jQuery('#aios-manually-approve-registrations-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_manual_approval_settings'); + }); + + jQuery("#aios-manual-approval-table").on('click', '.aios-approve-user-acct', function(e) { + e.preventDefault(); + let user_id = jQuery(this).data('id'), data = { + user_id: user_id, + action: 'approve_acct' + }; + if (confirm(jQuery(this).data('message'))) { + aios_submit_form(jQuery(this), 'perform_manual_approval_item_action', data, aios_trans.processing, null, function () { + jQuery('#aios-manual-approval-table').load(' #aios-manual-approval-table > *'); + }); + } + }); + + jQuery("#aios-manual-approval-table").on('click', '.aios-delete-user-acct', function(e) { + e.preventDefault(); + let user_id = jQuery(this).data('id'), data = { + user_id: user_id, + action: 'delete_acct' + }; + if (confirm(jQuery(this).data('message'))) { + aios_submit_form(jQuery(this), 'perform_manual_approval_item_action', data, aios_trans.processing, null, function () { + jQuery('#aios-manual-approval-table').load(' #aios-manual-approval-table > *'); + }); + } + }); + + jQuery("#aios-manual-approval-table").on('click', '.aios-block-ip', function(e) { + e.preventDefault(); + let ip_address = jQuery(this).data('ip'), data = { + ip_address: ip_address, + action: 'block_ip' + }; + if (confirm(jQuery(this).data('message'))) { + aios_submit_form(jQuery(this),'perform_manual_approval_item_action', data, aios_trans.blocking, null, function() { + jQuery('#aios-manual-approval-table').load(' #aios-manual-approval-table > *'); + }) + } + }); + + jQuery("#aios-refresh-manual-approval-list-form").on('submit', function(e) { + e.preventDefault(); + aios_block_ui(aios_trans.refreshing); + var submitButton = jQuery(this).find(':submit'); + submitButton.prop('disabled', true); + jQuery('#aios-manual-approval-table').load(' #aios-manual-approval-table > *', function () { + jQuery.unblockUI(); + submitButton.prop('disabled', false); + }); + }); + + jQuery("#aios-enforce-strong-password-form").on('submit', function(e) { + e.preventDefault(); + + aios_submit_form(jQuery(this), 'enforce_strong_password'); + }); + + // end of user security menu ajax + + // start of tools menu ajaxify + jQuery("#aiowpsec-whois-lookup-form").on('submit', function(e) { + e.preventDefault(); + + jQuery('#aios-who-is-lookup-result-container').html(''); + + aios_submit_form(jQuery(this), 'perform_whois_lookup', true, aios_trans.processing, null, function () { + var targetOffset = jQuery('#aios-who-is-lookup-result-container').offset().top; + jQuery('html, body').animate({ scrollTop: targetOffset }, 'slow'); + }); + }); + + jQuery("#aiowpsec-site-lockout-form").on('submit', function (e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_general_visitor_lockout', true, aios_trans.saving, function () { + var editor = tinyMCE.get('aiowps_site_lockout_msg_editor_content'); + if (editor) { + editor.save(); + } + }); + }); + + jQuery('#maintenance_mode_status').on('click', '#aiowps_site_lockout', function (e) { + aios_block_ui(aios_trans.saving); + + var enabled = jQuery(this).is(':checked'); + var data = {}; + + if (enabled) { + data.aiowps_site_lockout = '1'; + } + + aios_send_command('perform_general_visitor_lockout_dashboard_widget', data, function(response) { + aios_show_ajax_response_message(response); + if ('success' === response.status) { + if (enabled) { + jQuery("#aiowpsec-dashboard-maintenance-mode-status-message").text(aios_trans.maintenance_mode_enabled); + } else { + jQuery("#aiowpsec-dashboard-maintenance-mode-status-message").text(aios_trans.maintenance_mode_disabled); + } + } + }); + }); + + jQuery("#aiowpsec-save-custom-rules-settings-form").on('submit', function (e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_store_custom_htaccess_settings'); + }); + // end of tools menu ajaxify + jQuery('#aiowpsec-scheduled-fcd-scan-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_save_file_detection_change_settings'); + }); + + /** + * This function handles the view last scan result event + * + * @param {*} e - the event + */ + function view_scan_results_handler(e) { + e.preventDefault(); + + var reset_change_detected = jQuery(this).data('reset_change_detected') ? 1 : 0; + + aios_submit_form(jQuery(this), 'get_last_scan_results', { reset_change_detected: reset_change_detected}, aios_trans.processing, null, function (response) { + if (reset_change_detected) jQuery('#aiowps_fcds_change_detected').remove(); + var targetOffset = jQuery('#aiowps_previous_scan_wrapper').offset().top; + jQuery('html, body').animate({ scrollTop: targetOffset }, 'slow'); + }) + } + + jQuery('#aiowps_manual_fcd_scan').on('click', function(e) { + e.preventDefault(); + + aios_submit_form(jQuery(this), 'perform_file_scan', true, aios_trans.scanning, function () { + jQuery('#aiowps_activejobs_table').html('

            '+ aios_trans.processing + '

            '); + jQuery('#aiowps_activejobs_table .aiowps_spinner').addClass('visible'); + }, function (response) { + jQuery('#aiowps_activejobs_table').html(''); + if ('success' === response.status) { + jQuery('#aiowps_activejobs_table').append('

            '+response.extra_args.result+'

            '); + } + }); + }); + // End of file scan handling + + // start of brute force ajax + jQuery('#aios-rename-login-page-form').on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_rename_login_page', true, aios_trans.saving, null,function(response) { + if ("error" === response.status) { + jQuery('#aiowps_enable_rename_login_page').prop('checked', false); + } + }) + }); + + jQuery("#aios-cookie-based-settings-form").on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_cookie_based_brute_force_prevention', true, aios_trans.saving, null, function (response) { + if ("success" === response.status) { + jQuery('#aios_message').remove(); + jQuery('#post-body .postbox').before(response.info_box); + } + }) + }); + + jQuery("#aios-perform-cookie-test").on('click', function(e) { + e.preventDefault(); + var cookieButton = jQuery(this); + cookieButton.prop('disabled', true); + + aios_submit_form(jQuery(this), 'perform_cookie_test', {}, aios_trans.processing, null,function(response) { + cookieButton.prop('disabled', false); + if ("success" === response.status) { + var submitButton = jQuery('#aios-cookie-based-settings-form').find(':submit'); + submitButton.prop('disabled', false); + } + }) + }); + + jQuery("#aios-login-whitelist-settings-form").on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_login_whitelist_settings'); + }); + + jQuery("#aios-honeypot-settings-form").on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_honeypot_settings'); + }); + + jQuery("#aios-captcha-settings-form").on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_captcha_settings'); + }); + + jQuery("#aios-404-detection-settings-form").on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_404_settings', true, aios_trans.saving, null, function(response) { + if ("success" === response.status) { + jQuery('.aios-404-detection-container').toggleClass('aio_hidden', !jQuery('#aiowps_enable_404_IP_lockout').is(':checked')); + } + }); + }); + + jQuery("#aios-delete-404-form").on('submit', function(e) { + e.preventDefault(); + aios_submit_form(jQuery(this), 'perform_delete_404_event_records', true, aios_trans.deleting, null, function(response) { + if ("success" === response.status) jQuery('#aios-404-event-logs-table').load(' #aios-404-event-logs-table > *', function () { + jQuery(".aiowps_more_info_body").hide(); + }); + }); + }); + + jQuery("#aios-404-event-logs-table").on('click', ".aios-delete-404", function(e) { + e.preventDefault(); + let data = { + id: jQuery(this).data('id'), + action: 'delete' + }; + if (confirm(jQuery(this).data('message'))) { + aios_submit_form(jQuery(this), 'perform_404_log_item_action', data, aios_trans.deleting, null, function (response) { + if ('success' === response.status) jQuery('#aios-404-event-logs-table').load(' #aios-404-event-logs-table > *'); + }); + } + }); + + jQuery("#aios-404-event-logs-table").on('click', ".aios-temp-block-404", function(e) { + e.preventDefault(); + let ip = jQuery(this).data('ip'), username = jQuery(this).data('username'), data = { + ip: ip, + action: 'temp_block', + username: username + }; + if (confirm(jQuery(this).data('message'))) { + aios_submit_form(jQuery(this), 'perform_404_log_item_action', data, aios_trans.blocking, null, function (response) { + if ('success' === response.status) jQuery('#aios-404-event-logs-table').load(' #aios-404-event-logs-table > *'); + }); + } + }); + + jQuery("#aios-404-event-logs-table").on('click', ".aios-blacklist-404", function(e) { + e.preventDefault(); + let ip = jQuery(this).data('ip'), data = { + ip: ip, + action: 'blacklist' + }; + if (confirm(jQuery(this).data('message'))) { + aios_submit_form(jQuery(this), 'perform_404_log_item_action', data, aios_trans.processing, null, function (response) { + if ('success' === response.status) jQuery('#aios-404-event-logs-table').load(' #aios-404-event-logs-table > *'); + }); + } + }); + + jQuery("#aios-404-event-logs-table").on('click', ".aios-unblock-404", function(e) { + e.preventDefault(); + let ip = jQuery(this).data('ip'), data = { + ip: ip, + action: 'unblock' + }; + if (confirm(jQuery(this).data('message'))) { + aios_submit_form(jQuery(this), 'perform_404_log_item_action', data, aios_trans.unlocking, null, function (response) { + if ('success' === response.status) jQuery('#aios-404-event-logs-table').load(' #aios-404-event-logs-table > *'); + }); + } + }); + // end of brute force ajax + + // Start of login whitelist suggests both IPv4 and IPv6 + if (jQuery('#aios_user_ip_maybe_also').length) { + var selector = '#aios-ipify-ip-address'; + var ipfield = '#aios_user_ip_maybe_also'; + var getting_text = jQuery(ipfield).attr('getting_text'); + var ip_maybe = jQuery(ipfield).attr('ip_maybe'); + if ('v6' == ip_maybe) { + var url = 'https://api64.ipify.org/?format=json'; + } else { + var url = 'https://api.ipify.org/?format=json'; + } + jQuery(selector).html(getting_text); + jQuery.ajax({ + type: 'GET', + dataType: 'json', + url: url, + success: function (response, status) { + if (response.hasOwnProperty('ip') && response.ip != jQuery('#aiowps_user_ip').val()) { + jQuery(ipfield).val(response.ip); + jQuery(ipfield).removeClass('aio_hidden'); + } else { + console.log(response); + } + jQuery(selector).html(''); + }, + error: function (response, status, error_code) { + console.log(response); + jQuery(selector).html(''); + } + }); + } + // End of login whitelist suggests both IPv4 and IPv6 + + // Click the 'show/hide advanced options' button + jQuery('button.button-link.aios-toggle-advanced-options').on('click', function() { + if (!jQuery(this).hasClass('advanced-options-disabled')) { + jQuery(this).toggleClass('opened'); + } + }); + + // Start of the new UI settings + var initial_values = {}; + jQuery('.aiowps-actions').hide(); + + /** + * Set active tab from URL + * + * @param {string} subtab + * + * @returns {void} + */ + function set_active_tab_from_url() { + const url_params = new URLSearchParams(window.location.search); + const subtab = url_params.get('subtab'); + if (subtab) { + jQuery('.aiowps-rules li').removeClass('aiowps-active'); + jQuery(`.aiowps-rules li[data-template="${subtab}"]`).addClass('aiowps-active'); + jQuery('.aiowps-settings .postbox').hide(); + jQuery(`.aiowps-settings .postbox[data-template="${subtab}"]`).show(); + } else { + jQuery('.aiowps-settings .postbox:first').show(); + } + } + + var initial_values = {}; + + /** + * Store initial values of the settings + * + * @returns {void} + */ + function store_values() { + jQuery('.aiowps-settings :input').each(function() { + if (jQuery(this).is(':checkbox')) { + initial_values[jQuery(this).attr('name')] = jQuery(this).is(':checked'); + } else { + initial_values[jQuery(this).attr('name')] = jQuery(this).val(); + } + }); + } + + // Store initial values on page load + store_values(); + + // Add change event listener to all inputs + function check_input() { + jQuery('.aiowps-settings :input').on('change', function() { + var all_inputs_back_to_original = true; + jQuery('.aiowps-settings :input').each(function() { + var input_name = jQuery(this).attr('name'); + if (jQuery(this).is(':checkbox')) { + if (jQuery(this).is(':checked') !== initial_values[input_name]) { + all_inputs_back_to_original = false; + return false; + } + } else { + if (jQuery(this).val() !== initial_values[input_name]) { + all_inputs_back_to_original = false; + return false; + } + } + }); + + if (all_inputs_back_to_original) { + jQuery('.aiowps-actions').hide(); + } else { + jQuery('.aiowps-actions').show(); + } + }); + } + check_input(); + // Add click event listener to the button + jQuery('.aiowps-actions :input').on('click', function() { + // Hide the actions div + jQuery('.aiowps-actions').hide(); + + // Re-store the values + store_values(); + }); + + /** + * Initiates the download of a text file with the provided data and title. + * + * @param {string} data - The text data to be included in the file. + * @param {string} title - The name of the file to be downloaded. + */ + function aios_download_txt_file(data, title) { + + // Create a Blob containing the text data + let blob = new Blob([data], {type: 'text/plain'}); + aios_download_file(blob, title); + } + + /** + * Initiates the download of a CSV file with the provided data and title. + * + * @param {string} data - The CSV data to be included in the file. + * @param {string} title - The name of the file to be downloaded. + */ + function aios_download_csv_file(data, title) { + + // Create a Blob containing the CSV data + let blob = new Blob([data], {type: 'text/csv'}); + aios_download_file(blob, title); + } + + /** + * Triggers the download of a file using the provided Blob and filename. + * + * This function creates a temporary URL for the given Blob, then creates + * and triggers a download of the file with the specified title. After the + * download is initiated, it cleans up by removing the temporary element + * and revoking the Blob URL. + * + * @param {Blob} blob - The Blob object containing the file data to be downloaded. + * @param {string} title - The name of the file to be downloaded (including the file extension). + */ + function aios_download_file(blob, title) { + + // Create a temporary URL to the Blob + let url = window.URL.createObjectURL(blob); + + // Create a temporary element to trigger the download + let a = document.createElement('a'); + a.href = url; + a.download = title; + document.body.appendChild(a); + a.click(); + + // Cleanup: remove the temporary element and revoke the Blob URL + document.body.removeChild(a); + window.URL.revokeObjectURL(url); + } + + // Add click event listener to rules + jQuery('.aiowps-rules li').on('click', function() { + jQuery('.aiowps-rules li').removeClass('aiowps-active'); + jQuery(this).addClass('aiowps-active'); + var template = jQuery(this).data('template'); + jQuery('.aiowps-settings .postbox').hide(); + jQuery('.aiowps-settings .postbox').each(function() { + if (jQuery(this).data('template') === template) { + jQuery(this).show(); + return false; + } + }); + const url_params = new URLSearchParams(window.location.search); + const subtab_param = 'subtab=' + template; + + if (url_params.has('subtab')) { + // If subtab parameter already exists, replace its value + url_params.set('subtab', template); + } else { + // If subtab parameter doesn't exist + if ("" === url_params.toString()) { + // If there are no existing parameters, append subtab with '?' + window.history.replaceState({}, '', window.location.pathname + '?' + subtab_param); + return; + } else { + // If there are existing parameters + const query_params = Array.from(url_params.entries()); + const new_params = query_params.map(param => param.join('=')).join('&'); + window.history.replaceState({}, '', window.location.pathname + '?' + new_params + '&' + subtab_param); + return; + } + } + + window.history.replaceState({}, '', window.location.pathname + '?' + url_params.toString()); + }); + + // Search for rules + jQuery('.aiowps-search').on('keydown', function(event) { + if ('Enter' === event.key) { + event.preventDefault(); + } + }); + + jQuery('.aiowps-search').on('keyup', function(event) { + if ('Enter' === event.key) { + event.preventDefault(); + } + var value = jQuery(this).val().toLowerCase(); + jQuery('.aiowps-rules li').each(function() { + var template_value = jQuery(this).data('template').toLowerCase(); + var span_text = jQuery(this).find('span').text().toLowerCase(); + var th_match = false; + jQuery('.form-table th').each(function() { + var th_text = jQuery(this).text().toLowerCase(); + if (th_text.indexOf(value) > -1) { + var template = jQuery(this).closest('.postbox').data('template'); + if (template === template_value) { + th_match = true; + return false; + } + } + }); + if (template_value.indexOf(value) > -1 || span_text.indexOf(value) > -1 || th_match) { + jQuery(this).show(); + } else { + jQuery(this).hide(); + } + }); + }); + + jQuery('#aiowps-rule-search .clear-search').on('click', function() { + jQuery('.aiowps-search').val(''); + jQuery('.aiowps-search').trigger('keyup'); + }); + + set_active_tab_from_url(); + // End of the new UI settings + + //toggle xmlrpc warning + jQuery('#aiowps_enable_pingback_firewall').change(function() { + if (jQuery(this).is(':checked')) { + // When the checkbox is checked, remove the 'aio_hidden' class + jQuery('.xmlrpc_warning_box').removeClass('aio_hidden'); + } else { + // Optionally, if unchecked, you can add the class back (if needed) + jQuery('.xmlrpc_warning_box').addClass('aio_hidden'); + } + }); + + // Start of WP REST API toggle whitelist setting handling + jQuery('input[name=aiowps_disallow_unauthorized_rest_requests]').on('click', function() { + jQuery('.aios-rest-white-list-options-panel').toggleClass('hidden'); + }); + // End of WP REST API toggle whitelist setting handling + + // Start of the copy report button handling + jQuery('#copy-report').on('click', function(event) { + var text = jQuery('#report-textarea').val(); + if (navigator.clipboard) { + navigator.clipboard.writeText(text).then(function() { + alert(aios_trans.copied); + }, function() { + deprecated_copy(text); + }); + } else { + deprecated_copy(text); + } + }); + // End of the copy report button handling + + // Start of the send report button handling + jQuery('#send-report').on('click', function(e) { + e.preventDefault(); + var report_email = jQuery('#report_email').val(); + var report_sections = jQuery('#report_sections').val(); + jQuery('#report-response').html('

            '+ aios_trans.processing + '

            '); + jQuery('#report-response .aiowps_spinner').addClass('visible'); + + aios_send_command('send_report_email', {'report_email': report_email, 'report_sections': report_sections}, function (resp) { + if (resp.hasOwnProperty('message')) { + alert(resp.message); + } + }); + }); + // End of the send report button handling +}); diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/js/wp-security-front-script.js b/wp-content/plugins/all-in-one-wp-security-and-firewall/js/wp-security-front-script.js new file mode 100755 index 00000000..7a9e3cc3 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/js/wp-security-front-script.js @@ -0,0 +1,32 @@ +jQuery(function($) { + // antibot keys are expired then add new keys to comment form + if ($('.comment-form-aios-antibot-keys').length && $('#aios_antibot_keys_expiry').length) { + if ($('#aios_antibot_keys_expiry').val() < Math.floor(Date.now() / 1000)) { + jQuery.ajax({ + url: AIOS_FRONT.ajaxurl, + type: 'post', + dataType: 'json', + cache: false, + data: { + action: 'get_antibot_keys', + nonce: AIOS_FRONT.ajax_nonce + }, + success: function(resp) { + if (resp.hasOwnProperty('error_code')) { + console.log("ERROR: " + resp.error_message); + } else if (resp.hasOwnProperty('data')) { + for (var indx in resp.data) { + var input = $("").attr("type", "hidden"); + input.attr("name", resp.data[indx][0]); + input.attr("value", resp.data[indx][1]); + $('.comment-form-aios-antibot-keys').append(input); + } + } + }, + error: function(xhr, text_status, error_thrown) { + console.log("ERROR: " + text_status + " : " + error_thrown); + } + }); + } + } +}); \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-fr_FR.mo b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-fr_FR.mo new file mode 100755 index 0000000000000000000000000000000000000000..643e276ef582ab4797bae74e0d6b42765c05d9f1 GIT binary patch literal 119574 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 Ss^J~?28CAZ*)x@d`~L;xoRt#* literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-fr_FR.po b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-fr_FR.po new file mode 100755 index 00000000..3e5f3b15 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-fr_FR.po @@ -0,0 +1,5991 @@ +msgid "" +msgstr "" +"Project-Id-Version: AIOWPS\n" +"POT-Creation-Date: 2016-04-12 12:12+0200\n" +"PO-Revision-Date: 2016-04-18 17:41+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: fr_FR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Poedit 1.8.7\n" +"X-Poedit-Basepath: .\n" +"X-Poedit-KeywordsList: __;_e\n" +"X-Poedit-SearchPath-0: .\n" + +#. Plugin Name of the plugin +msgid "All In One WP Security" +msgstr "" + +#. Plugin URI of the plugin +msgid "https://wordpress.org/plugins/all-in-one-wp-security-and-firewall/" +msgstr "" + +#. Description of the plugin +msgid "All round best WordPress security plugin!" +msgstr "" + +#. Author of the plugin +msgid "All In One WP Security & Firewall Team" +msgstr "" + +#. Author URI of the plugin +msgid "https://teamupdraft.com/" +msgstr "" + +#: admin/general/wp-security-list-table.php:483 +msgid "Are you sure you want to perform this bulk action?" +msgstr "" + +#: admin/wp-security-admin-init.php:259 +msgid "Unexpected response:" +msgstr "" + +#: admin/wp-security-admin-init.php:290 +msgid "Enjoyed %1$s? Please leave us a %2$s rating. We really appreciate your support!" +msgstr "" + +#: admin/wp-security-admin-init.php:414 +#: classes/wp-security-two-factor-login.php:95 +msgid "WP Security" +msgstr "WP sécurité" + +#: admin/wp-security-admin-init.php:415 +#: admin/wp-security-dashboard-menu.php:26 +#: admin/wp-security-dashboard-menu.php:76 +msgid "Dashboard" +msgstr "Tableau de bord" + +#: admin/wp-security-admin-init.php:416 +#: admin/wp-security-settings-menu.php:95 +msgid "Settings" +msgstr "Paramètres" + +#: admin/wp-security-admin-init.php:417 +msgid "User Accounts" +msgstr "Comptes utilisateur" + +#: admin/wp-security-admin-init.php:418 +msgid "User Login" +msgstr "Connexion" + +#: admin/wp-security-admin-init.php:419 +msgid "User Registration" +msgstr "Enregistrement de l’utilisateur" + +#: admin/wp-security-admin-init.php:420 +msgid "Database Security" +msgstr "Sécurité BdD" + +#: admin/wp-security-admin-init.php:424 +msgid "Filesystem Security" +msgstr "Sécurité des fichiers" + +#: admin/wp-security-admin-init.php:429 +msgid "Blacklist Manager" +msgstr "Gestionnaire de liste noire" + +#: admin/wp-security-admin-init.php:434 +#: admin/wp-security-firewall-menu.php:60 +msgid "Firewall" +msgstr "Pare-feu" + +#: admin/wp-security-admin-init.php:436 +msgid "Brute Force" +msgstr "Brute Force" + +#: admin/wp-security-admin-init.php:437 +msgid "Spam Prevention" +msgstr "Prévention du SPAM" + +#: admin/wp-security-admin-init.php:441 +#: admin/wp-security-filescan-menu.php:53 +msgid "Scanner" +msgstr "Scanner" + +#: admin/wp-security-admin-init.php:443 +#: admin/wp-security-maintenance-menu.php:51 +msgid "Maintenance" +msgstr "Maintenance" + +#: admin/wp-security-admin-init.php:444 +#: admin/wp-security-misc-options-menu.php:57 +msgid "Miscellaneous" +msgstr "Divers" + +#: admin/wp-security-admin-init.php:445 +#: admin/wp-security-tools-menu.php:64 +msgid "Tools" +msgstr "" + +#: admin/wp-security-admin-init.php:457 +msgid "Premium Upgrade" +msgstr "" + +#: admin/wp-security-admin-menu.php:67 +msgid "Settings successfully updated." +msgstr "Paramètres correctement mis à jour" + +#: admin/wp-security-admin-menu.php:77 +msgid "Successfully deleted the selected record(s)." +msgstr "" + +#: admin/wp-security-admin-menu.php:86 +msgid "Failed to delete the selected record(s)." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:25 +msgid "Ban users" +msgstr "Utilisateurs bannis" + +#: admin/wp-security-blacklist-menu.php:51 +msgid "Blacklist manager" +msgstr "Gestionnaire de liste noire" + +#: admin/wp-security-blacklist-menu.php:132 +#: admin/wp-security-firewall-menu.php:1233 +#: admin/wp-security-list-404.php:234 +#: admin/wp-security-list-comment-spammer-ip.php:205 +msgid "The plugin was unable to write to the .htaccess file. Please edit file manually." +msgstr "L’extension a été incapable d’écrire dans le fichier .htaccess. Veuillez éditer manuellement ce fichier." + +#: admin/wp-security-blacklist-menu.php:139 +msgid "Ban IPs or user agents" +msgstr "Adresses IP ou ID d’utilisateur banni(e)s" + +#: admin/wp-security-blacklist-menu.php:142 +msgid "The All In One WP Security Blacklist feature gives you the option of banning certain host IP addresses or ranges and also user agents." +msgstr "La fonctionnalité liste noire d’All In One WP Security vous donne la possibilité de bannir certaines plages d’adresses IP, d’hôte ou ID d’utilisateurs." + +#: admin/wp-security-blacklist-menu.php:143 +msgid "This feature will deny total site access for users which have IP addresses or user agents matching those which you have configured in the settings below." +msgstr "Cette fonctionnalité refuse l’accès au site pour les utilisateurs qui ont des adresses IP ou ID utilisateurs correspondant à celles que vous avez configuré ci-dessous." + +#: admin/wp-security-blacklist-menu.php:144 +msgid "The plugin achieves this by making appropriate modifications to your .htaccess file." +msgstr "L’extension atteint cet objectif en apportant les modifications appropriées à votre fichier .htaccess." + +#: admin/wp-security-blacklist-menu.php:145 +msgid "By blocking people, you are using the most secure first line of defence, which denies all access to blacklisted visitors as soon as they hit your hosting server." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:154 +#: admin/wp-security-firewall-menu.php:1055 +#: templates/may-also-like.php:20 +msgid "All In One WP Security & Firewall Premium" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:155 +#: admin/wp-security-firewall-menu.php:1056 +msgid "You may also be interested in %s." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "This plugin adds a number of extra features including %s and %s." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "smart 404 blocking" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "country IP blocking" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:170 +msgid "IP hosts and user agent blacklist settings" +msgstr "Paramètres de liste noire d’IP hôtes et/ou d’ID utilisateurs" + +#: admin/wp-security-blacklist-menu.php:182 +#: admin/wp-security-brute-force-menu.php:193 +#: admin/wp-security-brute-force-menu.php:331 +msgid "must read this message" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:183 +#: admin/wp-security-brute-force-menu.php:194 +msgid "This feature can lock you out of admin if it doesn't work correctly on your site. You %s before activating this feature." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:189 +msgid "Enable IP or user agent blacklisting" +msgstr "Activer la liste noire d’IP ou d’ID utilisateur" + +#: admin/wp-security-blacklist-menu.php:192 +msgid "Check this if you want to enable the banning (or blacklisting) of selected IP addresses and/or user agents specified in the settings below" +msgstr "Cochez si vous souhaitez activer l’interdiction des adresses IP sélectionnées et/ou ID d’utilisateurs spécifiés dans les paramètres ci-dessous" + +#: admin/wp-security-blacklist-menu.php:196 +msgid "Enter IP addresses:" +msgstr "Entrez les adresses IP :" + +#: admin/wp-security-blacklist-menu.php:200 +msgid "Enter one or more IP addresses or IP ranges." +msgstr "Entrez une ou plusieurs adresse(s) IP (ou plage d’adresses)." + +#: admin/wp-security-blacklist-menu.php:205 +msgid "Enter user agents:" +msgstr "Entrez les agents utilisateurs:" + +#: admin/wp-security-blacklist-menu.php:210 +msgid "Enter one or more user agent strings." +msgstr "Saisissez un ou plusieurs chaînes de l’agent utilisateur." + +#: admin/wp-security-blacklist-menu.php:211 +#: admin/wp-security-brute-force-menu.php:374 +#: admin/wp-security-brute-force-menu.php:408 +#: admin/wp-security-brute-force-menu.php:431 +#: admin/wp-security-brute-force-menu.php:452 +#: admin/wp-security-filescan-menu.php:309 +#: admin/wp-security-filescan-menu.php:326 +#: admin/wp-security-firewall-menu.php:175 +#: admin/wp-security-firewall-menu.php:212 +#: admin/wp-security-firewall-menu.php:232 +#: admin/wp-security-firewall-menu.php:258 +#: admin/wp-security-firewall-menu.php:385 +#: admin/wp-security-firewall-menu.php:415 +#: admin/wp-security-firewall-menu.php:446 +#: admin/wp-security-firewall-menu.php:474 +#: admin/wp-security-firewall-menu.php:503 +#: admin/wp-security-firewall-menu.php:681 +#: admin/wp-security-firewall-menu.php:699 +#: admin/wp-security-firewall-menu.php:737 +#: admin/wp-security-firewall-menu.php:868 +#: admin/wp-security-firewall-menu.php:1087 +#: admin/wp-security-firewall-menu.php:1110 +#: admin/wp-security-spam-menu.php:186 +#: admin/wp-security-spam-menu.php:221 +#: admin/wp-security-spam-menu.php:390 +#: admin/wp-security-spam-menu.php:430 +#: admin/wp-security-user-login-menu.php:362 +#: templates/info/ip-address-ip-range-info.php:2 +#: templates/menus/settings/advanced-settings.php:63 +msgid "More info" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:214 +msgid "Each user agent string must be on a new line." +msgstr "Chaque chaîne d’ID utilisateur doit figurer sur une nouvelle ligne." + +#: admin/wp-security-blacklist-menu.php:215 +msgid "Example 1 - A single user agent string to block:" +msgstr "Exemple 1 - Un seul agent utilisateur à bloquer :" + +#: admin/wp-security-blacklist-menu.php:217 +msgid "Example 2 - A list of more than 1 user agent strings to block" +msgstr "Exemple 2 - Une liste de plusieurs agents utilisateurs à bloquer :" + +#: admin/wp-security-blacklist-menu.php:225 +#: admin/wp-security-brute-force-menu.php:213 +#: admin/wp-security-brute-force-menu.php:686 +#: admin/wp-security-brute-force-menu.php:806 +#: admin/wp-security-brute-force-menu.php:868 +#: admin/wp-security-filescan-menu.php:351 +#: admin/wp-security-filesystem-menu.php:242 +#: admin/wp-security-firewall-menu.php:945 +#: admin/wp-security-firewall-menu.php:1129 +#: admin/wp-security-misc-options-menu.php:167 +#: admin/wp-security-misc-options-menu.php:218 +#: admin/wp-security-misc-options-menu.php:278 +#: admin/wp-security-settings-menu.php:619 +#: admin/wp-security-settings-menu.php:680 +#: admin/wp-security-spam-menu.php:233 +#: admin/wp-security-spam-menu.php:407 +#: admin/wp-security-spam-menu.php:526 +#: admin/wp-security-spam-menu.php:588 +#: admin/wp-security-user-login-menu.php:384 +#: admin/wp-security-user-login-menu.php:422 +#: admin/wp-security-user-login-menu.php:601 +#: admin/wp-security-user-login-menu.php:788 +#: admin/wp-security-user-registration-menu.php:150 +#: admin/wp-security-user-registration-menu.php:242 +#: admin/wp-security-user-registration-menu.php:305 +#: templates/menus/settings/advanced-settings.php:217 +msgid "Save settings" +msgstr "Enregistrer les modifications" + +#: admin/wp-security-brute-force-menu.php:33 +#: admin/wp-security-brute-force-menu.php:759 +#: admin/wp-security-dashboard-menu.php:651 +msgid "Rename login page" +msgstr "Renommer la page de connexion" + +#: admin/wp-security-brute-force-menu.php:34 +#: admin/wp-security-brute-force-menu.php:154 +msgid "Cookie based brute force prevention" +msgstr "Protection contre « Brute Force basée cookie »" + +#: admin/wp-security-brute-force-menu.php:35 +#: classes/grade-system/wp-security-feature-item-manager.php:105 +msgid "Login CAPTCHA" +msgstr "Captcha de Connexion" + +#: admin/wp-security-brute-force-menu.php:36 +#: admin/wp-security-brute-force-menu.php:746 +msgid "Login whitelist" +msgstr "Liste blanche de connexion" + +#: admin/wp-security-brute-force-menu.php:37 +msgid "Honeypot" +msgstr "Utiliser Honeypot." + +#: admin/wp-security-brute-force-menu.php:67 +msgid "Brute force" +msgstr "Brute Force" + +#: admin/wp-security-brute-force-menu.php:105 +msgid "Please enter a value for your login page slug." +msgstr "Veuillez entrer un alias pour votre page de connexion sécurisée." + +#: admin/wp-security-brute-force-menu.php:109 +msgid "You cannot use the value \"wp-admin\" for your login page slug." +msgstr "Vous ne pouvez utiliser la valeur « wp-admin » pour l’alias de votre page de connexion sécurisée." + +#: admin/wp-security-brute-force-menu.php:111 +msgid "You must use alpha numeric characters for your login page slug." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:116 +#: admin/wp-security-filescan-menu.php:174 +#: admin/wp-security-firewall-menu.php:151 +#: admin/wp-security-firewall-menu.php:1011 +#: admin/wp-security-spam-menu.php:101 +#: admin/wp-security-spam-menu.php:270 +#: admin/wp-security-spam-menu.php:302 +#: admin/wp-security-user-login-menu.php:184 +#: admin/wp-security-user-login-menu.php:553 +#: templates/partials/non-apache-feature-notice.php:9 +msgid "Attention:" +msgstr "A l’attention de :" + +#: admin/wp-security-brute-force-menu.php:133 +msgid "Could not delete the Cookie-based directives from the .htaccess file. Please check the file permissions." +msgstr "Impossible de supprimer les directives basées-cookie à partir du fichier .htaccess. Veuillez vérifier les permissions des fichiers." + +#: admin/wp-security-brute-force-menu.php:155 +msgid "Login page white list" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:156 +msgid "An effective Brute Force prevention technique is to change the default WordPress login page URL." +msgstr "Une technique efficace de prévention contre Brute Force consiste à changer l’URL par défaut de la page de connexion à WordPress." + +#: admin/wp-security-brute-force-menu.php:157 +msgid "Normally if you wanted to login to WordPress you would type your site's home URL followed by wp-login.php." +msgstr "Normalement, si vous voulez vous connecter à WordPress, vous tapez l’URL de votre site attendue par wp-login.php." + +#: admin/wp-security-brute-force-menu.php:158 +msgid "This feature allows you to change the login URL by setting your own slug and renaming the last portion of the login URL which contains the wp-login.php to any string that you like." +msgstr "Cette fonction permet de modifier l'URL de connexion en définissant votre propre alias et ajoutant l'URL de connexion à wp-login.php." + +#: admin/wp-security-brute-force-menu.php:159 +msgid "By doing this, malicious bots and hackers will not be able to access your login page because they will not know the correct login page URL." +msgstr "En procédant ainsi, les robots et pirates ne pourront accéder à votre page de connexion, car ils ne connaîtront pas la bonne URL." + +#: admin/wp-security-brute-force-menu.php:161 +msgid "You may also be interested in the following alternative brute force prevention features:" +msgstr "Ces fonctionnalités alternatives de prévention de Brute Force peuvent également vous intéresser :" + +#: admin/wp-security-brute-force-menu.php:172 +msgid "Your WordPress login page URL has been renamed." +msgstr "Votre URL de connexion WordPress a été renommée." + +#: admin/wp-security-brute-force-menu.php:173 +msgid "Your current login URL is:" +msgstr "Votre nouvelle URL de connexion est :" + +#: admin/wp-security-brute-force-menu.php:181 +msgid "Rename login page settings" +msgstr "Renommer la page de connexion" + +#: admin/wp-security-brute-force-menu.php:195 +msgid "NOTE: If you are hosting your site on WPEngine or a provider which performs server caching, you will need to ask the host support people to NOT cache your renamed login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:200 +msgid "Enable rename login page feature" +msgstr "Autorisez le renommage de la page des réglages de Connexion" + +#: admin/wp-security-brute-force-menu.php:203 +msgid "Check this if you want to enable the rename login page feature" +msgstr "Cocher si vous souhaitez activer la fonction de renommage de la page de connexion" + +#: admin/wp-security-brute-force-menu.php:207 +msgid "Login page URL" +msgstr "URL de page de connexion" + +#: admin/wp-security-brute-force-menu.php:209 +msgid "Enter a string which will represent your secure login page slug. You are encouraged to choose something which is hard to guess and only you will remember." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:243 +msgid "Settings have not been saved - your secret word must consist only of alphanumeric characters, ie, letters and/or numbers only." +msgstr "Paramètres non enregistrés : votre mot secret ne doit comporter que des caractères alphanumériques, à savoir seulement lettres et chiffres !" + +#: admin/wp-security-brute-force-menu.php:257 +msgid "You have successfully enabled the cookie based brute force prevention feature" +msgstr "Vous avez correctement activé la fonctionnalité de prévention de Brute Force basée cookie" + +#: admin/wp-security-brute-force-menu.php:258 +msgid "From now on you will need to log into your WP Admin using the following URL:" +msgstr "À partir de maintenant, vous aurez besoin de l’URL suivante pour vous connecter à votre Admin WP :" + +#: admin/wp-security-brute-force-menu.php:260 +msgid "It is important that you save this URL value somewhere in case you forget it, OR," +msgstr "Il est important d’enregistrer cette URL quelque part pour le cas où vous l’oublieriez, OU" + +#: admin/wp-security-brute-force-menu.php:261 +msgid "simply remember to add a \"?%s=1\" to your current site URL address." +msgstr "rappelez-vous simplement d’ajouter « ?%s=1 » à l’adresse URL de votre site actuel." + +#: admin/wp-security-brute-force-menu.php:265 +msgid "You have successfully saved cookie based brute force prevention feature settings." +msgstr "Vous avez correctement enregistré les paramètres de prévention de Brute Force basée cookie." + +#: admin/wp-security-brute-force-menu.php:295 +msgid "Brute force prevention firewall settings" +msgstr "Paramètres du pare-feu contre la Brute Force" + +#: admin/wp-security-brute-force-menu.php:300 +msgid "A Brute Force Attack is when a hacker tries many combinations of usernames and passwords until they succeed in guessing the right combination." +msgstr "Une attaque Brute Force se caractérise par des essais répétés de nombreuses combinaisons d’ID utilisateurs / mots de passe, jusqu’à parvenir à trouver la bonne." + +#: admin/wp-security-brute-force-menu.php:301 +msgid "Due to the fact that at any one time there may be many concurrent login attempts occurring on your site via malicious automated robots, this also has a negative impact on your server's memory and performance." +msgstr "En raison du fait qu’à un moment donné, il peut y avoir de nombreuses tentatives de connexion à votre site par des robots malveillants, un énorme impact négatif sur la mémoire et les performances de votre serveur peut avoir lieu." + +#: admin/wp-security-brute-force-menu.php:302 +msgid "The features in this tab will stop the majority of brute force login attacks thus providing even better protection for your WP login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:307 +#: admin/wp-security-firewall-menu.php:654 +msgid "backup" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:308 +msgid "video tutorial" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:309 +msgid "To learn more about how to use this feature, please watch the following %s." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:310 +#: admin/wp-security-brute-force-menu.php:758 +msgid "Cookie-Based Brute Force Login Prevention" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:320 +#: admin/wp-security-user-login-menu.php:253 +msgid "Cookie based brute force login prevention" +msgstr "Protection contre « Brute Force basée cookie »" + +#: admin/wp-security-brute-force-menu.php:331 +msgid "This feature can lock you out of admin if it doesn't work correctly on your site. You
            " +msgstr "" + +#: admin/wp-security-brute-force-menu.php:342 +msgid "The cookie test was successful. You can now enable this feature." +msgstr "Le test de cookie a été couronnée de succès. Vous pouvez maintenant activer cette fonctionnalité." + +#: admin/wp-security-brute-force-menu.php:350 +msgid "The cookie test failed on this server. Consequently, this feature cannot be used on this site." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:357 +msgid "Before using this feature, you must perform a cookie test first." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:359 +msgid "This ensures that your browser cookie is working correctly and that you won't lock yourself out." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:364 +msgid "Perform cookie test" +msgstr "Effectuer le test du Cookie" + +#: admin/wp-security-brute-force-menu.php:370 +#: classes/grade-system/wp-security-feature-item-manager.php:103 +msgid "Enable brute force attack prevention" +msgstr "Activer la prévention d’attaque Brute Force" + +#: admin/wp-security-brute-force-menu.php:373 +msgid "Check this if you want to protect your login page from Brute Force Attack." +msgstr "Cocher si vous souhaitez protéger votre page de connexion d’une attaque par Brute Force." + +#: admin/wp-security-brute-force-menu.php:378 +msgid "This feature will deny access to your WordPress login page for all people except those who have a special cookie in their browser." +msgstr "Cette fonctionnalité refusera l’accès à votre page de connexion WordPress pour tous visiteurs sauf ceux ayant un cookie spécial dans leur navigateur." + +#: admin/wp-security-brute-force-menu.php:380 +msgid "To use this feature do the following:" +msgstr "Pour utiliser cette fonctionnalité procéder comme suit :" + +#: admin/wp-security-brute-force-menu.php:382 +msgid "1) Enable the checkbox." +msgstr "1) Cochez la case." + +#: admin/wp-security-brute-force-menu.php:384 +msgid "2) Enter a secret word consisting of alphanumeric characters which will be difficult to guess. This secret word will be useful whenever you need to know the special URL which you will use to access the login page (see point below)." +msgstr "2) Entrez un mot secret composé de caractères alphanumériques qui seront difficiles à deviner. Ce mot secret sera utile lorsque vous aurez besoin de vous remémorer l’URL spéciale que vous utiliserez pour accéder à la page de connexion (voir point ci-dessous)." + +#: admin/wp-security-brute-force-menu.php:386 +msgid "3) You will then be provided with a special login URL. You will need to use this URL to login to your WordPress site instead of the usual login URL. NOTE: The system will deposit a special cookie in your browser which will allow you access to the WordPress administration login page." +msgstr "3) vous recevrez ensuite une URL de connexion spéciale. Vous devrez utiliser cette URL pour vous connecter à votre site WordPress en lieu et place de l’URL de connexion standard. Remarque : Le système déposera un cookie spécial dans votre navigateur qui vous permettra d’accédez à la page de connexion d’administration WordPress (veillez à ce qu’il ne soit pas détruit)." + +#: admin/wp-security-brute-force-menu.php:388 +msgid "Any person trying to access your login page who does not have the special cookie in their browser will be automatically blocked." +msgstr "Tout visiteur essayant d’accéder à votre page de connexion sans avoir le cookie spécial dans son navigateur sera automatiquement bloqué(e)." + +#: admin/wp-security-brute-force-menu.php:395 +msgid "Secret word" +msgstr "Clé secrète" + +#: admin/wp-security-brute-force-menu.php:397 +msgid "Choose a secret word consisting of alphanumeric characters which you can use to access your special URL. Your are highly encouraged to choose a word which will be difficult to guess." +msgstr "Choisissez un mot secret composé de caractères alphanumériques qui vous permettra d’accéder à votre URL spéciale. Vous êtes fortement encouragés à choisir un mot difficile à deviner mais qu’il vous faudra retenir !" + +#: admin/wp-security-brute-force-menu.php:401 +msgid "Re-direct URL" +msgstr "URL de redirection" + +#: admin/wp-security-brute-force-menu.php:405 +msgid "Specify a URL to redirect a hacker to when they try to access your WordPress login page." +msgstr "Spécifiez l'URL où rediriger les pirates quand ils essaient d'accéder à votre page de connexion de WordPress." + +#: admin/wp-security-brute-force-menu.php:412 +msgid "The URL specified here can be any site's URL and does not have to be your own. For example you can be as creative as you like and send hackers to the CIA or NSA home page." +msgstr "L’URL spécifiée ici peut être celle de n’importe quel site et naturellement, pas le vôtre. Vous pouvez faire preuve de créativité et envoyez les pirates à la page d’accueil de la CIA ou de la NSA par exemple." + +#: admin/wp-security-brute-force-menu.php:414 +msgid "This field will default to: http://127.0.0.1 if you do not enter a value." +msgstr "Champ par défaut : http://127.0.0.1 si vous n’entrez aucune valeur." + +#: admin/wp-security-brute-force-menu.php:416 +msgid "Useful Tip:" +msgstr "Petite astuce utile :" + +#: admin/wp-security-brute-force-menu.php:418 +msgid "It's a good idea to not redirect attempted brute force login attempts to your site because it increases the load on your server." +msgstr "C’est une bonne idée que de ne pas rediriger les tentatives de connexion Brute Force sur votre propre site car elles augmenteraient la charge de votre serveur." + +#: admin/wp-security-brute-force-menu.php:420 +msgid "Redirecting a hacker or malicious bot back to \"http://127.0.0.1\" is ideal because it deflects them back to their own local host and puts the load on their server instead of yours." +msgstr "Rediriger pirates ou bots malicieux vers « http://127.0.0.1 » est idéal car elle les renvoie à leur propre hôte et met la charge sur leur serveur au lieu du vôtre." + +#: admin/wp-security-brute-force-menu.php:427 +msgid "My site has posts or pages which are password protected" +msgstr "Mon site a des articles ou des pages protégés par mot-clé anti Brute Force" + +#: admin/wp-security-brute-force-menu.php:430 +msgid "Check this if you are using the native WordPress password protection feature for some or all of your blog posts or pages." +msgstr "Cocher si vous utilisez la fonctionnalité native WordPress de protection par mot de passe pour tout ou partie de votre blog ou site." + +#: admin/wp-security-brute-force-menu.php:435 +msgid "In the cases where you are protecting some of your posts or pages using the in-built WordPress password protection feature, a few extra lines of directives and exceptions need to be added so that people trying to access pages are not automatically blocked." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:437 +msgid "By enabling this checkbox, the plugin will add the necessary rules and exceptions so that people trying to access these pages are not automatically blocked." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:439 +msgid "Helpful Tip:" +msgstr "Conseil utile :" + +#: admin/wp-security-brute-force-menu.php:441 +msgid "If you do not use the WordPress password protection feature for your posts or pages then it is highly recommended that you leave this checkbox disabled." +msgstr "Si vous n'utilisez pas la fonctionnalité de protection par mot de passe WordPress pour vos articles ou pages, il est hautement recommandé de laissez cette case désactivée." + +#: admin/wp-security-brute-force-menu.php:448 +msgid "My site has a theme or plugins which use AJAX" +msgstr "Mon Site a un thème ou des extensions utilisant AJAX" + +#: admin/wp-security-brute-force-menu.php:451 +msgid "Check this if your site uses AJAX functionality." +msgstr "Cocher si votre site utilise des fonctionnalités AJAX." + +#: admin/wp-security-brute-force-menu.php:456 +msgid "In the cases where your WordPress installation has a theme or plugin that uses AJAX, a few extra lines of directives and exceptions need to be added to prevent AJAX requests from being automatically blocked by the brute force prevention feature." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:458 +msgid "By enabling this checkbox, the plugin will add the necessary rules and exceptions so that AJAX operations will work as expected." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:467 +msgid "Save feature settings" +msgstr "Enregistrer les paramètres de fonction" + +#: admin/wp-security-brute-force-menu.php:525 +msgid "This feature allows you to add a CAPTCHA form on various WordPress login pages and forms." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:526 +msgid "Adding a CAPTCHA form on a login page or form is another effective yet simple \"Brute Force\" prevention technique." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:527 +msgid "You have the option of using either %s or a plain maths CAPTCHA form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:528 +msgid "If you enable Google reCAPTCHA the reCAPTCHA widget will be displayed for all forms the CAPTCHA settings below." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:529 +msgid "If Google reCAPTCHA is disabled the simple maths CAPTCHA form will apply and users will need to enter the answer to a simple mathematical question." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:535 +msgid "Google reCAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:540 +msgid "By enabling these settings the Google reCAPTCHA v2 widget will be applied by default for all forms with CAPTCHA enabled." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:549 +msgid "reCAPTCHA will not work because you have disabled login lockout by activating the AIOS_DISABLE_LOGIN_LOCKOUT constant value in a configuration file." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:550 +msgid "To enable it, define AIOS_DISABLE_LOGIN_LOCKOUT constant value as false, or remove it." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:558 +msgid "Use Google reCAPTCHA as default" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:561 +msgid "Check this if you want to default to Google reCAPTCHA for all settings below. (If this is left unchecked, all CAPTCHA forms will revert to the plain maths CAPTCHA)" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:565 +msgid "Site key" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:571 +msgid "Secret key" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:580 +msgid "Login form CAPTCHA settings" +msgstr "Réglage du Captcha du formulaire de connexion" + +#: admin/wp-security-brute-force-menu.php:589 +msgid "Enable CAPTCHA on login page" +msgstr "Activer le Captcha sur la page de Connexion" + +#: admin/wp-security-brute-force-menu.php:592 +msgid "Check this if you want to insert a CAPTCHA form on the login page." +msgstr "Cochez si vous souhaitez insérer un formulaire Captcha sur la page de connexion" + +#: admin/wp-security-brute-force-menu.php:598 +msgid "Lost password form CAPTCHA settings" +msgstr "Mot de passe des paramètres de formulaire Captcha perdu" + +#: admin/wp-security-brute-force-menu.php:608 +msgid "Enable CAPTCHA on lost password page" +msgstr "Activer le Captcha sur la page Mot de passe perdu" + +#: admin/wp-security-brute-force-menu.php:611 +msgid "Check this if you want to insert a CAPTCHA form on the lost password page." +msgstr "Cochez si vous souhaitez insérer un formulaire Captcha sur la page de mot de passe perdu" + +#: admin/wp-security-brute-force-menu.php:617 +msgid "Custom login form CAPTCHA settings" +msgstr "Personnalisation des réglages du Captcha de formulaire de connexion" + +#: admin/wp-security-brute-force-menu.php:626 +msgid "Enable CAPTCHA on custom login form" +msgstr "Activer le Captcha sur le formulaire de connexion" + +#: admin/wp-security-brute-force-menu.php:629 +msgid "Check this if you want to insert CAPTCHA on a custom login form generated by the following WP function: wp_login_form()" +msgstr "Cochez si vous souhaitez insérer un Captcha dans le formulaire de connexion personnalisé généré par la fonction WP : wp_login_form()" + +#: admin/wp-security-brute-force-menu.php:639 +msgid "WooCommerce forms CAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:648 +msgid "Enable CAPTCHA on WooCommerce login form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:651 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce login form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:661 +msgid "Enable CAPTCHA on WooCommerce lost password form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:664 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce lost password form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:674 +msgid "Enable CAPTCHA on WooCommerce registration form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:677 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce registration form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:749 +msgid "The All In One WP Security Whitelist feature gives you the option of only allowing certain IP addresses or ranges to have access to your WordPress login page." +msgstr "La fonctionnalité liste blanche d’All In One WP Security vous donne la possibilité de n’autoriser que certaines adresses IP (ou plages) à avoir accès à votre page de connexion WordPress." + +#: admin/wp-security-brute-force-menu.php:750 +msgid "This feature will deny login access for all IP addresses which are not in your whitelist as configured in the settings below." +msgstr "Cette fonctionnalité refusera l’accès à toutes les adresses IP qui ne font pas partie de votre liste blanche configurée dans les paramètres ci-dessous." + +#: admin/wp-security-brute-force-menu.php:751 +msgid "The plugin achieves this by writing the appropriate directives to your .htaccess file." +msgstr "L’extension réalise cela en écrivant les directives appropriées dans votre fichier .htaccess." + +#: admin/wp-security-brute-force-menu.php:752 +msgid "By allowing/blocking IP addresses, you are using the most secure first line of defence because login access will only be granted to whitelisted IP addresses and other addresses will be blocked as soon as they try to access your login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:760 +msgid "Attention: If in addition to enabling the white list feature, you also have one of the %s or %s features enabled, you will still need to use your secret word or special slug in the URL when trying to access your WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:761 +msgid "These features are NOT functionally related. Having both of them enabled on your site means you are creating 2 layers of security." +msgstr "Ces fonctionnalités ne sont pas liées opérationnellement. Si les deux sont activées sur votre site, cela signifie que vous créez 2 couches de sécurité." + +#: admin/wp-security-brute-force-menu.php:772 +msgid "Login IP whitelist settings" +msgstr "Paramétrage de liste blanche des IP de connexion" + +#: admin/wp-security-brute-force-menu.php:783 +msgid "Enable IP whitelisting" +msgstr "Activer la liste blanche d’IP" + +#: admin/wp-security-brute-force-menu.php:786 +#: admin/wp-security-user-login-menu.php:408 +msgid "Check this if you want to enable the whitelisting of selected IP addresses specified in the settings below" +msgstr "Cochez si vous souhaitez activer la liste blanche pour certaines adresses IP spécifiées dans les paramètres ci-dessous" + +#: admin/wp-security-brute-force-menu.php:790 +msgid "Your current IP address" +msgstr "Votre adresse IP actuelle" + +#: admin/wp-security-brute-force-menu.php:793 +msgid "You can copy and paste this address in the text box below if you want to include it in your login whitelist." +msgstr "Vous pouvez copier / coller cette adresse dans la zone de texte ci-dessous pour l’inclure en liste blanche de connexion." + +#: admin/wp-security-brute-force-menu.php:797 +#: admin/wp-security-user-login-menu.php:412 +msgid "Enter whitelisted IP addresses:" +msgstr "Entrez les adresses IP en liste blanche :" + +#: admin/wp-security-brute-force-menu.php:801 +#: admin/wp-security-user-login-menu.php:416 +msgid "Enter one or more IP addresses or IP ranges you wish to include in your whitelist." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:801 +msgid "Only the addresses specified here will have access to the WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:839 +msgid "This feature allows you to add a special hidden \"honeypot\" field on the WordPress login page. This will only be visible to robots and not humans." +msgstr "Cette fonctionnalité permet d’ajouter un champ caché spécial « Honeypot » sur la page de connexion WordPress. Il ne sera visible que des robots, et pas des humains." + +#: admin/wp-security-brute-force-menu.php:840 +msgid "Since robots usually fill in every input field from a login form, they will also submit a value for the special hidden honeypot field." +msgstr "Les robots remplissant généralement chaque champ de saisie d’un formulaire de connexion, ils présenteront également une valeur pour le champ spécial Honeypot caché." + +#: admin/wp-security-brute-force-menu.php:841 +#: admin/wp-security-user-registration-menu.php:278 +msgid "The way honeypots work is that a hidden field is placed somewhere inside a form which only robots will submit. If that field contains a value when the form is submitted then a robot has most likely submitted the form and it is consequently dealt with." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:842 +msgid "Therefore, if the plugin detects that this field has a value when the login form is submitted, then the robot which is attempting to login to your site will be redirected to its localhost address - http://127.0.0.1." +msgstr "Par conséquent, si l’extension détecte que ce champ a été rempli sur le formulaire envoyé, et que le robot tente de se connecter à votre site il sera redirigé vers l’adresse localhost - http://127.0.0.1." + +#: admin/wp-security-brute-force-menu.php:848 +msgid "Login form honeypot settings" +msgstr "Réglages du formulaire de connexion Honeypot" + +#: admin/wp-security-brute-force-menu.php:859 +msgid "Enable honeypot on login page" +msgstr "Activer Honeypot sur la page de connexion" + +#: admin/wp-security-brute-force-menu.php:862 +msgid "Check this if you want to enable the honeypot feature for the login page" +msgstr "Cochez cette case si vous souhaitez activer la fonctionnalité Honeypot sur la page de connexion" + +#: admin/wp-security-dashboard-menu.php:27 +#: admin/wp-security-dashboard-menu.php:374 +#: classes/wp-security-user-login.php:74 +msgid "Locked IP addresses" +msgstr "Adresses IP Verrouillées" + +#: admin/wp-security-dashboard-menu.php:28 +msgid "Permanent block list" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:29 +msgid "Logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:33 +msgid "Premium upgrade" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:131 +#: admin/wp-security-dashboard-menu.php:518 +#: admin/wp-security-user-login-menu.php:53 +#: classes/grade-system/wp-security-feature-item-manager.php:49 +msgid "Login lockout" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:132 +msgid "This tab displays the list of all IP addresses which are currently temporarily locked out due to the login lockout feature:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:138 +msgid "Currently locked out IP addresses and ranges" +msgstr "Plages et adresses IP actuellement en lock-out" + +#: admin/wp-security-dashboard-menu.php:183 +msgid "This tab displays the list of all permanently blocked IP addresses." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:184 +#: admin/wp-security-spam-menu.php:339 +msgid "NOTE: This feature does NOT use the .htaccess file to permanently block the IP addresses so it should be compatible with all web servers running WordPress." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:189 +msgid "Permanently blocked IP addresses" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:200 +#: admin/wp-security-firewall-menu.php:1151 +#: admin/wp-security-user-login-menu.php:485 +#: admin/wp-security-user-login-menu.php:643 +#: admin/wp-security-user-registration-menu.php:164 +msgid "Search" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:238 +#: admin/wp-security-dashboard-menu.php:249 +#: admin/wp-security-dashboard-menu.php:260 +msgid "All In One WP Security & Firewall" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:250 +msgid "Debug logs have been cleared." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:261 +msgid "Unable to clear the logs; an invalid nonce was provided" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:274 +msgid "Debug log options" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:281 +msgid "Clear logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:289 +msgid "Debug logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:362 +msgid "Security strength meter" +msgstr "Mesure de l’efficacité du mot de passe." + +#: admin/wp-security-dashboard-menu.php:363 +msgid "Security points breakdown" +msgstr "Répartition des points de sécurité" + +#: admin/wp-security-dashboard-menu.php:364 +msgid "Spread the word" +msgstr "Passez le message" + +#: admin/wp-security-dashboard-menu.php:365 +msgid "Get to know the developers" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:366 +msgid "Critical feature status" +msgstr "État des caractéristiques critiques" + +#: admin/wp-security-dashboard-menu.php:367 +msgid "Last 5 logins" +msgstr "Les 5 dernières connexions" + +#: admin/wp-security-dashboard-menu.php:368 +msgid "Maintenance mode status" +msgstr "État du mode maintenance" + +#: admin/wp-security-dashboard-menu.php:373 +#: admin/wp-security-dashboard-menu.php:664 +#: admin/wp-security-user-login-menu.php:57 +msgid "Logged in users" +msgstr "Utilisateurs connectés" + +#: admin/wp-security-dashboard-menu.php:417 +msgid "Total Achievable Points: " +msgstr "Total de Points réalisables :" + +#: admin/wp-security-dashboard-menu.php:419 +msgid "Current Score of Your Site: " +msgstr "Score actuel de votre site:" + +#: admin/wp-security-dashboard-menu.php:472 +msgid "We are working hard to make your WordPress site more secure. Please support us, here is how:" +msgstr "Nous travaillons dur pour rendre votre site WordPress plus sûr. Merci de nous aider, vous le pouvez d’une (ou plusieurs) façon(s) suivante(s) :" + +#: admin/wp-security-dashboard-menu.php:473 +msgid "Follow us on" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:477 +msgid "Post to Twitter" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:481 +msgid "Give us a good rating" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:488 +msgid "Wanna know more about the developers behind this plugin?" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:499 +msgid "Below is the current status of the critical features that you should activate on your site to achieve a minimum level of recommended security" +msgstr "Ci-dessous, l’état actuel des fonctionnalités essentielles que vous devez activer sur votre site pour atteindre un niveau minimal de sécurité recommandé" + +#: admin/wp-security-dashboard-menu.php:503 +msgid "Admin username" +msgstr "Identifiant de l’administrateur" + +#: admin/wp-security-dashboard-menu.php:533 +msgid "File permission" +msgstr "Autorisation de fichier" + +#: admin/wp-security-dashboard-menu.php:548 +msgid "Basic firewall" +msgstr "Pare-feu de base" + +#: admin/wp-security-dashboard-menu.php:577 +msgid "No data found." +msgstr "Aucune donnée!" + +#: admin/wp-security-dashboard-menu.php:581 +msgid "Last 5 logins summary:" +msgstr "Sommaire des 5 dernières connexions :" + +#: admin/wp-security-dashboard-menu.php:585 +msgid "User" +msgstr "Utilisateur" + +#: admin/wp-security-dashboard-menu.php:586 +#: admin/wp-security-list-404.php:95 +#: admin/wp-security-list-login-fails.php:56 +#: admin/wp-security-list-permanent-blocked-ip.php:68 +msgid "Date" +msgstr "Date" + +#: admin/wp-security-dashboard-menu.php:587 +msgid "IP" +msgstr "IP" + +#: admin/wp-security-dashboard-menu.php:608 +msgid "Maintenance mode is currently enabled. Remember to turn it off when you are done" +msgstr "Mode maintenance actuellement activé. Rappelez-vous de l’enlever lorsque vous aurez terminé" + +#: admin/wp-security-dashboard-menu.php:610 +msgid "Maintenance mode is currently off." +msgstr "Mode maintenance actuellement désactivé." + +#: admin/wp-security-dashboard-menu.php:614 +msgid "Maintenance mode" +msgstr "Mode maintenance" + +#: admin/wp-security-dashboard-menu.php:632 +msgid "Cookie based brute force" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:636 +#: admin/wp-security-dashboard-menu.php:654 +msgid "The %s feature is currently active." +msgstr "La fonction %s est actuellement active." + +#: admin/wp-security-dashboard-menu.php:637 +#: admin/wp-security-dashboard-menu.php:655 +msgid "Your new WordPress login URL is now:" +msgstr "Votre nouvelle URL de connexion WordPress est maintenant :" + +#: admin/wp-security-dashboard-menu.php:666 +msgid "Number of users currently logged into your site (including you) is:" +msgstr "Nombre d’utilisateurs actuellement connectés à votre site (y compris vous-même ) :" + +#: admin/wp-security-dashboard-menu.php:667 +msgid "There are no other users currently logged in." +msgstr "Aucun autre utilisateur connecté." + +#: admin/wp-security-dashboard-menu.php:680 +msgid "Number of users currently logged in site-wide (including you) is:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:681 +msgid "There are no other site-wide users currently logged in." +msgstr "Il n’y a aucun autre utilisateur actuellement connecté sur l’ensemble du site." + +#: admin/wp-security-dashboard-menu.php:694 +#: admin/wp-security-dashboard-menu.php:711 +msgid "Go to the %s menu to see more details" +msgstr "Accéder au menu %s pour plus de détails" + +#: admin/wp-security-dashboard-menu.php:707 +msgid "There are no IP addresses currently locked out." +msgstr "Aucune adresse IP actuellement verrouillée." + +#: admin/wp-security-dashboard-menu.php:710 +msgid "Number of temporarily locked out IP addresses: " +msgstr "Nombre d’adresses IP verrouillées temporairement :" + +#: admin/wp-security-database-menu.php:52 +msgid "UpdraftPlus is installed but currently not active." +msgstr "" + +#: admin/wp-security-database-menu.php:52 +msgid "Follow this link to activate UpdraftPlus, to take a backup." +msgstr "" + +#: admin/wp-security-database-menu.php:57 +msgid "Follow this link to install UpdraftPlus, to take a database backup." +msgstr "" + +#: admin/wp-security-database-menu.php:87 +#: admin/wp-security-database-menu.php:92 +msgid "Database backup" +msgstr "sauvegarde de BdD" + +#: admin/wp-security-database-menu.php:91 +#: classes/grade-system/wp-security-feature-item-manager.php:65 +msgid "Database prefix" +msgstr "Préfixe de BdD" + +#: admin/wp-security-database-menu.php:119 +msgid "Database security" +msgstr "Sécurité BdD" + +#: admin/wp-security-database-menu.php:147 +msgid "Nonce check failed for DB prefix change operation!" +msgstr "Echec du contrôle lors du changement de préfixe BdD !" + +#: admin/wp-security-database-menu.php:155 +msgid "The plugin has detected that it cannot write to the wp-config.php file. This feature can only be used if the plugin can successfully write to the wp-config.php file." +msgstr "L’extension a détecté qu’elle ne peut écrire dans le fichier wp-config.php. Vérifiez les autorisations d’accès et recommencez l’opération." + +#: admin/wp-security-database-menu.php:168 +msgid "Please enter a value for the DB prefix." +msgstr "Veuillez saisir une valeur de préfixe pour la BdD." + +#: admin/wp-security-database-menu.php:177 +msgid "ERROR: The table prefix can only contain numbers, letters, and underscores." +msgstr "ERREUR : Le préfixe des tables ne peut contenir que des chiffres, des lettres et « _ »." + +#: admin/wp-security-database-menu.php:186 +#: admin/wp-security-database-menu.php:245 +msgid "Change database prefix" +msgstr "Changer le préfixe des tables de la BdD" + +#: admin/wp-security-database-menu.php:189 +msgid "Your WordPress database is the most important asset of your website because it contains a lot of your site's precious information." +msgstr "" + +#: admin/wp-security-database-menu.php:190 +msgid "The database is also a target for hackers via methods such as SQL injections and malicious and automated code which targets certain tables." +msgstr "" + +#: admin/wp-security-database-menu.php:191 +msgid "One way to add a layer of protection for your DB is to change the default WordPress table prefix from \"wp_\" to something else which will be difficult for hackers to guess." +msgstr "Une façon d’ajouter une couche de protection supplémentaire à votre BdD consiste à modifier le préfixe des tables WordPress (« wp_ » par défaut !) en quelque chose de plus difficile à découvrir par les pirates." + +#: admin/wp-security-database-menu.php:192 +msgid "This feature allows you to easily change the prefix to a value of your choice or to a random value set by this plugin." +msgstr "Cette fonctionnalité permet de changer facilement le préfixe actuel de la BdD en une valeur de votre choix ou à une valeur aléatoire définie par l’extension." + +#: admin/wp-security-database-menu.php:198 +msgid "Database prefix options" +msgstr "Options de préfixe BdD" + +#: admin/wp-security-database-menu.php:210 +msgid "database backup" +msgstr "sauvegarde de BdD" + +#: admin/wp-security-database-menu.php:211 +msgid "It is recommended that you perform a %s before using this feature" +msgstr "Il est recommandé d’effectuer une %s avant d’utiliser cette fonctionnalité" + +#: admin/wp-security-database-menu.php:221 +msgid "Current database table prefix" +msgstr "Préfixe actuel des tables de BdD" + +#: admin/wp-security-database-menu.php:227 +msgid "Your site is currently using the default WordPress database prefix value of \"wp_\"." +msgstr "" + +#: admin/wp-security-database-menu.php:227 +msgid "To increase your site's security you should consider changing the database prefix value to another value." +msgstr "" + +#: admin/wp-security-database-menu.php:234 +msgid "Generate new database table prefix" +msgstr "Générer un nouveau préfixe de tables BdD" + +#: admin/wp-security-database-menu.php:238 +msgid "Check this if you want the plugin to generate a random 6 character string for the table prefix" +msgstr "Cochez si vous souhaitez que l’extension génère une chaîne de 6 caractères aléatoires pour préfixer les tables" + +#: admin/wp-security-database-menu.php:239 +msgid "OR" +msgstr "OU" + +#: admin/wp-security-database-menu.php:241 +msgid "Choose your own database prefix by specifying a string which contains letters and/or numbers and/or underscores. Example: xyz_" +msgstr "" + +#: admin/wp-security-database-menu.php:265 +msgid "Take a database backup using UpdraftPlus" +msgstr "" + +#: admin/wp-security-database-menu.php:270 +msgid "Manual backup" +msgstr "Sauvegarde manuelle" + +#: admin/wp-security-database-menu.php:274 +msgid "UpdraftPlus Backup/Restore" +msgstr "" + +#: admin/wp-security-database-menu.php:274 +msgid "Your backups are on the UpdraftPlus Backup/Restore admin page." +msgstr "" + +#: admin/wp-security-database-menu.php:276 +msgid "Create database backup now" +msgstr "" + +#: admin/wp-security-database-menu.php:308 +msgid "Error - Could not get tables or no tables found!" +msgstr "Erreur : Impossible d’obtenir des tables (ou tables non trouvées) !" + +#: admin/wp-security-database-menu.php:312 +msgid "Starting DB prefix change operations....." +msgstr "Début du changement de préfixe BdD…" + +#: admin/wp-security-database-menu.php:314 +msgid "Your WordPress system has a total of %s tables and your new DB prefix will be: %s" +msgstr "Votre BdD WordPress contient un total de %s tables et leur nouveau préfixe sera : %s" + +#: admin/wp-security-database-menu.php:320 +#: classes/wp-security-utility.php:306 +msgid "Failed to make a backup of the wp-config.php file. This operation will not go ahead." +msgstr "Impossible de faire une sauvegarde du fichier wp-config.php. Cette opération n’ira pas plus loin." + +#: admin/wp-security-database-menu.php:324 +msgid "A backup copy of your wp-config.php file was created successfully!" +msgstr "Une copie de sauvegarde de votre fichier wp-config.php a été réalisée avec succès !" + +#: admin/wp-security-database-menu.php:351 +msgid "%s table name update failed" +msgstr "Le renommage de table en « %s » à échoué" + +#: admin/wp-security-database-menu.php:363 +msgid "Please change the prefix manually for the above tables to: %s" +msgstr "Veuillez changer manuellement le préfixe des tables ci-dessus en : %s" + +#: admin/wp-security-database-menu.php:366 +msgid "%s tables had their prefix updated successfully!" +msgstr "Renommage des tables en « %s » terminé avec succès !" + +#: admin/wp-security-database-menu.php:387 +msgid "wp-config.php file was updated successfully!" +msgstr "Le fichier wp-config.php a été mis à jour avec succès !" + +#: admin/wp-security-database-menu.php:390 +msgid "The \"wp-config.php\" file was not able to be modified." +msgstr "" + +#: admin/wp-security-database-menu.php:390 +msgid "Please modify this file manually using your favourite editor and search for variable \"$table_prefix\" and assign the following value to that variable: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:401 +#: admin/wp-security-database-menu.php:420 +msgid "Update of table %s failed: unable to change %s to %s" +msgstr "L’actualisation de la table %s a échoué : impossible de passer de %s à %s" + +#: admin/wp-security-database-menu.php:405 +msgid "The options table records which had references to the old DB prefix were updated successfully!" +msgstr "Les options de table qui faisaient référence à l’ancien préfixe BdD ont été actualisées avec succès !" + +#: admin/wp-security-database-menu.php:424 +msgid "The %s table records which had references to the old DB prefix were updated successfully!" +msgstr "Les enregistrements de la table %s qui faisaient référence à l’ancien préfixe BdD ont été actualisés avec succès !" + +#: admin/wp-security-database-menu.php:452 +msgid "Error updating user_meta table where new meta_key = %s, old meta_key = %s and user_id = %s." +msgstr "Erreur d’actualisation de la table avec nouvelle meta_key = %s, ancienne meta_key = %s et user_id = %s." + +#: admin/wp-security-database-menu.php:457 +msgid "The usermeta table records which had references to the old DB prefix were updated successfully!" +msgstr "Les enregistrement de la table de méta-utilisateur qui faisaient référence à l’ancien préfixe BdD ont été actualisés avec succès !" + +#: admin/wp-security-database-menu.php:459 +msgid "The database prefix change tasks have been completed." +msgstr "Les tâches de modification du préfixe BdD sont terminées." + +#: admin/wp-security-database-menu.php:503 +msgid "Checking for MySQL tables of type \"view\"....." +msgstr "" + +#: admin/wp-security-database-menu.php:520 +msgid "Update of the following MySQL view definition failed: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:527 +msgid "%s view definitions were updated successfully!" +msgstr "" + +#: admin/wp-security-filescan-menu.php:26 +#: classes/grade-system/wp-security-feature-item-manager.php:127 +msgid "File change detection" +msgstr "Détection de changement dans un fichier" + +#: admin/wp-security-filescan-menu.php:27 +msgid "Malware scan" +msgstr "Recherche de logiciel(s) malveillant(s)" + +#: admin/wp-security-filescan-menu.php:88 +msgid "There have been no file changes since the last scan." +msgstr "Aucune modification de fichier n’a été repérée depuis la dernière analyse." + +#: admin/wp-security-filescan-menu.php:98 +msgid "Nonce check failed for manual file change detection scan operation!" +msgstr "Échec de l’analyse de modification de fichier !" + +#: admin/wp-security-filescan-menu.php:104 +msgid "There was an error during the file change detection scan. Please check the AIOS logs." +msgstr "" + +#: admin/wp-security-filescan-menu.php:110 +msgid "The plugin has detected that this is your first file change detection scan. The file details from this scan will be used to detect file changes for future scans." +msgstr "L’extension a détecté que vous n’avez pas encore effectué d’analyse de changements dans les fichiers. Les détails de celle-ci seront utilisés pour détecter les modifications lors d’analyses ultérieures !" + +#: admin/wp-security-filescan-menu.php:112 +msgid "Scan complete - There were no file changes detected!" +msgstr "Analyse terminée - Il n’y a pas eu de modifications de fichiers détectées !" + +#: admin/wp-security-filescan-menu.php:133 +msgid "You entered a non numeric value for the \"backup time interval\" field. It has been set to the default value." +msgstr "Vous avez entré une valeur non numérique pour le champ « intervalle entre sauvegardes ». Elle sera fixée à la valeur par défaut." + +#: admin/wp-security-filescan-menu.php:167 +msgid "The following address was removed because it is not a valid email address: " +msgstr "" + +#: admin/wp-security-filescan-menu.php:206 +msgid "NEW SCAN COMPLETED: The plugin has detected that you have made changes to the \"File Types To Ignore\" or \"Files To Ignore\" fields." +msgstr "" + +#: admin/wp-security-filescan-menu.php:206 +msgid "In order to ensure that future scan results are accurate, the old scan data has been refreshed." +msgstr "" + +#: admin/wp-security-filescan-menu.php:215 +msgid "All In One WP Security & Firewall has detected that there was a change in your host's files." +msgstr "All In One WP Security & Firewall a détecté un changement dans les fichiers de votre hôte." + +#: admin/wp-security-filescan-menu.php:217 +msgid "View scan details and clear this message" +msgstr "" + +#: admin/wp-security-filescan-menu.php:226 +msgid "If given an opportunity hackers can insert their code or files into your system which they can then use to carry out malicious acts on your site." +msgstr "Si on leur en laisse l’opportunité, des pirates peuvent insérer leur code et / ou fichiers dans votre système, qu’ensuite ils utiliseront pour perpétrer des actes malveillants sur votre site." + +#: admin/wp-security-filescan-menu.php:227 +msgid "Being informed of any changes in your files can be a good way to quickly prevent a hacker from causing damage to your website." +msgstr "Être informé de toute modification de vos fichiers peut être un bon moyen d’empêcher rapidement un hacker de nuire à votre site Web." + +#: admin/wp-security-filescan-menu.php:228 +msgid "In general, WordPress core and plugin files and file types such as \".php\" or \".js\" should not change often and when they do, it is important that you are made aware when a change occurs and which file was affected." +msgstr "En général, les fichiers du noyau et extensions WordPress et les types de fichiers comme « .php » ou « .js » ne devraient pas changer souvent, quand ils le font, il est important que vous soyez mis au courant qu’une telle modification s’est produite et quel fichier a été affecté." + +#: admin/wp-security-filescan-menu.php:229 +msgid "The \"File Change Detection Feature\" will notify you of any file change which occurs on your system, including the addition and deletion of files by performing a regular automated or manual scan of your system's files." +msgstr "La fonction « détection d’un changement de fichier » vous avise de tout changement dans votre système de fichiers, y compris l’ajout ou la suppression en effectuant une analyse régulière, automatisée ou manuelle, de votre système de fichiers." + +#: admin/wp-security-filescan-menu.php:230 +msgid "This feature also allows you to exclude certain files or folders from the scan in cases where you know that they change often as part of their normal operation. (For example log files and certain caching plugin files may change often and hence you may choose to exclude such files from the file change detection scan)" +msgstr "Cette fonction permet également d’exclure certains fichiers ou dossiers de l’analyse dans les cas où vous savez qu’ils changent quelquefois dans le cadre d’un fonctionnement normal. (Par exemple les fichiers journaux et certains fichiers plugin mis en cache peuvent changer souvent, c’est pourquoi vous pouvez choisir de les exclure de l’analyse des changements)" + +#: admin/wp-security-filescan-menu.php:241 +msgid "It appears that your server is using an old PHP version which is missing the %s. The file scanner feature needs this class in order to work. If you would like to use this feature please upgrade your server PHP version to 5.3 or greater." +msgstr "" + +#: admin/wp-security-filescan-menu.php:249 +msgid "Manual file change detection scan" +msgstr "Détection manuelle de changements dans les fichiers" + +#: admin/wp-security-filescan-menu.php:255 +msgid "To perform a manual file change detection scan click on the button below." +msgstr "Pour effectuer une analyse manuelle de changement dans les fichiers, cliquez le bouton ci-dessous." + +#: admin/wp-security-filescan-menu.php:258 +msgid "Perform scan now" +msgstr "Effectuer une analyse maintenant" + +#: admin/wp-security-filescan-menu.php:262 +msgid "View last saved file change results" +msgstr "Voir les résultats de la dernière sauvegarde d’analyse des modifications de fichiers" + +#: admin/wp-security-filescan-menu.php:268 +msgid "Click the button below to view the saved file change results from the last scan." +msgstr "Cliquez le bouton ci-dessous pour afficher les résultats des modifications de fichier depuis la dernière analyse." + +#: admin/wp-security-filescan-menu.php:271 +msgid "View last file change" +msgstr "Dernières modifications de fichier" + +#: admin/wp-security-filescan-menu.php:275 +msgid "File change detection settings" +msgstr "Paramètres d’analyse des changements dans les fichiers" + +#: admin/wp-security-filescan-menu.php:287 +msgid "Enable automated file change detection scan" +msgstr "Activer l’analyse automatisée des modifications dans les fichiers" + +#: admin/wp-security-filescan-menu.php:290 +msgid "Check this if you want the system to automatically/periodically scan your files to check for file changes based on the settings below" +msgstr "Cochez si vous voulez que le système analyse automatiquement/périodiquement vos fichiers à la recherche des modifications avec les paramètres ci-dessous" + +#: admin/wp-security-filescan-menu.php:294 +msgid "Scan time interval" +msgstr "Intervalle d’analyse" + +#: admin/wp-security-filescan-menu.php:297 +msgid "Hours" +msgstr "Heures" + +#: admin/wp-security-filescan-menu.php:298 +msgid "Days" +msgstr "Jours" + +#: admin/wp-security-filescan-menu.php:299 +msgid "Weeks" +msgstr "Semaines" + +#: admin/wp-security-filescan-menu.php:301 +msgid "Set the value for how often you would like a scan to occur" +msgstr "Définissez la fréquence souhaitée pour l’analyse" + +#: admin/wp-security-filescan-menu.php:305 +msgid "File types to ignore" +msgstr "Type de fichiers à ignorer" + +#: admin/wp-security-filescan-menu.php:308 +msgid "Enter each file type or extension on a new line which you wish to exclude from the file change detection scan." +msgstr "Entrez chaque type de fichier ou extension à exclure de l’analyse sur une nouvelle ligne." + +#: admin/wp-security-filescan-menu.php:312 +msgid "You can exclude file types from the scan which would not normally pose any security threat if they were changed. These can include things such as image files." +msgstr "Vous pouvez exclure de l’analyse les types de fichiers qui ne constituent pas normalement une menace pour la sécurité s’il ont été modifiés. Ceux-ci peuvent par exemple être les fichiers image." + +#: admin/wp-security-filescan-menu.php:313 +msgid "Example: If you want the scanner to ignore files of type jpg, png, and bmp, then you would enter the following:" +msgstr "Exemple : Si vous souhaitez que l’analyse ignore les fichiers de type JPG, PNG, BMP etc., entrez le texte suivant :" + +#: admin/wp-security-filescan-menu.php:314 +msgid "jpg" +msgstr "jpg" + +#: admin/wp-security-filescan-menu.php:315 +msgid "png" +msgstr "png" + +#: admin/wp-security-filescan-menu.php:316 +msgid "bmp" +msgstr "bmp" + +#: admin/wp-security-filescan-menu.php:322 +msgid "Files/Directories to ignore" +msgstr "Fichiers / Dossiers à ignorer" + +#: admin/wp-security-filescan-menu.php:325 +msgid "Enter each file or directory on a new line which you wish to exclude from the file change detection scan." +msgstr "Entrez chaque fichier ou dossier à exclure de l’analyse sur une nouvelle ligne." + +#: admin/wp-security-filescan-menu.php:329 +msgid "You can exclude specific files/directories from the scan which would not normally pose any security threat if they were changed. These can include things such as log files." +msgstr "Vous pouvez exclure de l’analyse des fichiers et / ou dossiers spécifiques qui ne constituent normalement pas une menace pour la sécurité s’il ont été modifiés. Ceux-ci peuvent être, entre autres, les fichiers journaux." + +#: admin/wp-security-filescan-menu.php:330 +msgid "Example: If you want the scanner to ignore certain files in different directories or whole directories, then you would enter the following:" +msgstr "Exemple : Si vous souhaitez que l’analyse ignore certains fichiers dans différents dossiers ou des dossiers entiers, vous devez entrer le texte suivant :" + +#: admin/wp-security-filescan-menu.php:331 +msgid "cache/config/master.php" +msgstr "cache/config/master.php" + +#: admin/wp-security-filescan-menu.php:332 +msgid "somedirectory" +msgstr "un dossier" + +#: admin/wp-security-filescan-menu.php:339 +msgid "Send email when change detected" +msgstr "Envoyer un courriel si un changement a été détecté" + +#: admin/wp-security-filescan-menu.php:343 +msgid "Check this if you want the system to email you if a file change was detected" +msgstr "Cochez si vous voulez que le système vous contacte s’il détecte une modification de fichier" + +#: admin/wp-security-filescan-menu.php:347 +msgid "Enter one or more email addresses on a new line." +msgstr "" + +#: admin/wp-security-filescan-menu.php:364 +msgid "What is malware?" +msgstr "Qu’est-ce qu’un malware ?" + +#: admin/wp-security-filescan-menu.php:365 +msgid "The word malware stands for Malicious Software. It can consist of things like trojan horses, adware, worms, spyware and any other undesirable code which a hacker will try to inject into your website." +msgstr "Le mot Malware signifie « logiciel malveillant ». Il consiste souvent en des bouts de code comme les chevaux de Troie, adwares, vers, logiciels espions ou tout autre code indésirable qu’un pirate va essayer d’injecter dans votre site web." + +#: admin/wp-security-filescan-menu.php:366 +msgid "Often when malware code has been inserted into your site you will normally not notice anything out of the ordinary based on appearances, but it can have a dramatic effect on your site's search ranking." +msgstr "Souvent, lorsqu’un code malveillant a été inséré dans votre site, vous ne remarquez rien sortant des apparences ordinaires, mais il peut avoir un effet dramatique sur le classement de recherche de votre site." + +#: admin/wp-security-filescan-menu.php:367 +msgid "This is because the bots and spiders from search engines such as Google have the capability to detect malware when they are indexing the pages on your site, and consequently they can blacklist your website which will in turn affect your search rankings." +msgstr "Et parce que les bots et les robots des moteurs de recherche tels que Google ont la capacité de les détecter tout en procédant à l’indexation des pages de votre site, ils risquent de l’ostracisme, ce qui, par voie de conséquences affectera vos classements de recherche." + +#: admin/wp-security-filescan-menu.php:369 +msgid "CLICK HERE" +msgstr "" + +#: admin/wp-security-filescan-menu.php:371 +msgid "Scanning for malware" +msgstr "Recherche de Malwares" + +#: admin/wp-security-filescan-menu.php:372 +msgid "Due to the constantly changing and complex nature of Malware, scanning for such things using a standalone plugin will not work reliably. This is something best done via an external scan of your site regularly." +msgstr "En raison de la constante évolution et de la complexité croissante des Malwares, la recherche en utilisant une simple extension autonome ne donnera que de piètres résultats. C’est une tâche qu’il vaut mieux confier à une analyse externe régulière de votre site." + +#: admin/wp-security-filescan-menu.php:373 +msgid "This is why we have created an easy-to-use scanning service which is hosted off our own server which will scan your site for malware once every day and notify you if it finds anything." +msgstr "C’est pourquoi nous avons créé un service d’analyse facile à utiliser, hébergé hors de notre propre serveur, qui va analyser votre site pour traquer les logiciels malveillants une fois par jour et vous avertir s’il trouve quelque chose." + +#: admin/wp-security-filescan-menu.php:374 +msgid "When you sign up for this service you will get the following:" +msgstr "Lorsque vous vous inscrirez à ce service, vous obtiendrez :" + +#: admin/wp-security-filescan-menu.php:376 +msgid "Automatic daily scan of 1 website" +msgstr "– Une analyse automatique quotidienne pour 1 site Web," + +#: admin/wp-security-filescan-menu.php:377 +msgid "Automatic malware and blacklist monitoring" +msgstr "" + +#: admin/wp-security-filescan-menu.php:378 +msgid "Automatic email alerting" +msgstr "– L’alerte courriel automatique en cas de positif," + +#: admin/wp-security-filescan-menu.php:379 +msgid "Site uptime monitoring" +msgstr "- Surveillance de la disponibilité du site" + +#: admin/wp-security-filescan-menu.php:380 +msgid "Site response time monitoring" +msgstr "– Surveillance du temps de réponse du site" + +#: admin/wp-security-filescan-menu.php:381 +msgid "We provide advice for malware cleanup" +msgstr "" + +#: admin/wp-security-filescan-menu.php:382 +msgid "Blacklist removal" +msgstr "– Annulation du Blacklistage éventuel par les moteurs de recherche," + +#: admin/wp-security-filescan-menu.php:383 +msgid "No contract (cancel anytime)" +msgstr "– Un service non contractuel (arrêt sur simple demande)." + +#: admin/wp-security-filescan-menu.php:385 +msgid "To learn more please %s." +msgstr "Pour en savoir plus, %s." + +#: admin/wp-security-filescan-menu.php:406 +msgid "Latest file change scan results" +msgstr "Résultats de la dernière analyse des modifications de fichiers" + +#: admin/wp-security-filescan-menu.php:416 +msgid "The following files were added to your host." +msgstr "Les fichiers suivants ont été ajoutés à votre hôte :" + +#: admin/wp-security-filescan-menu.php:419 +#: admin/wp-security-filescan-menu.php:440 +#: admin/wp-security-filescan-menu.php:464 +msgid "File" +msgstr "Fichier" + +#: admin/wp-security-filescan-menu.php:420 +#: admin/wp-security-filescan-menu.php:441 +#: admin/wp-security-filescan-menu.php:465 +msgid "File size" +msgstr "Taille du fichier" + +#: admin/wp-security-filescan-menu.php:421 +#: admin/wp-security-filescan-menu.php:442 +#: admin/wp-security-filescan-menu.php:466 +msgid "File modified" +msgstr "Modifié le" + +#: admin/wp-security-filescan-menu.php:437 +msgid "The following files were removed from your host." +msgstr "Les fichiers suivants ont été supprimés de votre hôte :" + +#: admin/wp-security-filescan-menu.php:461 +msgid "The following files were changed on your host." +msgstr "Les fichiers suivants ont été modifiés sur votre hôte :" + +#: admin/wp-security-filesystem-menu.php:26 +#: classes/grade-system/wp-security-feature-item-manager.php:69 +msgid "File permissions" +msgstr "Autorisations du fichier" + +#: admin/wp-security-filesystem-menu.php:27 +msgid "PHP file editing" +msgstr "Édition de fichier PHP" + +#: admin/wp-security-filesystem-menu.php:28 +msgid "WP file access" +msgstr "Accès aux fichiers WP" + +#: admin/wp-security-filesystem-menu.php:29 +msgid "Host system logs" +msgstr "Journaux système" + +#: admin/wp-security-filesystem-menu.php:55 +msgid "Filesystem security" +msgstr "Sécurité des fichiers" + +#: admin/wp-security-filesystem-menu.php:80 +msgid "Nonce check failed for manual DB backup operation!" +msgstr "Echec du contrôle afférent à la sauvegarde manuelle de la BdD !" + +#: admin/wp-security-filesystem-menu.php:90 +msgid "The permissions for %s were succesfully changed to %s" +msgstr "Les autorisations pour %s ont été correctement remplacées par %s" + +#: admin/wp-security-filesystem-menu.php:94 +msgid "Unable to change permissions for %s!" +msgstr "Impossible de modifier les autorisations de %s !" + +#: admin/wp-security-filesystem-menu.php:100 +msgid "File permissions scan" +msgstr "Analyse des autorisations de fichier" + +#: admin/wp-security-filesystem-menu.php:103 +msgid "Your WordPress file and folder permission settings govern the accessability and read/write privileges of the files and folders which make up your WP installation." +msgstr "Les paramètres d’autorisation régissent les privilèges d’accessibilité et de lecture / écriture des fichiers et dossiers qui composent votre installation WP." + +#: admin/wp-security-filesystem-menu.php:104 +msgid "Your WP installation already comes with reasonably secure file permission settings for the filesystem." +msgstr "Votre installation de WP semble disposer de paramètres d’autorisation raisonnablement sécurisés." + +#: admin/wp-security-filesystem-menu.php:105 +msgid "However, sometimes people or other plugins modify the various permission settings of certain core WP folders or files such that they end up making their site less secure because they chose the wrong permission values." +msgstr "Parfois, cependant, des acteurs humains ou d’autres extensions peuvent modifier différents paramètres d’autorisation sur certains fichiers ou dossiers du noyau WP de telle sorte qu’elles finissent par rendre le site moins sécurisé en raison des valeurs d’autorisation incorrectes qu’elles ont choisies." + +#: admin/wp-security-filesystem-menu.php:106 +msgid "This feature will scan the critical WP core folders and files and will highlight any permission settings which are insecure." +msgstr "Cette fonctionnalité va analyser les dossiers et fichiers critiques du noyau WP et mettre en évidence les paramètres d’autorisation précaires." + +#: admin/wp-security-filesystem-menu.php:114 +msgid "This plugin has detected that your site is running on a Windows server." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:115 +msgid "This feature is not applicable for Windows server installations." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:121 +msgid "WP directory and file permissions scan results" +msgstr "Résultat d’analyse des autorisations des dossiers et fichiers du noyau WP" + +#: admin/wp-security-filesystem-menu.php:133 +#: admin/wp-security-filesystem-menu.php:152 +msgid "Name" +msgstr "Nom" + +#: admin/wp-security-filesystem-menu.php:134 +#: admin/wp-security-filesystem-menu.php:153 +msgid "File/Folder" +msgstr "Fichier / Dossier" + +#: admin/wp-security-filesystem-menu.php:135 +#: admin/wp-security-filesystem-menu.php:154 +msgid "Current permissions" +msgstr "Autorisations actuelles" + +#: admin/wp-security-filesystem-menu.php:136 +#: admin/wp-security-filesystem-menu.php:155 +msgid "Recommended permissions" +msgstr "Autorisations recommandées" + +#: admin/wp-security-filesystem-menu.php:137 +#: admin/wp-security-filesystem-menu.php:156 +msgid "Recommended action" +msgstr "Action recommandée" + +#: admin/wp-security-filesystem-menu.php:195 +msgid "Your PHP file editing settings were saved successfully." +msgstr "Les paramètres d’édition des fichiers PHP ont été correctement sauvegardées." + +#: admin/wp-security-filesystem-menu.php:199 +msgid "Operation failed! Unable to modify or make a backup of wp-config.php file!" +msgstr "L’opération a échoué ! Impossible de modifier ou de faire une sauvegarde du fichier wp-config.php !" + +#: admin/wp-security-filesystem-menu.php:212 +#: classes/grade-system/wp-security-feature-item-manager.php:71 +msgid "File editing" +msgstr "Édition de fichier" + +#: admin/wp-security-filesystem-menu.php:215 +msgid "The WordPress Dashboard by default allows administrators to edit PHP files, such as plugin and theme files." +msgstr "Le tableau de bord par défaut de WordPress permet aux administrateurs de modifier les fichiers PHP, tout comme les extension et thèmes." + +#: admin/wp-security-filesystem-menu.php:216 +msgid "This is often the first tool an attacker will use if able to login, since it allows code execution." +msgstr "C’est souvent le premier outil qu’un agresseur utilisera s’il parvient à se connecter, car il permet l’exécution de code." + +#: admin/wp-security-filesystem-menu.php:217 +msgid "This feature will disable the ability for people to edit PHP files via the dashboard." +msgstr "Cette fonction désactive la capacité d’éditer certains fichiers PHP via le tableau de bord." + +#: admin/wp-security-filesystem-menu.php:223 +msgid "Disable PHP file editing" +msgstr "Désactiver l’édition de fichier PHP" + +#: admin/wp-security-filesystem-menu.php:235 +msgid "Disable ability to edit PHP files" +msgstr "Désactiver la capacité d’éditer des fichiers PHP" + +#: admin/wp-security-filesystem-menu.php:238 +msgid "Check this if you want to remove the ability for people to edit PHP files via the WP dashboard" +msgstr "Cochez pour supprimer la possibilité d’éditer les fichiers PHP via le tableau de bord WP" + +#: admin/wp-security-filesystem-menu.php:282 +msgid "You have successfully saved the Prevent Access to Default WP Files configuration." +msgstr "Vous avez enregistré avec succès l’interdiction d’accès à la configuration par défaut des fichiers de WP." + +#: admin/wp-security-filesystem-menu.php:286 +#: admin/wp-security-firewall-menu.php:126 +#: admin/wp-security-firewall-menu.php:346 +#: admin/wp-security-firewall-menu.php:613 +#: admin/wp-security-firewall-menu.php:912 +#: admin/wp-security-settings-menu.php:772 +#: admin/wp-security-spam-menu.php:124 +msgid "Could not write to the .htaccess file. Please check the file permissions." +msgstr "Impossible d’écrire dans le fichier .htaccess. Veuillez vérifier les permissions." + +#: admin/wp-security-filesystem-menu.php:291 +msgid "WordPress files" +msgstr "Fichiers WordPress" + +#: admin/wp-security-filesystem-menu.php:294 +msgid "This feature allows you to prevent access to files such as %s, %s and %s which are delivered with all WP installations." +msgstr "Cette fonctionnalité permet d’empêcher l’accès à des fichiers tels que %s, %s et %s livrés avec toutes les installations de WP." + +#: admin/wp-security-filesystem-menu.php:295 +msgid "By preventing access to these files you are hiding some key pieces of information (such as WordPress version info) from potential hackers." +msgstr "En empêchant l’accès à ces fichiers, vous cacherez certains éléments clé d’information (version de WordPress, celle des d’extensions…) aux pirates éventuels." + +#: admin/wp-security-filesystem-menu.php:300 +msgid "Prevent access to default WP files" +msgstr "Empêcher l’accès aux fichiers par défaut WP" + +#: admin/wp-security-filesystem-menu.php:311 +msgid "Prevent access to WP default install files" +msgstr "Empêcher l’accès aux fichiers d’installation par défaut WP" + +#: admin/wp-security-filesystem-menu.php:314 +msgid "Check this if you want to prevent access to readme.html, license.txt and wp-config-sample.php." +msgstr "Cochez si vous voulez empêcher l’accès à readme.html, license.txt et wp-config-sample.php." + +#: admin/wp-security-filesystem-menu.php:318 +msgid "Save setting" +msgstr "Enregistrer les paramètres" + +#: admin/wp-security-filesystem-menu.php:342 +msgid "System logs" +msgstr "Journaux système" + +#: admin/wp-security-filesystem-menu.php:345 +msgid "Sometimes your hosting platform will produce error or warning logs in a file called \"error_log\"." +msgstr "Parfois, votre plate-forme d’hébergement produira erreur ou avertissement dans le fichier appelé « error_log »." + +#: admin/wp-security-filesystem-menu.php:346 +msgid "Depending on the nature and cause of the error or warning, your hosting server can create multiple instances of this file in numerous directory locations of your WordPress installation." +msgstr "Selon la nature et la cause de l’erreur ou avertissement, votre serveur d’hébergement peut créer plusieurs instances de ce fichier en de nombreux emplacements des dossiers de votre installation WordPress." + +#: admin/wp-security-filesystem-menu.php:347 +msgid "By occassionally viewing the contents of these logs files you can keep informed of any underlying problems on your system which you might need to address." +msgstr "En regardant de temps en temps le contenu de ces fichiers lors vous pouvez être tenu informé de problèmes sous-jacents sur votre système, dont vous pourriez avoir besoin pour répondre." + +#: admin/wp-security-filesystem-menu.php:353 +msgid "View system logs" +msgstr "Voir les journaux système" + +#: admin/wp-security-filesystem-menu.php:355 +msgid "Please click the button below to view the latest system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:358 +msgid "Enter System Log File Name" +msgstr "Entrez le nom du fichier journal système" + +#: admin/wp-security-filesystem-menu.php:360 +msgid "Enter your system log file name. (Defaults to error_log)" +msgstr "Entrez le nom de fichier journal du système. (Par défaut pour error_log)" + +#: admin/wp-security-filesystem-menu.php:363 +msgid "View latest system logs" +msgstr "Afficher les derniers journaux système" + +#: admin/wp-security-filesystem-menu.php:365 +msgid "Loading..." +msgstr "Chargement…" + +#: admin/wp-security-filesystem-menu.php:382 +msgid "No system logs were found." +msgstr "Aucun journal système n’a été trouvé !" + +#: admin/wp-security-filesystem-menu.php:435 +msgid "Set recommended permissions" +msgstr "Appliquer le réglage des autorisations recommandé" + +#: admin/wp-security-filesystem-menu.php:441 +msgid "No action required" +msgstr "Aucune action n’est requise." + +#: admin/wp-security-filesystem-menu.php:481 +msgid "Showing latest entries of error_log file: %s" +msgstr "Affichage des dernières entrées du fichier error_log : %s" + +#: admin/wp-security-firewall-menu.php:28 +msgid "Basic firewall rules" +msgstr "Règles de base du pare-feu" + +#: admin/wp-security-firewall-menu.php:29 +msgid "Additional firewall rules" +msgstr "Règles supplémentaires du pare-feu" + +#: admin/wp-security-firewall-menu.php:30 +msgid "6G Blacklist firewall rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:31 +msgid "Internet bots" +msgstr "Bots internet" + +#: admin/wp-security-firewall-menu.php:32 +msgid "Prevent hotlinks" +msgstr "Prévenir des Hotlinks" + +#: admin/wp-security-firewall-menu.php:33 +msgid "404 detection" +msgstr "Détection d’erreur(s) 404" + +#: admin/wp-security-firewall-menu.php:34 +msgid "Custom rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:122 +#: admin/wp-security-firewall-menu.php:908 +#: admin/wp-security-spam-menu.php:120 +#: admin/wp-security-spam-menu.php:494 +#: admin/wp-security-spam-menu.php:556 +#: admin/wp-security-user-registration-menu.php:95 +msgid "Settings were successfully saved" +msgstr "Vos paramètres ont été enregistrés avec succès." + +#: admin/wp-security-firewall-menu.php:131 +#: admin/wp-security-firewall-menu.php:651 +msgid "Firewall settings" +msgstr "Paramètres du pare-feu" + +#: admin/wp-security-firewall-menu.php:138 +msgid "This should not have any impact on your site's general functionality but if you wish you can take a %s of your .htaccess file before proceeding." +msgstr "Cela ne devrait pas avoir d’incidence sur les fonctionnalités générales de votre site mais, si vous le souhaitez, vous pouvez faire une %s de votre fichier .htaccess avant de procéder." + +#: admin/wp-security-firewall-menu.php:139 +msgid "The features in this tab allow you to activate some basic firewall security protection rules for your site." +msgstr "Les fonctions de cet onglet vous permettent d’activer certaines règles de protection basiques de sécurité du pare-feu pour votre site." + +#: admin/wp-security-firewall-menu.php:140 +msgid "The firewall functionality is achieved via the insertion of special code into your currently active .htaccess file." +msgstr "La fonctionnalité de pare-feu est réalisée par insertion d’un code spécial dans votre fichier .htaccess actuellement actif." + +#: admin/wp-security-firewall-menu.php:151 +msgid "You have enabled the \"Completely Block Access To XMLRPC\" checkbox which means all XMLRPC functionality will be blocked." +msgstr "" + +#: admin/wp-security-firewall-menu.php:152 +msgid "By leaving this feature enabled you will prevent Jetpack or Wordpress iOS or other apps which need XMLRPC from working correctly on your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:153 +msgid "If you still need XMLRPC then uncheck the \"Completely Block Access To XMLRPC\" checkbox and enable only the \"Disable Pingback Functionality From XMLRPC\" checkbox." +msgstr "" + +#: admin/wp-security-firewall-menu.php:163 +msgid "Basic firewall settings" +msgstr "Paramètres de base du pare-feu" + +#: admin/wp-security-firewall-menu.php:171 +msgid "Enable basic firewall protection" +msgstr "Activer la protection de base du pare-feu" + +#: admin/wp-security-firewall-menu.php:174 +msgid "Check this if you want to apply basic firewall protection to your site." +msgstr "Cochez si vous souhaitez appliquer une protection de base au pare-feu de votre site." + +#: admin/wp-security-firewall-menu.php:178 +msgid "This setting will implement the following basic firewall protection mechanisms on your site:" +msgstr "Ce paramètre mettra en œuvre les mécanismes de protection de base du pare-feu suivants sur votre site :" + +#: admin/wp-security-firewall-menu.php:179 +msgid "1) Protect your htaccess file by denying access to it." +msgstr "1) Protection de votre fichier .htaccess en refusant l’accès à celui-ci." + +#: admin/wp-security-firewall-menu.php:180 +msgid "2) Disable the server signature." +msgstr "2) Désactivation de la signature de serveur." + +#: admin/wp-security-firewall-menu.php:181 +msgid "3) Limit file upload size (%sMB)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:182 +msgid "4) Protect your wp-config.php file by denying access to it." +msgstr "4) Protection de votre fichier wp-config.php en refusant l’accès à celui-ci." + +#: admin/wp-security-firewall-menu.php:183 +msgid "The above firewall features will be applied via your .htaccess file and should not affect your site's overall functionality." +msgstr "Les fonctionnalités de pare-feu ci-dessus s’appliqueront via votre fichier .htaccess et ne devraient pas affecter le fonctionnement global du site." + +#: admin/wp-security-firewall-menu.php:184 +msgid "You are still advised to take a backup of your active .htaccess file just in case." +msgstr "Il est toujours conseillé de faire une sauvegarde de votre fichier .htaccess actif, juste au cas où." + +#: admin/wp-security-firewall-menu.php:190 +msgid "Max file upload size (MB)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:192 +msgid "The value for the maximum file upload size used in the .htaccess file. (Defaults to %sMB if left blank)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:200 +msgid "WordPress XMLRPC and pingback vulnerability protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:208 +msgid "Completely block access to XMLRPC" +msgstr "" + +#: admin/wp-security-firewall-menu.php:211 +msgid "Check this if you are not using the WP XML-RPC functionality and you want to completely block external access to XMLRPC." +msgstr "" + +#: admin/wp-security-firewall-menu.php:215 +msgid "This setting will add a directive in your .htaccess to disable access to the WordPress xmlrpc.php file which is responsible for the XML-RPC functionality in WordPress." +msgstr "" + +#: admin/wp-security-firewall-menu.php:216 +msgid "Hackers can exploit various vulnerabilities in the WordPress XML-RPC API in a number of ways such as:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:217 +msgid "1) Denial of Service (DoS) attacks" +msgstr "1) Attaques par déni de Service (DoS)" + +#: admin/wp-security-firewall-menu.php:218 +msgid "2) Hacking internal routers." +msgstr "2) Pirater des routeurs internes." + +#: admin/wp-security-firewall-menu.php:219 +msgid "3) Scanning ports in internal networks to get info from various hosts." +msgstr "3) Analyse des ports dans les réseaux internes pour obtenir des informations de divers hôtes‪." + +#: admin/wp-security-firewall-menu.php:220 +msgid "Apart from the security protection benefit, this feature may also help reduce load on your server, particularly if your site currently has a lot of unwanted traffic hitting the XML-RPC API on your installation." +msgstr "En dehors du bénéfice de protection de sécurité, cette fonctionnalité peut également aider à réduire la charge sur votre serveur, en particulier si votre site a beaucoup de trafic indésirable touchant l’API XML-RPC de votre installation." + +#: admin/wp-security-firewall-menu.php:221 +msgid "NOTE: You should only enable this feature if you are not currently using the XML-RPC functionality on your WordPress installation." +msgstr "REMARQUE : Vous ne devez activer cette fonction que si vous n’utilisez pas actuellement la fonctionnalité XML-RPC sur votre installation WordPress." + +#: admin/wp-security-firewall-menu.php:222 +msgid "Leave this feature disabled and use the feature below if you want pingback protection but you still need XMLRPC." +msgstr "" + +#: admin/wp-security-firewall-menu.php:228 +msgid "Disable pingback functionality from XMLRPC" +msgstr "" + +#: admin/wp-security-firewall-menu.php:231 +msgid "If you use Jetpack or WP iOS or other apps which need WP XML-RPC functionality then check this. This will enable protection against WordPress pingback vulnerabilities." +msgstr "" + +#: admin/wp-security-firewall-menu.php:235 +msgid "NOTE: If you use Jetpack or the Wordpress iOS or other apps then you should enable this feature but leave the \"Completely Block Access To XMLRPC\" checkbox unchecked." +msgstr "" + +#: admin/wp-security-firewall-menu.php:236 +msgid "The feature will still allow XMLRPC functionality on your site but will disable the pingback methods." +msgstr "" + +#: admin/wp-security-firewall-menu.php:237 +msgid "This feature will also remove the \"X-Pingback\" header if it is present." +msgstr "" + +#: admin/wp-security-firewall-menu.php:246 +msgid "Block access to debug log file" +msgstr "" + +#: admin/wp-security-firewall-menu.php:254 +msgid "Block access to debug.log file" +msgstr "" + +#: admin/wp-security-firewall-menu.php:257 +msgid "Check this if you want to block access to the debug.log file that WordPress creates when debug logging is enabled." +msgstr "" + +#: admin/wp-security-firewall-menu.php:261 +msgid "WordPress has an option to turn on the debug logging to a file located in wp-content/debug.log. This file may contain sensitive information." +msgstr "" + +#: admin/wp-security-firewall-menu.php:262 +msgid "Using this option will block external access to this file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:262 +msgid "You can still access this file by logging into your site via FTP." +msgstr "" + +#: admin/wp-security-firewall-menu.php:270 +msgid "Save basic firewall settings" +msgstr "Enregistrer les paramètres de base du pare-feu" + +#: admin/wp-security-firewall-menu.php:342 +msgid "You have successfully saved the Additional Firewall Protection configuration" +msgstr "Vous avez enregistré avec succès la configuration supplémentaire du pare-feu" + +#: admin/wp-security-firewall-menu.php:356 +msgid "Additional firewall protection" +msgstr "Protection supplémentaire du pare-feu" + +#: admin/wp-security-firewall-menu.php:360 +msgid "Due to the nature of the code being inserted to the .htaccess file, this feature may break some functionality for certain plugins and you are therefore advised to take a %s of .htaccess before applying this configuration." +msgstr "En raison de la nature du code étant inséré dans le fichier .htaccess, cette fonctionnalité peut briser certaines fonctionnalités pour certains plugins et vous êtes donc invités à prendre un%s de .htaccess avant d’appliquer cette configuration." + +#: admin/wp-security-firewall-menu.php:362 +msgid "This feature allows you to activate more advanced firewall settings to your site." +msgstr "Cette fonction vous permet d’activer les paramètres de pare-feu plus avancés sur votre site." + +#: admin/wp-security-firewall-menu.php:363 +msgid "The advanced firewall rules are applied via the insertion of special code to your currently active .htaccess file." +msgstr "Les règles avancées du pare-feu sont appliquées par l’intermédiaire de l’insertion de code spécial à votre fichier .htaccess actuellement actif." + +#: admin/wp-security-firewall-menu.php:372 +msgid "Listing of directory contents" +msgstr "Liste du Répertoire des matières" + +#: admin/wp-security-firewall-menu.php:381 +#: classes/grade-system/wp-security-feature-item-manager.php:85 +msgid "Disable index views" +msgstr "Désactiver les vues Index" + +#: admin/wp-security-firewall-menu.php:384 +msgid "Check this if you want to disable directory and file listing." +msgstr "Cochez pour désactiver le listage des dossier et de fichiers." + +#: admin/wp-security-firewall-menu.php:389 +msgid "By default, an Apache server will allow the listing of the contents of a directory if it doesn't contain an index.php file." +msgstr "Par défaut, un serveur Apache permet de lister le contenu d’un dossier, s’il ne contient pas de fichier index.php" + +#: admin/wp-security-firewall-menu.php:391 +msgid "This feature will prevent the listing of contents for all directories." +msgstr "Cette fonctionnalité permet d’empêcher de lister le contenu pour tous les répertoires." + +#: admin/wp-security-firewall-menu.php:393 +msgid "NOTE: In order for this feature to work \"AllowOverride\" of the Indexes directive must be enabled in your httpd.conf file. Ask your hosting provider to check this if you don't have access to httpd.conf" +msgstr "REMARQUE : Afin que cette option puisse travailler en « AllowOverride » la directive de l’index doit être activée dans votre fichier httpd.conf, demandez-en confirmation à votre hébergeur. Si vous n’avez pas accès au fichier httpd.conf, cochez cette case." + +#: admin/wp-security-firewall-menu.php:402 +msgid "Trace and track" +msgstr "Trace et Pistage" + +#: admin/wp-security-firewall-menu.php:411 +#: classes/grade-system/wp-security-feature-item-manager.php:86 +msgid "Disable trace and track" +msgstr "Désactiver Trace et Pistage" + +#: admin/wp-security-firewall-menu.php:414 +msgid "Check this if you want to disable trace and track." +msgstr "Cochez si vous voulez désactiver la trace et le pistage." + +#: admin/wp-security-firewall-menu.php:419 +msgid "HTTP Trace attack (XST) can be used to return header requests and grab cookies and other information." +msgstr "L’attaque par Trace HTTP (XST) peut être utilisée pour renvoyer des demandes d’en-tête et récupérer les cookies et autres informations." + +#: admin/wp-security-firewall-menu.php:421 +msgid "This hacking technique is usually used together with cross site scripting attacks (XSS)." +msgstr "Cette technique de piratage est généralement utilisée conjointement à des attaques cross-site stripping (XSS)." + +#: admin/wp-security-firewall-menu.php:423 +msgid "Disabling trace and track on your site will help prevent HTTP Trace attacks." +msgstr "La désactivation du traçage et du pistage sur votre site aidera à prévenir ces attaques HTTP Trace." + +#: admin/wp-security-firewall-menu.php:432 +msgid "Proxy comment posting" +msgstr "Publication commentaire Proxy" + +#: admin/wp-security-firewall-menu.php:442 +msgid "Forbid proxy comment posting" +msgstr "Interdire l’émission de commentaire par Proxy" + +#: admin/wp-security-firewall-menu.php:445 +msgid "Check this if you want to forbid proxy comment posting." +msgstr "Cochez si vous voulez interdire l’émission de commentaire par proxy." + +#: admin/wp-security-firewall-menu.php:450 +msgid "This setting will deny any requests that use a proxy server when posting comments." +msgstr "Ce paramètre interdit toute requête utilisant un serveur proxy lors de la publication de commentaires." + +#: admin/wp-security-firewall-menu.php:451 +msgid "By forbidding proxy comments you are in effect eliminating some spam and other proxy requests." +msgstr "En interdisant les commentaires par Proxy, quelques courriels et autres requêtes Proxy peuvent être éliminés." + +#: admin/wp-security-firewall-menu.php:460 +msgid "Bad query strings" +msgstr "Chaînes Query incorrectes" + +#: admin/wp-security-firewall-menu.php:470 +msgid "Deny bad query strings" +msgstr "Refuser les chaînes Query incorrecte" + +#: admin/wp-security-firewall-menu.php:473 +msgid "This will help protect you against malicious queries via XSS." +msgstr "Cela contribuera à vous protéger des requêtes malveillantes via XSS." + +#: admin/wp-security-firewall-menu.php:478 +msgid "This feature will write rules in your .htaccess file to prevent malicious string attacks on your site using XSS." +msgstr "Cette fonction va écrire dans votre fichier .htaccess les règles pour contrer les attaques par chaînes XSS malveillantes sur votre site." + +#: admin/wp-security-firewall-menu.php:479 +msgid "NOTE: Some of these strings might be used for plugins or themes and hence this might break some functionality." +msgstr "REMARQUE : Certaines de ces chaînes peuvent servir à certains plugins ou thèmes ceci pourrait briser certaines fonctionnalités." + +#: admin/wp-security-firewall-menu.php:480 +#: admin/wp-security-firewall-menu.php:510 +msgid "You are therefore strongly advised to take a backup of your active .htaccess file before applying this feature." +msgstr "Il est donc fortement conseillé de faire une sauvegarde de votre fichier .htaccess actif avant d’appliquer cette fonctionnalité." + +#: admin/wp-security-firewall-menu.php:489 +#: classes/grade-system/wp-security-feature-item-manager.php:89 +msgid "Advanced character string filter" +msgstr "Filtre avancé de chaînes de caractères" + +#: admin/wp-security-firewall-menu.php:499 +msgid "Enable advanced character string filter" +msgstr "Activer le filtre avancé de chaînes de caractères" + +#: admin/wp-security-firewall-menu.php:502 +msgid "This will block bad character matches from XSS." +msgstr "Ceci bloquera les identités de caractères incorrects depuis XSS." + +#: admin/wp-security-firewall-menu.php:507 +msgid "This is an advanced character string filter to prevent malicious string attacks on your site coming from Cross Site Scripting (XSS)." +msgstr "Il s’agit d’un filtre avancé de chaînes de caractères destiné à contrer les attaques par chaînes sur votre site en provenance de Cross Site Stripping (XSS)." + +#: admin/wp-security-firewall-menu.php:508 +msgid "This setting matches for common malicious string patterns and exploits and will produce a 403 error for the hacker attempting the query." +msgstr "Ce paramètre identifie des modèles de chaînes malveillantes communément exploitées et produit une erreur 403 si un pirate tente une requête." + +#: admin/wp-security-firewall-menu.php:509 +msgid "NOTE: Some strings for this setting might break some functionality." +msgstr "REMARQUE: Certaines chaînes de ce paramètre peuvent briser certaines autres fonctionnalités." + +#: admin/wp-security-firewall-menu.php:518 +msgid "Save additional firewall settings" +msgstr "Enregistrer les paramètres supplémentaires du pare-feu" + +#: admin/wp-security-firewall-menu.php:609 +msgid "You have successfully saved the 5G/6G Firewall Protection configuration" +msgstr "" + +#: admin/wp-security-firewall-menu.php:633 +msgid "All in One WP Security and Firewall" +msgstr "" + +#: admin/wp-security-firewall-menu.php:634 +msgid "We were unable to access the firewall's configuration file:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:636 +msgid "As a result, the firewall will be unavailable." +msgstr "" + +#: admin/wp-security-firewall-menu.php:637 +msgid "Please check your PHP error log for further information." +msgstr "" + +#: admin/wp-security-firewall-menu.php:638 +msgid "If you're unable to locate your PHP log file, please contact your web hosting company to ask them where it can be found on their setup." +msgstr "" + +#: admin/wp-security-firewall-menu.php:655 +msgid "This feature allows you to activate the %s (or legacy %s) firewall security protection rules designed and produced by %s." +msgstr "" + +#: admin/wp-security-firewall-menu.php:656 +msgid "The 6G Blacklist is updated and improved version of 5G Blacklist. If you have 5G Blacklist active, you might consider activating 6G Blacklist instead." +msgstr "" + +#: admin/wp-security-firewall-menu.php:657 +msgid "The 6G Blacklist is a simple, flexible blacklist that helps reduce the number of malicious URL requests that hit your website." +msgstr "" + +#: admin/wp-security-firewall-menu.php:658 +msgid "The added advantage of applying the 6G firewall to your site is that it has been tested and confirmed by the people at PerishablePress.com to be an optimal and least disruptive set of .htaccess security rules for general WP sites running on an Apache server or similar." +msgstr "" + +#: admin/wp-security-firewall-menu.php:659 +msgid "Therefore the 6G firewall rules should not have any impact on your site's general functionality but if you wish you can take a %s of your .htaccess file before proceeding." +msgstr "" + +#: admin/wp-security-firewall-menu.php:665 +msgid "6G blacklist/firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:677 +msgid "Enable 6G firewall protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:680 +msgid "Check this if you want to apply the 6G Blacklist firewall protection from perishablepress.com to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:684 +msgid "This setting will implement the 6G security firewall protection mechanisms on your site which include the following things:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:685 +#: admin/wp-security-firewall-menu.php:703 +msgid "1) Block forbidden characters commonly used in exploitative attacks." +msgstr "1) Blocage de caractères interdits couramment utilisés dans les attaques d’exploitation." + +#: admin/wp-security-firewall-menu.php:686 +#: admin/wp-security-firewall-menu.php:704 +msgid "2) Block malicious encoded URL characters such as the \".css(\" string." +msgstr "2) Blocage les codes malveillants composés de caractères d’URL tels la chaîne « CSS ( »," + +#: admin/wp-security-firewall-menu.php:687 +#: admin/wp-security-firewall-menu.php:705 +msgid "3) Guard against the common patterns and specific exploits in the root portion of targeted URLs." +msgstr "3) Protection contre les schémas communs et spécifiques d’attaques dans la partie racine d’URL ciblées," + +#: admin/wp-security-firewall-menu.php:688 +#: admin/wp-security-firewall-menu.php:706 +msgid "4) Stop attackers from manipulating query strings by disallowing illicit characters." +msgstr "4) Arrêt des attaques manipulant des requête par chaînes en interdisant les caractères illicites" + +#: admin/wp-security-firewall-menu.php:689 +#: admin/wp-security-firewall-menu.php:707 +msgid "....and much more." +msgstr "…et plus encore." + +#: admin/wp-security-firewall-menu.php:695 +msgid "Enable legacy 5G firewall protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:698 +msgid "Check this if you want to apply the 5G Blacklist firewall protection from perishablepress.com to your site." +msgstr "Cochez si vous souhaitez appliquer la protection liste noire pare-feu 5G de perishablepress.com à votre site." + +#: admin/wp-security-firewall-menu.php:702 +msgid "This setting will implement the 5G security firewall protection mechanisms on your site which include the following things:" +msgstr "Ce paramètre mettra en œuvre les mécanismes de sécurité 5G de protection pare-feu sur votre site incluant les éléments suivants :" + +#: admin/wp-security-firewall-menu.php:713 +msgid "Save 5G/6G firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:721 +msgid "6G block request methods" +msgstr "" + +#: admin/wp-security-firewall-menu.php:725 +msgid "HTTP Request methods are used by browsers and clients to communicate with servers to get responses." +msgstr "" + +#: admin/wp-security-firewall-menu.php:726 +msgid "GET and POST are the most commonly used methods to request and submit data for specified resources of the server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:732 +msgid "Block %s method" +msgstr "" + +#: admin/wp-security-firewall-menu.php:735 +msgid "Check this to block the %s request method" +msgstr "" + +#: admin/wp-security-firewall-menu.php:740 +msgid "Some WooCommerce extensions use the PUT request method in addition to GET and POST." +msgstr "" + +#: admin/wp-security-firewall-menu.php:740 +msgid "This means WooCommerce users shouldn't block the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:741 +msgid "A few REST requests use the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:741 +msgid "If your site is communicated by the WP REST API, you should not block the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:749 +msgid "Save request methods settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:757 +msgid "6G other settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:761 +msgid "Block query strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:764 +msgid "Check this to block all query strings recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:768 +msgid "Block request strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:771 +msgid "Check this to block all request strings recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:775 +msgid "Block referrers" +msgstr "" + +#: admin/wp-security-firewall-menu.php:778 +msgid "Check this to block all referrers recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:782 +msgid "Block user-agents" +msgstr "" + +#: admin/wp-security-firewall-menu.php:785 +msgid "Check this to block all user-agents recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:789 +msgid "Save other settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:823 +msgid "The Internet bot settings were successfully saved" +msgstr "Les paramètres de bots Internet ont été enregistrés avec succès" + +#: admin/wp-security-firewall-menu.php:827 +msgid "Internet bot settings" +msgstr "Paramètres Bots Internet" + +#: admin/wp-security-firewall-menu.php:833 +msgid "What is an Internet Bot" +msgstr "" + +#: admin/wp-security-firewall-menu.php:834 +msgid "%s?" +msgstr "%s ?" + +#: admin/wp-security-firewall-menu.php:836 +msgid "A bot is a piece of software which runs on the Internet and performs automatic tasks. For example when Google indexes your pages it uses automatic bots to achieve this task." +msgstr "Un bot est un logiciel qui tourne sur Internet et effectue des tâches automatiques. Par exemple, lorsque Google indexe vos pages, il utilise des robots bots automatiques pour achever cette tâche." + +#: admin/wp-security-firewall-menu.php:837 +msgid "A lot of bots are legitimate and non-malicous but not all bots are good and often you will find some which try to impersonate legitimate bots such as \"Googlebot\" but in reality they have nohing to do with Google at all." +msgstr "De nombreux bots sont légitimes et non-malveillants mais pas tous, ni tout le temps : vous en trouverez qui essaient de se faire passer pour des robots collecteurs légitimes tels « Googlebot » mais qui, en réalité, n’ont rien à voir avec Google." + +#: admin/wp-security-firewall-menu.php:838 +msgid "Although most of the bots out there are relatively harmless sometimes website owners want to have more control over which bots they allow into their site." +msgstr "Bien que la plupart des bots soient relativement inoffensifs, parfois les propriétaires de sites Web veulent avoir le contrôle sur les bots qu’ils admettent dans leur site." + +#: admin/wp-security-firewall-menu.php:839 +msgid "This feature allows you to block bots which are impersonating as a Googlebot but actually aren't. (In other words they are fake Google bots)" +msgstr "Cette fonctionnalité permet de bloquer les robots qui empruntent une identité comme celle de Googlebots, ce qu’en fait ils ne sont pas. (En d’autres termes, ce sont de faux Googlebots)" + +#: admin/wp-security-firewall-menu.php:840 +msgid "Googlebots have a unique indentity which cannot easily be forged and this feature will indentify any fake Google bots and block them from reading your site's pages." +msgstr "les Googlebots ont une identité unique qui ne peut pas facilement être forgée et cette caractéristique va identifier tout faux robots Google et leur bloquer la lecture de pages de votre site." + +#: admin/wp-security-firewall-menu.php:846 +msgid "Attention: Sometimes non-malicious Internet organizations might have bots which impersonate as a \"Googlebot\"." +msgstr "ATTENTION : Parfois des organisations Internet non-malveillantes peuvent avoir des bots usurpant l’identité d’un « Googlebot »." + +#: admin/wp-security-firewall-menu.php:847 +msgid "Just be aware that if you activate this feature the plugin will block all bots which use the \"Googlebot\" string in their User Agent information but are NOT officially from Google (irrespective whether they are malicious or not)." +msgstr "Soyez juste conscient(e) que si vous activez cette fonctionnalité le plugin bloquera tous les robots utilisant la chaîne « Googlebot » dans leurs informations d’ID, mais n’appartenant pas officiellement à Google (indépendamment de ce qu’elles soient malveillantes ou non)." + +#: admin/wp-security-firewall-menu.php:848 +msgid "All other bots from other organizations such as \"Yahoo\", \"Bing\" etc will not be affected by this feature." +msgstr "Aucun des autres robots d’autres organisations telles que « Yahoo », « Bing » etc. ne souffriront de cette fonctionnalité." + +#: admin/wp-security-firewall-menu.php:854 +#: admin/wp-security-firewall-menu.php:864 +#: classes/grade-system/wp-security-feature-item-manager.php:93 +msgid "Block fake Googlebots" +msgstr "Bloquer les faux Googlebots" + +#: admin/wp-security-firewall-menu.php:867 +msgid "Check this if you want to block all fake Googlebots." +msgstr "Cochez si vous souhaitez bloquer tous les faux Googlebots" + +#: admin/wp-security-firewall-menu.php:871 +msgid "This feature will check if the User Agent information of a bot contains the string \"Googlebot\"." +msgstr "Cette fonction vérifie si les informations d’ID d’un bot contient la chaîne « Googlebot »." + +#: admin/wp-security-firewall-menu.php:872 +msgid "It will then perform a few tests to verify if the bot is legitimately from Google and if so it will allow the bot to proceed." +msgstr "Il sera ensuite effectué quelques tests pour vérifier si le bot est légitimement de Google et si elle autorisera le bot à agir." + +#: admin/wp-security-firewall-menu.php:873 +msgid "If the bot fails the checks then the plugin will mark it as being a fake Googlebot and it will block it" +msgstr "Si le bot ne les satisfait pas, alors l’extension le marquera comme faux Googlebot et le bloquera" + +#: admin/wp-security-firewall-menu.php:880 +msgid "Save internet bot settings" +msgstr "Enregistrer les paramètres de Bot Internet" + +#: admin/wp-security-firewall-menu.php:916 +#: admin/wp-security-firewall-menu.php:938 +#: classes/grade-system/wp-security-feature-item-manager.php:95 +msgid "Prevent image hotlinking" +msgstr "Empêcher les liens dynamiques (Hotline)" + +#: admin/wp-security-firewall-menu.php:919 +msgid "A Hotlink is where someone displays an image on their site which is actually located on your site by using a direct link to the source of the image on your server." +msgstr "Un lien dynamique est un lien pointant vers une image de votre site que quelqu’un affiche indûment sur le sien, alors qu’il n’en a pas les droits." + +#: admin/wp-security-firewall-menu.php:920 +msgid "Due to the fact that the image being displayed on the other person's site is coming from your server, this can cause leaking of bandwidth and resources for you because your server has to present this image for the people viewing it on someone elses's site." +msgstr "De plus, du fait que l’image affichée sur l’autre site provient de votre serveur, cela peut provoquer une fuite de bande passante et de ressources pour vous, car votre serveur doit présenter cette image pour la consultation sur un site étranger, cela risque de vous être préjudiciable." + +#: admin/wp-security-firewall-menu.php:921 +msgid "This feature will prevent people from directly hotlinking images from your site's pages by writing some directives in your .htaccess file." +msgstr "Cette fonction neutralise le lien dynamique visant directement les images, articles ou pages de votre site en écrivant quelques directives dans votre fichier .htaccess." + +#: admin/wp-security-firewall-menu.php:926 +msgid "Prevent hotlinking" +msgstr "Prévention des liens dynamiques (Hotlinking)" + +#: admin/wp-security-firewall-menu.php:941 +msgid "Check this if you want to prevent hotlinking to images on your site." +msgstr "Cochez si vous souhaitez empêcher le « Hotlinking » vers votre site." + +#: admin/wp-security-firewall-menu.php:961 +msgid "Nonce check failed for delete all 404 event logs operation!" +msgstr "Échec du contrôle de suppression des journaux d’événements 404 !" + +#: admin/wp-security-firewall-menu.php:972 +msgid "404 Detection Feature - Delete all 404 event logs operation failed!" +msgstr "Fonction de détection 404 - échec de l’opération de suppression de tous les événements 404 des journaux !" + +#: admin/wp-security-firewall-menu.php:976 +msgid "All 404 event logs were deleted from the DB successfully!" +msgstr "Tous les évènements 404 dans les journaux ont été supprimés avec succès !" + +#: admin/wp-security-firewall-menu.php:1000 +msgid "You entered a non numeric value for the lockout time length field. It has been set to the default value." +msgstr "Vous avez entré une valeur non numérique pour le champ « intervalle entre sauvegardes ». Elle sera fixée à la valeur par défaut." + +#: admin/wp-security-firewall-menu.php:1006 +msgid "You entered an incorrect format for the \"Redirect URL\" field. It has been set to the default value." +msgstr "Vous avez entré un format incorrect pour le champ « URL de redirection ». Il a été renseigné par la valeur par défaut." + +#: admin/wp-security-firewall-menu.php:1039 +msgid "404 detection configuration" +msgstr "Configuration de la détection 404" + +#: admin/wp-security-firewall-menu.php:1042 +msgid "A 404 or Not Found error occurs when somebody tries to access a non-existent page on your website." +msgstr "Une erreur 404 « adresse (URL) introuvable » se produit lorsque quelqu'un tente d'accéder à une page inexistante sur votre site web." + +#: admin/wp-security-firewall-menu.php:1043 +msgid "Typically, most 404 errors happen quite innocently when people have mis-typed a URL or used an old link to page which doesn't exist anymore." +msgstr "Généralement, la plupart des erreurs 404 se produisent assez innocemment quand l’utilisateur a mal saisi une URL ou utilisé un vieux lien vers une page qui n’existe plus." + +#: admin/wp-security-firewall-menu.php:1044 +msgid "However, in some cases you may find many repeated 404 errors which occur in a relatively short space of time and from the same IP address which are all attempting to access a variety of non-existent page URLs." +msgstr "Toutefois, dans certains cas, vous pouvez trouver de nombreuses répétition d’erreurs 404 se produisant dans un laps de temps relativement court avec la même adresse IP d’origine qui sont toutes des tentatives d’accéder à une variété d’URL de pages inexistantes." + +#: admin/wp-security-firewall-menu.php:1045 +msgid "Such behaviour can mean that a hacker might be trying to find a particular page or URL for sinister reasons." +msgstr "Un tel comportement peut signifier qu’un pirate essaye de trouver une page ou une URL particulière pour de sinistres mots." + +#: admin/wp-security-firewall-menu.php:1046 +msgid "This feature allows you to monitor all 404 events which occur on your site, and it also gives you the option of blocking IP addresses for a configured length of time." +msgstr "Cette fonctionnalité permet de surveiller tous les événements 404 se produisant sur votre site, et donne également la possibilité de bloquer les adresses IP les ayant générées pour une durée configurée." + +#: admin/wp-security-firewall-menu.php:1047 +msgid "If you want to temporarily block or blacklist an IP address, simply click the \"Temp Block\" or \"Blacklist IP\" link for the applicable IP entry in the \"404 Event Logs\" table below." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1071 +msgid "404 detection options" +msgstr "Options de détection 404" + +#: admin/wp-security-firewall-menu.php:1083 +msgid "Enable 404 IP detection and lockout" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1086 +msgid "Check this if you want to enable the lockout of selected IP addresses." +msgstr "Cochez si vous souhaitez activer le verrouillage des adresses IP sélectionnées." + +#: admin/wp-security-firewall-menu.php:1091 +msgid "When you enable this checkbox, all 404 events on your site will be logged in the table below. You can monitor these events and select some IP addresses listed in the table below and block them for a specified amount of time. All IP addresses you select to be blocked from the \"404 Event Logs\" table section will be unable to access your site during the time specified." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1099 +msgid "Enable 404 event logging" +msgstr "Activer le journal des événements" + +#: admin/wp-security-firewall-menu.php:1102 +msgid "Check this if you want to enable the logging of 404 events" +msgstr "Cochez si vous souhaitez activer la journalisation des événements 404" + +#: admin/wp-security-firewall-menu.php:1107 +msgid "Time length of 404 lockout (minutes)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1109 +msgid "Set the length of time for which a blocked IP address will be prevented from visiting your site" +msgstr "Réglez la durée pendant laquelle une adresse IP bloquée sera empêché de visiter votre site" + +#: admin/wp-security-firewall-menu.php:1114 +msgid "You can lock any IP address which is recorded in the \"404 Event Logs\" table section below." +msgstr "Vous pouvez verrouiller une adresse IP enregistrée dans la section « journaux d'événements 404 » du tableau ci-dessous." + +#: admin/wp-security-firewall-menu.php:1116 +msgid "To temporarily lock an IP address, hover over the ID column and click the \"Temp Block\" link for the applicable IP entry." +msgstr "Pour verrouiller temporairement une adresse IP, survolez la colonne ID et cliquez sur le lien « Temps de Blocage » pour l'entrée IP sélectionnée." + +#: admin/wp-security-firewall-menu.php:1123 +msgid "404 lockout redirect URL" +msgstr "URL de redirection verrouillage 404" + +#: admin/wp-security-firewall-menu.php:1125 +msgid "A blocked visitor will be automatically redirected to this URL." +msgstr "Un visiteur bloqué sera automatiquement redirigé vers cette URL." + +#: admin/wp-security-firewall-menu.php:1135 +msgid "This list displays the 404 event logs when somebody tries to access a non-existent page on your website." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1136 +msgid "404 event logs that are older than %1$d days are purged automatically." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1141 +msgid "404 event logs" +msgstr "Journaux d'événements 404" + +#: admin/wp-security-firewall-menu.php:1163 +#: admin/wp-security-firewall-menu.php:1172 +#: admin/wp-security-user-login-menu.php:495 +#: admin/wp-security-user-login-menu.php:504 +#: admin/wp-security-user-login-menu.php:653 +#: admin/wp-security-user-login-menu.php:662 +msgid "Export to CSV" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1169 +#: admin/wp-security-user-login-menu.php:501 +#: admin/wp-security-user-login-menu.php:659 +msgid "Click this button if you wish to download this log in CSV format." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1176 +#: admin/wp-security-firewall-menu.php:1185 +msgid "Delete all 404 event logs" +msgstr "Supprimer toutes entrées des journaux d'événements 404" + +#: admin/wp-security-firewall-menu.php:1182 +msgid "Click this button if you wish to purge all 404 event logs from the DB." +msgstr "Cliquez ce bouton si vous souhaitez purger les journaux d'événements 404 dans la BdD." + +#: admin/wp-security-firewall-menu.php:1241 +msgid "Custom .htaccess rules settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1248 +msgid "This feature can be used to apply your own custom .htaccess rules and directives." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1249 +msgid "It is useful for when you want to tweak our existing firewall rules or when you want to add your own." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1250 +msgid "NOTE: This feature can only be used if your site is hosted in an apache or similar web server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1256 +msgid "Warning: Only use this feature if you know what you are doing." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1257 +msgid "Incorrect .htaccess rules or directives can break or prevent access to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1258 +msgid "It is your responsibility to ensure that you are entering the correct code!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1259 +msgid "If you break your site you will need to access your server via FTP or something similar and then edit your .htaccess file and delete the changes you made." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1265 +msgid "Custom .htaccess rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1269 +msgid "Enable custom .htaccess rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1272 +msgid "Check this if you want to enable custom rules entered in the text box below" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1276 +msgid "Place custom rules at the top" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1279 +msgid "Check this if you want to place your custom rules at the beginning of all the rules applied by this plugin" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1283 +msgid "Enter custom .htaccess rules:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1287 +msgid "Enter your custom .htaccess rules/directives." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1292 +msgid "Save custom rules" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:338 +#: admin/wp-security-firewall-setup-notice.php:407 +#: admin/wp-security-firewall-setup-notice.php:479 +#: admin/wp-security-firewall-setup-notice.php:595 +#: wp-security.php:43 +msgid "All In One WP Security and Firewall" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:340 +msgid "We were unable to create the file necessary to give you the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:341 +msgid "Your firewall will have reduced protection which means some of your firewall's functionality will be unavailable." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:342 +msgid "If you would like to manually set up the necessary file, please follow these steps:" +msgstr "" + +#. translators: %s Boostrap file name. +#. translators: %s Firewall file name. +#: admin/wp-security-firewall-setup-notice.php:346 +#: admin/wp-security-firewall-setup-notice.php:453 +msgid "1. Create a file with the name %s in the same directory as your WordPress install is in, i.e.:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:350 +msgid "2. Paste in the following code:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:352 +#: admin/wp-security-firewall-setup-notice.php:462 +msgid "3. Save the file and press the 'Try again' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:372 +msgid "1. Open the following file:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:378 +msgid "2. Look for the auto_prepend_file directive." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:382 +msgid "2. Look for the following:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:388 +msgid "3. Change it to the following:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:392 +msgid "4. Save the file and press the 'Try again' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:392 +#: admin/wp-security-firewall-setup-notice.php:441 +msgid "You may have to wait up to 5 minutes before the settings take effect." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:410 +msgid "Your firewall has been installed with the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:411 +msgid "You may have to wait 5 minutes for the changes to take effect." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:434 +msgid "1. Open your php.ini file." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:437 +msgid "2. Set the auto_prepend_file directive like below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:441 +msgid "3. Restart the webserver and refresh the page" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:458 +msgid "2. Paste in the following directives:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:482 +msgid "We were unable to set up your firewall with the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:483 +msgid "Your firewall will have reduced functionality." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:487 +msgid "To give your site the highest level of protection, please follow these steps:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:500 +msgid "Note: if you're unable to perform any of the aforementioned steps, please ask your web hosting provider for further assistance." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:517 +msgid "Try again" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:539 +msgid "We have detected that your AIOS firewall is not fully installed, and therefore does not have the highest level of protection. " +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:540 +msgid "Your firewall will have reduced functionality until it has been upgraded. " +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:542 +msgid "Upgrade your protection now" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:598 +msgid "Our PHP-based firewall has been created to give you even greater protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:602 +msgid "If you already have our .htaccess-based firewall enabled, you will still need to set up the PHP-based firewall to benefit from its protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:605 +msgid "To set up the PHP-based firewall, press the 'Set up now' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:608 +msgid "Set up now" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:614 +#: templates/notices/custom-notice.php:10 +#: templates/notices/custom-notice.php:12 +#: templates/notices/horizontal-notice.php:50 +#: templates/notices/horizontal-notice.php:52 +#: templates/notices/htaccess-to-php-feature-notice.php:10 +#: templates/notices/htaccess-to-php-feature-notice.php:12 +msgid "Dismiss" +msgstr "" + +#: admin/wp-security-list-404.php:91 +msgid "Event type" +msgstr "" + +#: admin/wp-security-list-404.php:92 +#: admin/wp-security-list-logged-in-users.php:46 +#: admin/wp-security-list-registered-users.php:74 +msgid "IP address" +msgstr "" + +#: admin/wp-security-list-404.php:93 +msgid "Attempted URL" +msgstr "" + +#: admin/wp-security-list-404.php:94 +msgid "Referer" +msgstr "" + +#: admin/wp-security-list-404.php:96 +msgid "Lock status" +msgstr "" + +#: admin/wp-security-list-404.php:118 +msgid "Temp block IP" +msgstr "" + +#: admin/wp-security-list-404.php:119 +msgid "Blacklist IP" +msgstr "" + +#: admin/wp-security-list-404.php:120 +#: admin/wp-security-list-acct-activity.php:82 +#: admin/wp-security-list-locked-ip.php:37 +#: admin/wp-security-list-locked-ip.php:84 +#: admin/wp-security-list-login-fails.php:73 +#: admin/wp-security-list-registered-users.php:93 +msgid "Delete" +msgstr "" + +#: admin/wp-security-list-404.php:128 +#: admin/wp-security-list-404.php:136 +#: admin/wp-security-list-404.php:143 +#: admin/wp-security-list-acct-activity.php:92 +#: admin/wp-security-list-comment-spammer-ip.php:95 +#: admin/wp-security-list-locked-ip.php:97 +#: admin/wp-security-list-locked-ip.php:105 +#: admin/wp-security-list-login-fails.php:85 +#: admin/wp-security-list-permanent-blocked-ip.php:96 +#: admin/wp-security-list-registered-users.php:107 +#: admin/wp-security-list-registered-users.php:115 +#: admin/wp-security-list-registered-users.php:123 +msgid "Please select some records using the checkboxes" +msgstr "Veuillez sélectionner les enregistrements concernés par l'opération à l'aide des cases à cocher" + +#: admin/wp-security-list-404.php:278 +msgid "Nonce check failed for delete selected 404 event logs operation!" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:35 +msgid "Are you sure you want to delete this item?" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:46 +msgid "Login session still active" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:60 +#: admin/wp-security-list-locked-ip.php:60 +#: admin/wp-security-list-logged-in-users.php:44 +#: admin/wp-security-list-login-fails.php:54 +#: admin/wp-security-list-registered-users.php:69 +msgid "User ID" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:61 +#: admin/wp-security-list-locked-ip.php:61 +#: admin/wp-security-list-login-fails.php:55 +msgid "Username" +msgstr "Nom d’utilisateur" + +#: admin/wp-security-list-acct-activity.php:62 +msgid "Login date" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:63 +msgid "Logout date" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:136 +msgid "Nonce check failed for delete selected account activity logs operation!" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:59 +msgid "Spammer IP" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:60 +msgid "Number of spam comments from this IP" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:61 +msgid "Status" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:81 +msgid "Block" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:130 +#: admin/wp-security-list-comment-spammer-ip.php:179 +msgid "Nonce check failed for delete selected blocked IP operation!" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:137 +msgid "The selected IP addresses are now permanently blocked!" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:193 +msgid "The selected IP addresses were saved in the blacklist configuration settings." +msgstr "Les adresses IP sélectionnées ont été enregistrées dans les paramètres de la liste noire." + +#: admin/wp-security-list-comment-spammer-ip.php:201 +msgid "The .htaccess file was successfully modified to include the selected IP addresses." +msgstr "Le fichier .htaccess a été modifié avec succès pour exclure les adresses IP sélectionnées." + +#: admin/wp-security-list-comment-spammer-ip.php:212 +msgid "NOTE: The .htaccess file was not modified because you have disabled the \"Enable IP or User Agent Blacklisting\" check box." +msgstr "REMARQUE : Le fichier .htaccess n’a pas été modifié car vous avez décoché la case « Activer l’IP ou l’ID sur liste noire »." + +#: admin/wp-security-list-comment-spammer-ip.php:213 +msgid "To block these IP addresses you will need to enable the above flag in the %s menu" +msgstr "Pour bloquer ces adresses IP, vous devrez activer l’indicateur ci-dessus dans le menu %s" + +#: admin/wp-security-list-debug.php:47 +msgid "Level" +msgstr "" + +#: admin/wp-security-list-debug.php:48 +msgid "Message" +msgstr "" + +#: admin/wp-security-list-debug.php:49 +msgid "Type" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:36 +#: admin/wp-security-list-locked-ip.php:83 +msgid "Unlock" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:59 +msgid "Locked IP/range" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:62 +#: admin/wp-security-list-permanent-blocked-ip.php:67 +msgid "Reason" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:63 +msgid "Date locked" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:64 +msgid "Release date" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:134 +msgid "The selected IP entries were unlocked successfully." +msgstr "Les IP sélectionnées ont été débloquées avec succès ." + +#: admin/wp-security-list-locked-ip.php:140 +msgid "Nonce check failed for unlock IP operation!" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:147 +msgid "The selected IP entry was unlocked successfully." +msgstr "L'IP sélectionnée a été déverrouillée avec succès !" + +#: admin/wp-security-list-logged-in-users.php:45 +#: admin/wp-security-list-registered-users.php:70 +msgid "Login name" +msgstr "" + +#: admin/wp-security-list-logged-in-users.php:87 +msgid "Nonce check failed for force user logout operation!" +msgstr "" + +#: admin/wp-security-list-logged-in-users.php:96 +msgid "The selected user was logged out successfully!" +msgstr "" + +#: admin/wp-security-list-login-fails.php:53 +msgid "Login IP range" +msgstr "" + +#: admin/wp-security-list-login-fails.php:130 +msgid "Nonce check failed for delete failed login record operation!" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:66 +msgid "Blocked IP" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:87 +msgid "Unblock" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:122 +#: admin/wp-security-list-permanent-blocked-ip.php:139 +msgid "Successfully unblocked and deleted the selected record(s)." +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:126 +#: admin/wp-security-list-permanent-blocked-ip.php:143 +msgid "Failed to unblock and delete the selected record(s)." +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:133 +msgid "Nonce check failed for unblock IP operation!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:71 +msgid "Email" +msgstr "" + +#: admin/wp-security-list-registered-users.php:72 +msgid "Register date" +msgstr "" + +#: admin/wp-security-list-registered-users.php:73 +msgid "Account status" +msgstr "" + +#: admin/wp-security-list-registered-users.php:92 +msgid "Approve" +msgstr "" + +#: admin/wp-security-list-registered-users.php:94 +msgid "Block IP" +msgstr "" + +#: admin/wp-security-list-registered-users.php:159 +msgid "The selected accounts were approved successfully!" +msgstr "Les comptes sélectionnés ont été approuvés avec succès !" + +#: admin/wp-security-list-registered-users.php:163 +msgid "The following accounts failed to update successfully: " +msgstr "Les comptes suivants ont échoué à être mis à jour :" + +#: admin/wp-security-list-registered-users.php:171 +msgid "The selected account was approved successfully!" +msgstr "Le compte sélectionné a été approuvé avec succès !" + +#: admin/wp-security-list-registered-users.php:190 +msgid "Your account is now active" +msgstr "Votre compte est désormais actif" + +#: admin/wp-security-list-registered-users.php:191 +msgid "Your account with username: " +msgstr "Identifiant de l’administrateur" + +#: admin/wp-security-list-registered-users.php:191 +msgid " is now active" +msgstr "est maintenant actif" + +#: admin/wp-security-list-registered-users.php:222 +msgid "The selected accounts were deleted successfully!" +msgstr "Les comptes sélectionnés ont été supprimés avec succès!" + +#: admin/wp-security-list-registered-users.php:230 +msgid "Nonce check failed for delete registered user account operation!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:238 +msgid "The selected account was deleted successfully!" +msgstr "Le compte sélectionné a été supprimé avec succès !" + +#: admin/wp-security-list-registered-users.php:264 +msgid "The selected IP addresses were successfully added to the permanent block list!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:265 +#: admin/wp-security-list-registered-users.php:282 +msgid "View Blocked IPs" +msgstr "" + +#: admin/wp-security-list-registered-users.php:274 +msgid "Nonce check failed for block IP operation of registered user!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:281 +msgid "The selected IP was successfully added to the permanent block list!" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:25 +msgid "Visitor lockout" +msgstr "Visiteur bloqué" + +#: admin/wp-security-maintenance-menu.php:85 +msgid "Site lockout feature settings saved!" +msgstr "Paramètres de fonction de verrouillage du site sauvegardés !" + +#: admin/wp-security-maintenance-menu.php:92 +msgid "General visitor lockout" +msgstr "Tous visiteurs bloqués" + +#: admin/wp-security-maintenance-menu.php:98 +msgid "This feature allows you to put your site into \"maintenance mode\" by locking down the front-end to all visitors except logged in users with super admin privileges." +msgstr "Cette fonctionnalité permet de mettre votre site en mode « maintenance » en verrouillant le site à tous les visiteurs, sauf ceux ayant des privilèges d'administrateur ou super-admin." + +#: admin/wp-security-maintenance-menu.php:99 +msgid "Locking your site down to general visitors can be useful if you are investigating some issues on your site or perhaps you might be doing some maintenance and wish to keep out all traffic for security reasons." +msgstr "Le verrouillage de votre site aux visiteurs peut être utile, que vous ayez à étudier quelque point sur votre site, deviez faire un peu de ménage ou souhaitiez fermer tout le trafic pour raison de sécurité." + +#: admin/wp-security-maintenance-menu.php:104 +msgid "Enable front-end lockout" +msgstr "Activer le verrouillage du site" + +#: admin/wp-security-maintenance-menu.php:107 +msgid "Check this if you want all visitors except those who are logged in as administrator to be locked out of the front-end of your site." +msgstr "Cochez si vous souhaitez que tous les visiteurs, sauf ceux ayant des privilèges administrateur soient empêchés d’accès à votre site." + +#: admin/wp-security-maintenance-menu.php:111 +msgid "Enter a message:" +msgstr "Saisissez un message :" + +#: admin/wp-security-maintenance-menu.php:123 +msgid "Enter a message you wish to display to visitors when your site is in maintenance mode." +msgstr "Entrez le message que vous souhaitez afficher aux visiteurs lorsque votre site est en mode maintenance." + +#: admin/wp-security-maintenance-menu.php:130 +msgid "Save site lockout settings" +msgstr "Enregistrer les paramètres de verrouillage du site" + +#: admin/wp-security-misc-options-menu.php:28 +msgid "Copy protection" +msgstr "Protection contre la copie" + +#: admin/wp-security-misc-options-menu.php:29 +msgid "Frames" +msgstr "Cadres" + +#: admin/wp-security-misc-options-menu.php:30 +msgid "Users enumeration" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:31 +msgid "WP REST API" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:89 +msgid "Copy Protection feature settings saved!" +msgstr "Paramètres de la fonction de protection contre la copie sauvegardés !" + +#: admin/wp-security-misc-options-menu.php:94 +msgid "Disable the ability to copy text" +msgstr "Désactiver la possibilité de copier du texte" + +#: admin/wp-security-misc-options-menu.php:100 +msgid "This feature allows you to disable the ability to select and copy text from your front end." +msgstr "Cette fonction permet de désactiver la possibilité de sélectionner et copier du texte depuis votre site." + +#: admin/wp-security-misc-options-menu.php:101 +msgid "When admin user is logged in, the feature is automatically disabled for his session." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:106 +msgid "Enable copy protection" +msgstr "Activer la protection contre la copie" + +#: admin/wp-security-misc-options-menu.php:109 +msgid "Check this if you want to disable the \"Right click\", \"Text selection\" and \"Copy\" option on the front end of your site." +msgstr "Cochez si vous souhaitez désactiver le « clic droit », « Sélection de texte » et l'option « Copier » sur votre site." + +#: admin/wp-security-misc-options-menu.php:116 +msgid "Save copy protection settings" +msgstr "Enregistrer les paramètres de protection contre la copie" + +#: admin/wp-security-misc-options-menu.php:140 +msgid "Frame Display Prevention feature settings saved!" +msgstr "Paramètres de la fonction protection de l’affichage de cadres enregistrés !" + +#: admin/wp-security-misc-options-menu.php:145 +msgid "Prevent your site from being displayed in a frame" +msgstr "Empêcher votre site d'être affiché dans un cadre" + +#: admin/wp-security-misc-options-menu.php:151 +msgid "This feature allows you to prevent other sites from displaying any of your content via a frame or iframe." +msgstr "Cette fonction permet d’empêcher d’autres sites d’afficher tout le contenu du votre via un frame ou iframe." + +#: admin/wp-security-misc-options-menu.php:152 +msgid "When enabled, this feature will set the \"X-Frame-Options\" paramater to \"sameorigin\" in the HTTP header." +msgstr "Lorsqu’activée, cette fonction permet de paramétrer « X-Frame-Options » à « sameorigin » dans l’en-tête HTTP." + +#: admin/wp-security-misc-options-menu.php:157 +msgid "Enable iFrame protection" +msgstr "Activer la protection iFrame" + +#: admin/wp-security-misc-options-menu.php:160 +msgid "Check this if you want to stop other sites from displaying your content in a frame or iframe." +msgstr "Cochez si vous voulez empêcher d’autres sites d’afficher votre contenu dans un frame (cadre) ou iframe." + +#: admin/wp-security-misc-options-menu.php:191 +msgid "Users Enumeration Prevention feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:196 +msgid "Prevent users enumeration" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:202 +msgid "This feature allows you to prevent external users/bots from fetching the user info with urls like \"/?author=1\"." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:203 +msgid "When enabled, this feature will print a \"forbidden\" error rather than the user information." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:208 +msgid "Disable users enumeration" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:211 +msgid "Check this if you want to stop users enumeration." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:242 +msgid "WP REST API Security feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:253 +msgid "This feature allows you to block WordPress REST API access for unauthorized requests." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:254 +msgid "When enabled this feature will only allow REST requests to be processed if the user is logged in." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:260 +msgid "Beware that if you are using other plugins which have registered REST endpoints (eg, Contact Form 7), then this feature will also block REST requests used by these plugins if the user is not logged in. It is recommended that you leave this feature disabled if you want uninterrupted functionality for such plugins." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:268 +msgid "Disallow unauthorized REST requests" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:271 +msgid "Check this if you want to stop REST API access for non-logged in requests." +msgstr "" + +#: admin/wp-security-settings-menu.php:25 +msgid "General settings" +msgstr "Paramètres généraux" + +#: admin/wp-security-settings-menu.php:29 +#: admin/wp-security-settings-menu.php:33 +msgid "file" +msgstr "Fichier" + +#: admin/wp-security-settings-menu.php:37 +msgid "Delete plugin settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:41 +msgid "WP version info" +msgstr "" + +#: admin/wp-security-settings-menu.php:45 +msgid "Import/Export" +msgstr "Importer/Exporter" + +#: admin/wp-security-settings-menu.php:52 +msgid "Advanced settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:128 +msgid "All the security features have been disabled successfully!" +msgstr "Tous les dispositifs de sécurité ont été désactivés avec succès!" + +#: admin/wp-security-settings-menu.php:132 +#: admin/wp-security-settings-menu.php:159 +msgid "Could not write to the .htaccess file. Please restore your .htaccess file manually using the restore functionality in the \".htaccess File\"." +msgstr "Impossible d’écrire dans le fichier .htaccess. Veuillez restaurer manuellement votre fichier .htaccess en utilisant la fonction de restauration dans « Fichier .htaccess »." + +#: admin/wp-security-settings-menu.php:137 +msgid "Could not write to the wp-config.php. Please restore your wp-config.php file manually using the restore functionality in the \"wp-config.php File\"." +msgstr "Impossible d’écrire dans wp-config.php. Veuillez restaurer manuellement votre fichier wp-config.php en utilisant la fonction de restauration dans « Fichier wp-config.php »." + +#: admin/wp-security-settings-menu.php:155 +msgid "All firewall rules have been disabled successfully!" +msgstr "Toutes les règles de pare-feu ont été désactivés avec succès !" + +#: admin/wp-security-settings-menu.php:177 +msgid "Deletion of aio_wp_security_configs option and .htaccess directives failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:179 +msgid "Reset of aio_wp_security_configs option failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:181 +msgid "Deletion of .htaccess directives failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:183 +msgid "All settings have been successfully reset." +msgstr "" + +#: admin/wp-security-settings-menu.php:203 +msgid "For information, updates and documentation, please visit the" +msgstr "Pour informations, mises à jour et documentation, veuillez visiter" + +#: admin/wp-security-settings-menu.php:203 +msgid "Page" +msgstr "Page" + +#: admin/wp-security-settings-menu.php:204 +msgid "Follow us" +msgstr "Suivez-nous" + +#: admin/wp-security-settings-menu.php:204 +msgid "on Twitter, Google+ or via Email to stay up to date about the new security features of this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:208 +msgid "WP Security plugin" +msgstr "Extension de sécurité WP" + +#: admin/wp-security-settings-menu.php:212 +msgid "Thank you for using the AIOS security plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:216 +msgid "There are a lot of security features in this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:221 +msgid "To start, go through each security option and enable the \"basic\" options." +msgstr "" + +#: admin/wp-security-settings-menu.php:225 +msgid "The more features you enable, the more security points you will achieve." +msgstr "" + +#: admin/wp-security-settings-menu.php:228 +msgid "Before doing anything we advise taking a backup of your .htaccess file, database and wp-config.php." +msgstr "" + +#: admin/wp-security-settings-menu.php:231 +msgid "Backup your database" +msgstr "Sauvegarder votre BdD" + +#: admin/wp-security-settings-menu.php:232 +#: admin/wp-security-settings-menu.php:433 +msgid "Backup .htaccess file" +msgstr "Sauvegarder le .htaccess" + +#: admin/wp-security-settings-menu.php:233 +#: admin/wp-security-settings-menu.php:534 +msgid "Backup wp-config.php file" +msgstr "Sauvegarder wp-config.php" + +#: admin/wp-security-settings-menu.php:240 +msgid "Disable security features" +msgstr "Désactiver les fonctions de sécurité" + +#: admin/wp-security-settings-menu.php:246 +msgid "If you think that some plugin functionality on your site is broken due to a security feature you enabled in this plugin, then use the following option to turn off all the security features of this plugin." +msgstr "Si vous pensez que certaines fonctionnalités d'extension sur votre site sont brisées à cause d'une fonction de sécurité activée par All-In-One WP Security & Firewall, utilisez l'option suivante pour désactiver toutes les fonctions de sécurité." + +#: admin/wp-security-settings-menu.php:250 +msgid "Disable all security features" +msgstr "Désactiver toutes les fonctions de sécurité" + +#: admin/wp-security-settings-menu.php:257 +#: admin/wp-security-settings-menu.php:267 +msgid "Disable all firewall rules" +msgstr "Désactiver toutes les règles de pare-feu" + +#: admin/wp-security-settings-menu.php:263 +msgid "This feature will disable all firewall rules which are currently active in this plugin and it will also delete these rules from your .htacess file. Use it if you think one of the firewall rules is causing an issue on your site." +msgstr "Cette fonction permet de désactiver toutes les règles de pare-feu actuellement actives dans cette extension, elle supprime également ces règles dans le fichier .htaccess. Utilisez-la si vous pensez que l’une des règles de pare-feu est à l’origine d’un problème sur votre site." + +#: admin/wp-security-settings-menu.php:274 +#: admin/wp-security-settings-menu.php:287 +msgid "Reset settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:279 +msgid "This button click will delete all of your settings related to the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:280 +msgid "This button click will reset/empty all the database tables of the security plugin also." +msgstr "" + +#: admin/wp-security-settings-menu.php:281 +msgid "Use this plugin if you were locked out by the All In One WP Security & Firewall Plugin and/or you are having issues logging in when that plugin is activated." +msgstr "" + +#: admin/wp-security-settings-menu.php:282 +msgid "In addition to the settings it will also delete any directives which were added to the .htaccess file by the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:283 +msgid "%1$sNOTE: %2$sAfter deleting the settings you will need to re-configure the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:295 +msgid "Debug settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:301 +msgid "This setting allows you to enable/disable debug for this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:307 +msgid "Enable debug" +msgstr "" + +#: admin/wp-security-settings-menu.php:310 +msgid "Check this if you want to enable debug. You should keep this option disabled after you have finished debugging the issue." +msgstr "" + +#: admin/wp-security-settings-menu.php:314 +msgid "Save debug settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:350 +msgid "Your .htaccess file was successfully backed up! Using an FTP program go to the \"/wp-content/aiowps_backups\" directory to save a copy of the file to your computer." +msgstr "Votre fichier .htaccess a été sauvegardé avec succès ! Si vous utilisez un programme FTP, allez dans le répertoire « /wp-content/aiowps_backups » pour en enregistrer une copie sur votre ordinateur." + +#: admin/wp-security-settings-menu.php:356 +msgid "htaccess file rename failed during backup. Please check your root directory for the backup file using FTP." +msgstr "Le renommage du .htaccess a échoué lors de la sauvegarde. Veuillez vérifier votre répertoire racine pour le fichier de sauvegarde via FTP." + +#: admin/wp-security-settings-menu.php:362 +msgid "htaccess backup failed." +msgstr "La sauvegarde du .htaccess a échoué." + +#: admin/wp-security-settings-menu.php:377 +msgid "Please choose a .htaccess to restore from." +msgstr "Choisir un .htaccess à partir duquel restaurer." + +#: admin/wp-security-settings-menu.php:392 +msgid "htaccess file restore failed. Please attempt to restore the .htaccess manually using FTP." +msgstr "Échec de la restauration du .htaccess. Essayer de le restaurer manuellement en utilisant FTP si nécessaire." + +#: admin/wp-security-settings-menu.php:396 +msgid "Your .htaccess file has successfully been restored!" +msgstr "Votre fichier .htaccess a été restauré avec succès !" + +#: admin/wp-security-settings-menu.php:402 +msgid "htaccess Restore operation failed! Please check the contents of the file you are trying to restore from." +msgstr "L’opération de restauration du .htaccess a échoué ! Veuillez vérifier le contenu du fichier à partir duquel vous avez essayé de restaurer." + +#: admin/wp-security-settings-menu.php:408 +msgid ".htaccess file operations" +msgstr "Opérations sur le fichier .htaccess" + +#: admin/wp-security-settings-menu.php:411 +msgid "Your \".htaccess\" file is a key component of your website's security and it can be modified to implement various levels of protection mechanisms." +msgstr "Votre fichier « .htaccess » est un élément clé de la sécurité de votre site Web et il peut être modifié pour mettre en œuvre différents niveaux de mécanismes de protection." + +#: admin/wp-security-settings-menu.php:412 +msgid "This feature allows you to backup and save your currently active .htaccess file should you need to re-use the the backed up file in the future." +msgstr "Cette fonctionnalité permet de sauvegarder et enregistrer votre fichier .htaccess actuellement actif si vous avez besoin de réutiliser la sauvegarde à l’avenir." + +#: admin/wp-security-settings-menu.php:413 +msgid "You can also restore your site's .htaccess settings using a backed up .htaccess file." +msgstr "Vous pouvez également restaurer les paramètres .htaccess de votre site en utilisant un fichier .htaccess sauvegardé." + +#: admin/wp-security-settings-menu.php:428 +msgid "Save the current .htaccess file" +msgstr "Sauvegarder le fichier .htaccess actuel" + +#: admin/wp-security-settings-menu.php:432 +msgid "Click the button below to backup and save the currently active .htaccess file." +msgstr "Cliquez le bouton ci-dessous pour sauvegarder et enregistrer le fichier .htaccess actuellement actif." + +#: admin/wp-security-settings-menu.php:437 +msgid "Restore from a backed up .htaccess file" +msgstr "Restaurer à partir d'un fichier .htaccess sauvegardé antérieurement" + +#: admin/wp-security-settings-menu.php:443 +msgid ".htaccess file to restore from" +msgstr "Fichier .htaccess à partir duquel restaurer" + +#: admin/wp-security-settings-menu.php:445 +msgid "Select Your htaccess File" +msgstr "" + +#: admin/wp-security-settings-menu.php:449 +msgid "After selecting your file, click the button below to restore your site using the backed up htaccess file (htaccess_backup.txt)." +msgstr "Après avoir sélectionné votre fichier, cliquez le bouton ci-dessous pour restaurer votre site en utilisant le fichier .htaccess sauvegardé (htaccess_backup.txt)." + +#: admin/wp-security-settings-menu.php:455 +msgid "Restore .htaccess file" +msgstr "Restaurer le fichier .htaccess" + +#: admin/wp-security-settings-menu.php:477 +msgid "Please choose a wp-config.php file to restore from." +msgstr "Veuillez choisir un fichier wp-config.php à partir duquel restaurer." + +#: admin/wp-security-settings-menu.php:493 +msgid "wp-config.php file restore failed. Please attempt to restore this file manually using FTP." +msgstr "Échec de la restauration du fichier wp-config.php. Essayez de restaurer ce fichier manuellement, à l’aide de FTP si nécessaire." + +#: admin/wp-security-settings-menu.php:497 +msgid "Your wp-config.php file has successfully been restored!" +msgstr "Votre fichier wp-config.php a été restauré avec succès" + +#: admin/wp-security-settings-menu.php:503 +msgid "wp-config.php Restore operation failed! Please check the contents of the file you are trying to restore from." +msgstr "L'opération de restauration du wp-config.php a échoué ! Veuillez vérifiez le contenu du fichier à partir duquel vous avez essayez de restaurer." + +#: admin/wp-security-settings-menu.php:509 +msgid "wp-config.php file operations" +msgstr "Opérations sur les fichiers wp-config.php" + +#: admin/wp-security-settings-menu.php:512 +msgid "Your \"wp-config.php\" file is one of the most important in your WordPress installation. It is a primary configuration file and contains crucial things such as details of your database and other critical components." +msgstr "Votre fichier « wp-config.php » est l’un des plus importants de votre installation WordPress. C’est un fichier de configuration principal qui contient des éléments essentiels comme les détails de votre base de données et autres éléments importants." + +#: admin/wp-security-settings-menu.php:513 +msgid "This feature allows you to backup and save your currently active wp-config.php file should you need to re-use the the backed up file in the future." +msgstr "Cette fonctionnalité permet de sauvegarder et enregistrer votre fichier wp-config.php actuellement actif au cas où vous auriez besoin de ré-utiliser le fichier sauvegardé à l'avenir." + +#: admin/wp-security-settings-menu.php:514 +msgid "You can also restore your site's wp-config.php settings using a backed up wp-config.php file." +msgstr "Vous pouvez également restaurer les paramètres wp-config.php de votre site en utilisant un fichier wp-config.php sauvegardés." + +#: admin/wp-security-settings-menu.php:529 +msgid "Save the current wp-config.php file" +msgstr "Le fichier wp-config.php a été mis à jour avec succès !" + +#: admin/wp-security-settings-menu.php:533 +msgid "Click the button below to backup and download the contents of the currently active wp-config.php file." +msgstr "Cliquez le bouton ci-dessous pour sauvegarder et télécharger le contenu du fichier wp-config.php actif." + +#: admin/wp-security-settings-menu.php:539 +msgid "Restore from a backed up wp-config file" +msgstr "Restaurer wp-config à partir d’une sauvegarde antérieure" + +#: admin/wp-security-settings-menu.php:545 +msgid "wp-config file to restore from" +msgstr "Fichier wp-config à restaurer" + +#: admin/wp-security-settings-menu.php:547 +msgid "Select Your wp-config File" +msgstr "" + +#: admin/wp-security-settings-menu.php:551 +msgid "After selecting your file click the button below to restore your site using the backed up wp-config file (wp-config.php.backup.txt)." +msgstr "Après avoir sélectionné votre fichier, cliquez le bouton ci-dessous pour restaurer votre site en utilisant la sauvegarde du fichier wp-config (wp-config.php.backup.txt)." + +#: admin/wp-security-settings-menu.php:557 +msgid "Restore wp-config file" +msgstr "Restaurer le fichier wp-config" + +#: admin/wp-security-settings-menu.php:591 +msgid "Manage delete plugin settings saved." +msgstr "" + +#: admin/wp-security-settings-menu.php:596 +msgid "Manage delete plugin tasks" +msgstr "" + +#: admin/wp-security-settings-menu.php:603 +msgid "Delete database tables" +msgstr "" + +#: admin/wp-security-settings-menu.php:606 +msgid "Check this if you want to remove database tables when the plugin is uninstalled." +msgstr "" + +#: admin/wp-security-settings-menu.php:610 +msgid "Delete settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:613 +msgid "Check this if you want to remove all plugin settings when uninstalling the plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:613 +msgid "It will also remove all custom htaccess rules that were added by this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:647 +msgid "WP generator meta tag and version info" +msgstr "" + +#: admin/wp-security-settings-menu.php:650 +msgid "WordPress generator automatically adds some meta information inside the \"head\" tags of every page on your site's front end. Below is an example of this:" +msgstr "Le générateur WordPress ajoute automatiquement quelques méta-informations à l’intérieur des balises « Head » de chaque page du visuel de votre site. Voici un exemple de celles-ci :" + +#: admin/wp-security-settings-menu.php:652 +msgid "The above meta information shows which version of WordPress your site is currently running and thus can help hackers or crawlers scan your site to see if you have an older version of WordPress or one with a known exploit." +msgstr "Les méta-informations ci-dessus indiquent quelle version de WordPress est en cours d'exécution pour votre site, et peut ainsi aider les pirates ou des robots d'analyse si vous avez une ancienne version de WordPress ou comportant une faille connue." + +#: admin/wp-security-settings-menu.php:653 +msgid "There are also other ways wordpress reveals version info such as during style and script loading. An example of this is:" +msgstr "" + +#: admin/wp-security-settings-menu.php:655 +msgid "This feature will allow you to remove the WP generator meta info and other version info from your site's pages." +msgstr "" + +#: admin/wp-security-settings-menu.php:661 +msgid "WP generator meta info" +msgstr "WP générateur d’Infos Meta" + +#: admin/wp-security-settings-menu.php:673 +msgid "Remove WP generator meta info" +msgstr "Supprimer le générateur WP d’Infos Meta" + +#: admin/wp-security-settings-menu.php:676 +msgid "Check this if you want to remove the version and meta info produced by WP from all pages" +msgstr "" + +#: admin/wp-security-settings-menu.php:704 +msgid "Please choose a file to import your settings from." +msgstr "Veuillez choisir un fichier à partir duquel importer les paramètres." + +#: admin/wp-security-settings-menu.php:736 +msgid "Import AIOS settings from " +msgstr "" + +#: admin/wp-security-settings-menu.php:742 +#: admin/wp-security-settings-menu.php:786 +msgid "The deletion of the import file failed. Please delete this file manually via the media menu for security purposes." +msgstr "La suppression du fichier importation a échoué. Veuillez supprimer ce fichier manuellement via le menu médias pour raison de sécurité." + +#: admin/wp-security-settings-menu.php:744 +#: admin/wp-security-settings-menu.php:788 +msgid "The file you uploaded was also deleted for security purposes because it contains security settings details." +msgstr "Le fichier que vous avez téléchargé a également été supprimé pour raison de sécurité, car il contient des informations de paramétrage de sécurité." + +#: admin/wp-security-settings-menu.php:759 +msgid "Your AIOS settings were successfully imported via file input." +msgstr "" + +#: admin/wp-security-settings-menu.php:760 +msgid "The deletion of the import file failed. Please delete this file manually via the media menu for security purposes because it contains security settings details." +msgstr "La suppression du fichier à importer a échoué. Veuillez supprimer ce fichier manuellement via le menu des médias pour raison de sécurité, car il contient le détail des paramètres de sécurité." + +#: admin/wp-security-settings-menu.php:762 +msgid "Your AIOS settings were successfully imported. The file you uploaded was also deleted for security purposes because it contains security settings details." +msgstr "" + +#: admin/wp-security-settings-menu.php:765 +msgid "Your AIOS settings were successfully imported via text entry." +msgstr "" + +#: admin/wp-security-settings-menu.php:780 +msgid "The contents of your settings file appear invalid. Please check the contents of the file you are trying to import settings from." +msgstr "Le contenu du fichier de paramètres affiché est non valide. Vérifiez le contenu du fichier d'import des paramètres." + +#: admin/wp-security-settings-menu.php:797 +msgid "Export or import your AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:800 +msgid "This section allows you to export or import your All In One WP Security & Firewall settings." +msgstr "Cette section permet d’exporter ou importer tous vos paramètres d’All In One WP Security & Firewall ." + +#: admin/wp-security-settings-menu.php:801 +msgid "This can be handy if you wanted to save time by applying the settings from one site to another site." +msgstr "Cela peut être pratique si vous voulez gagner du temps en appliquant les paramètres d’un site à un autre." + +#: admin/wp-security-settings-menu.php:802 +msgid "NOTE: Before importing, it is your responsibility to know what settings you are trying to import. Importing settings blindly can cause you to be locked out of your site." +msgstr "REMARQUE : Avant d’importer, il est de votre responsabilité de bien savoir quels sont les paramètres que vous essayez d’installer : importer aveuglément des paramètres de sécurité peut vous bloquer hors de votre site." + +#: admin/wp-security-settings-menu.php:803 +msgid "For Example: If a settings item relies on the domain URL then it may not work correctly when imported into a site with a different domain." +msgstr "Par exemple : si un des élément du paramétrage dépend de l’URL de domaine, il peut ne pas fonctionner correctement lorsqu’importé dans un site avec un domaine différent." + +#: admin/wp-security-settings-menu.php:809 +#: admin/wp-security-settings-menu.php:818 +msgid "Export AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:815 +msgid "To export your All In One WP Security & Firewall settings click the button below." +msgstr "Pour exporter vos paramètres d’All-In-One WP Security & Firewall, cliquez le bouton ci-dessous." + +#: admin/wp-security-settings-menu.php:822 +#: admin/wp-security-settings-menu.php:851 +msgid "Import AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:828 +msgid "Use this section to import your All In One WP Security & Firewall settings from a file. Alternatively, copy/paste the contents of your import file into the textarea below." +msgstr "Utilisez cette section pour importer tous vos paramètres d’All In One WP Security & Firewall. Vous pouvez également copier / coller le contenu de votre fichier d’importation dans la zone de texte ci-dessous." + +#: admin/wp-security-settings-menu.php:830 +msgid "Import file" +msgstr "Importer le fichier" + +#: admin/wp-security-settings-menu.php:833 +msgid "Select Your Import Settings File" +msgstr "" + +#: admin/wp-security-settings-menu.php:837 +msgid "After selecting your file, click the button below to apply the settings to your site." +msgstr "Après avoir sélectionné votre fichier, cliquez le bouton ci-dessous pour appliquer les paramètres à votre site." + +#: admin/wp-security-settings-menu.php:844 +msgid "Copy/Paste import data" +msgstr "Copier / coller les données importées" + +#: admin/wp-security-settings-menu.php:893 +msgid "Default - if correct, then this is the best option" +msgstr "" + +#: admin/wp-security-settings-menu.php:894 +msgid "Only use if you're using Cloudflare." +msgstr "" + +#: admin/wp-security-settings-menu.php:902 +msgid "(current value: %s)" +msgstr "" + +#: admin/wp-security-settings-menu.php:905 +msgid "no value (i.e. empty) on your server" +msgstr "" + +#: admin/wp-security-spam-menu.php:28 +msgid "Comment spam" +msgstr "Commentaire SPAM" + +#: admin/wp-security-spam-menu.php:29 +msgid "Comment spam IP monitoring" +msgstr "Surveillance IP commentaires SPAM" + +#: admin/wp-security-spam-menu.php:30 +msgid "BuddyPress" +msgstr "BuddyPress" + +#: admin/wp-security-spam-menu.php:31 +msgid "bbPress" +msgstr "" + +#: admin/wp-security-spam-menu.php:57 +msgid "Spam prevention" +msgstr "Prévention du SPAM" + +#: admin/wp-security-spam-menu.php:99 +msgid "You entered a non numeric value for the \"move spam comments to trash after number of days\" field." +msgstr "" + +#: admin/wp-security-spam-menu.php:99 +#: admin/wp-security-spam-menu.php:297 +#: admin/wp-security-user-login-menu.php:118 +#: admin/wp-security-user-login-menu.php:124 +#: admin/wp-security-user-login-menu.php:130 +#: admin/wp-security-user-login-menu.php:136 +msgid "It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:129 +msgid "Comment spam settings" +msgstr "Paramètres commentaires SPAM" + +#: admin/wp-security-spam-menu.php:134 +msgid "Add CAPTCHA to comments form" +msgstr "Ajouter un Captcha au formulaire de commentaires" + +#: admin/wp-security-spam-menu.php:138 +msgid "This feature will add a CAPTCHA field in the WordPress comments form." +msgstr "" + +#: admin/wp-security-spam-menu.php:139 +msgid "Adding a CAPTCHA field in the comment form is a simple way of greatly reducing spam comments from bots without using .htaccess rules." +msgstr "L’ajout d’un champ Captcha dans le formulaire de commentaire est un moyen simple de réduire grandement le SPAM de commentaires contre les robots collecteurs sans utiliser les règles .htaccess." + +#: admin/wp-security-spam-menu.php:148 +msgid "Enable CAPTCHA on comment forms" +msgstr "Activer le Captcha sur les formulaires de commentaire" + +#: admin/wp-security-spam-menu.php:151 +msgid "Check this if you want to insert a CAPTCHA field on the comment forms." +msgstr "Cochez si vous souhaitez insérer un champ Captcha sur les formulaires de commentaires" + +#: admin/wp-security-spam-menu.php:158 +msgid "Block spambot comments" +msgstr "Bloquer les commentaires de spambots" + +#: admin/wp-security-spam-menu.php:162 +msgid "A large portion of WordPress blog comment spam is mainly produced by automated bots and not necessarily by humans." +msgstr "" + +#: admin/wp-security-spam-menu.php:163 +msgid "This feature will greatly minimize the useless and unecessary traffic and load on your server resulting from spam comments by blocking all comment requests which do not originate from your domain." +msgstr "Cette fonctionnalité va considérablement réduire le trafic et les chargements inutiles sur votre serveur dus aux SPAM de commentaires en bloquant toutes les demandes de commentaire qui ne proviennent pas de votre domaine." + +#: admin/wp-security-spam-menu.php:164 +msgid "In other words, if the comment was not submitted by a human who physically submitted the comment on your site, the request will be blocked." +msgstr "En d’autres termes, si le commentaire n’était pas présenté physiquement par un humain sur votre site, il sera bloqué." + +#: admin/wp-security-spam-menu.php:182 +msgid "Block spambots from posting comments" +msgstr "Bloquer le Spambot postant un commentaire" + +#: admin/wp-security-spam-menu.php:185 +msgid "Check this if you want to apply a firewall rule which will block comments originating from spambots." +msgstr "Cochez cette case pour appliquer une règle de pare-feu permettant de bloquer les commentaires provenant des spambots." + +#: admin/wp-security-spam-menu.php:189 +msgid "This feature will implement a firewall rule to block all comment attempts which do not originate from your domain." +msgstr "Cette fonction mettra en œuvre une règle de pare-feu pour bloquer toutes tentatives de commentaire qui ne provient pas de votre domaine." + +#: admin/wp-security-spam-menu.php:190 +msgid "A legitimate comment is one which is submitted by a human who physically fills out the comment form and clicks the submit button. For such events, the HTTP_REFERRER is always set to your own domain." +msgstr "Un commentaire légitime est celui qui est présenté par un humain qui physiquement remplit le formulaire de commentaire et clique sur le bouton « Soumettre ». Pour de tels événements, le HTTP_REFERRER est toujours positionné sur votre propre nom de domaine." + +#: admin/wp-security-spam-menu.php:191 +msgid "A comment submitted by a spambot is done by directly calling the comments.php file, which usually means that the HTTP_REFERRER value is not your domain and often times empty." +msgstr "Un commentaire présenté par un spambot se fait en appelant directement le fichier comments.php, ce qui signifie généralement que la valeur HTTP_REFERRER n’est pas votre domaine et est le plus souvent vide." + +#: admin/wp-security-spam-menu.php:192 +msgid "This feature will check and block comment requests which are not referred by your domain thus greatly reducing your overall blog spam and PHP requests done by the server to process these comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:202 +msgid "Comment processing" +msgstr "" + +#: admin/wp-security-spam-menu.php:207 +msgid "Trash spam comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:216 +msgid "Move spam comments to trash after %s days." +msgstr "" + +#: admin/wp-security-spam-menu.php:224 +msgid "Enble this feature in order to move the spam comments to trash after given number of days." +msgstr "" + +#: admin/wp-security-spam-menu.php:262 +msgid "You entered a non numeric value for the minimum number of spam comments field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:265 +msgid "You must enter an integer greater than zero for minimum number of spam comments field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:292 +msgid "Nonce check failed for list spam comment IPs." +msgstr "Échec du contrôle ponctuel pour voir les IPs des Spammeurs de commentaire !" + +#: admin/wp-security-spam-menu.php:297 +msgid "You entered a non numeric value for the minimum spam comments per IP field." +msgstr "" + +#: admin/wp-security-spam-menu.php:308 +msgid "Displaying results for IP addresses which have posted a minimum of %s spam comments." +msgstr "Afficher les résultats d’adresses IP qui ont posté un minimum de %s commentaires indésirables" + +#: admin/wp-security-spam-menu.php:323 +msgid "Auto block spammer IPs" +msgstr "" + +#: admin/wp-security-spam-menu.php:328 +msgid "This feature has detected that %s is not active. It is highly recommended that you activate the Akismet plugin to make the most of this feature." +msgstr "" + +#: admin/wp-security-spam-menu.php:337 +msgid "This feature allows you to automatically and permanently block IP addresses which have exceeded a certain number of comments labelled as spam." +msgstr "" + +#: admin/wp-security-spam-menu.php:338 +msgid "Comments are usually labelled as spam either by the Akismet plugin or manually by the WP administrator when they mark a comment as \"spam\" from the WordPress Comments menu." +msgstr "" + +#: admin/wp-security-spam-menu.php:352 +msgid "You currently have no IP addresses permanently blocked due to spam." +msgstr "" + +#: admin/wp-security-spam-menu.php:365 +msgid "Spammer IPs added to permanent block list today: " +msgstr "" + +#: admin/wp-security-spam-menu.php:366 +msgid "All time total: " +msgstr "" + +#: admin/wp-security-spam-menu.php:367 +msgid "View blocked IPs" +msgstr "" + +#: admin/wp-security-spam-menu.php:380 +msgid "Enable auto block of spam comment IPs" +msgstr "" + +#: admin/wp-security-spam-menu.php:383 +msgid "Check this box if you want this plugin to automatically block IP addresses which submit spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:387 +msgid "Minimum number of spam comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:389 +msgid "Specify the minimum number of spam comments for an IP address before it is permanently blocked." +msgstr "" + +#: admin/wp-security-spam-menu.php:393 +msgid "Example 1: Setting this value to \"1\" will block ALL IP addresses which were used to submit at least one spam comment." +msgstr "" + +#: admin/wp-security-spam-menu.php:394 +msgid "Example 2: Setting this value to \"5\" will block only those IP addresses which were used to submit 5 spam comments or more on your site." +msgstr "" + +#: admin/wp-security-spam-menu.php:412 +msgid "List spammer IP addresses" +msgstr "Liste des adresses IP de Spammeurs" + +#: admin/wp-security-spam-menu.php:416 +msgid "This section displays a list of the IP addresses of the people or bots who have left spam comments on your site." +msgstr "" + +#: admin/wp-security-spam-menu.php:417 +msgid "This information can be handy for identifying the most persistent IP addresses or ranges used by spammers." +msgstr "Cette information peut être utile pour identifier les adresses IP ou plages les plus tenaces utilisées par les spammeurs." + +#: admin/wp-security-spam-menu.php:418 +msgid "By inspecting the IP address data coming from spammers you will be in a better position to determine which addresses or address ranges you should block by adding them to the permanent block list." +msgstr "" + +#: admin/wp-security-spam-menu.php:419 +msgid "To add one or more of the IP addresses displayed in the table below to your blacklist, simply click the \"Block\" link for the individual row or select more than one address using the checkboxes and then choose the \"block\" option from the Bulk Actions dropdown list and click the \"Apply\" button." +msgstr "" + +#: admin/wp-security-spam-menu.php:427 +msgid "Minimum number of spam comments per IP" +msgstr "Nombre minimal de commentaires SPAM par IP" + +#: admin/wp-security-spam-menu.php:429 +msgid "This field allows you to list only those IP addresses which have been used to post X or more spam comments." +msgstr "Ce champ vous permet d’énumérer uniquement les adresses IP qui ont été utilisés pour un (ou davantage de) commentaire SPAM." + +#: admin/wp-security-spam-menu.php:433 +msgid "Example 1: Setting this value to \"0\" or \"1\" will list ALL IP addresses which were used to submit spam comments." +msgstr "Exemple 1 : Définition de cette valeur à « 0 » ou « 1 » listera toutes les adresses IP ayant été utilisés pour soumettre des commentaires SPAMmés." + +#: admin/wp-security-spam-menu.php:434 +msgid "Example 2: Setting this value to \"5\" will list only those IP addresses which were used to submit 5 spam comments or more on your site." +msgstr "Exemple 2 : Définir cette valeur à « 5 » listera uniquement les adresses IP qui ont été utilisés pour présenter 5 commentaires SPAM ou plus sur votre site." + +#: admin/wp-security-spam-menu.php:441 +msgid "Find IP addresses" +msgstr "Trouver les adresses IP" + +#: admin/wp-security-spam-menu.php:445 +msgid "Spammer IP address results" +msgstr "Liste des adresses IP de spammeurs" + +#: admin/wp-security-spam-menu.php:451 +#: classes/wp-security-utility.php:253 +msgid "The plugin has detected that you are using a Multi-Site WordPress installation." +msgstr "L’extension a détecté que vous utilisez une installation multi-site WordPress." + +#: admin/wp-security-spam-menu.php:452 +msgid "Only the \"superadmin\" can block IP addresses from the main site." +msgstr "Seul le « super Admin » peut bloquer les adresses IP à partir du site principal." + +#: admin/wp-security-spam-menu.php:453 +msgid "Take note of the IP addresses you want blocked and ask the superadmin to add these to the blacklist using the \"Blacklist Manager\" on the main site." +msgstr "Prenez note des adresses IP que vous voulez bloquer et demandez au « super Admin » de les ajouter à la liste noire en utilisant le « gestionnaire de liste noire » sur le site principal." + +#: admin/wp-security-spam-menu.php:498 +msgid "BuddyPress spam settings" +msgstr "Paramétrage anti-SPAM de BuddyPress" + +#: admin/wp-security-spam-menu.php:503 +msgid "Add CAPTCHA to BuddyPress registration form" +msgstr "Ajouter un Captcha sur le formulaire d’inscription à BuddyPress" + +#: admin/wp-security-spam-menu.php:507 +msgid "This feature will add a simple math CAPTCHA field in the BuddyPress registration form." +msgstr "Cette fonctionnalité va ajouter un champ Captcha arithmétique simple dans le formulaire d’inscription à BuddyPress." + +#: admin/wp-security-spam-menu.php:508 +msgid "Adding a CAPTCHA field in the registration form is a simple way of greatly reducing spam signups from bots without using .htaccess rules." +msgstr "L’ajout d’un champ Captcha dans le formulaire de commentaire est un moyen simple de réduire grandement les formulaires SPAM contrant ainsi les robots collecteurs sans pour autant utiliser les règles .htaccess." + +#: admin/wp-security-spam-menu.php:518 +msgid "Enable CAPTCHA on BuddyPress registration form" +msgstr "Activer un Captcha sur le formulaire d’inscription à BuddyPress" + +#: admin/wp-security-spam-menu.php:521 +msgid "Check this if you want to insert a CAPTCHA field on the BuddyPress registration forms." +msgstr "Case à cocher pour insérer un champ Captcha sur le formulaire d’enregistrement de BuddyPress" + +#: admin/wp-security-spam-menu.php:530 +msgid "BuddyPress is not active! In order to use this feature you will need to have BuddyPress installed and activated." +msgstr "BuddyPress est pas actif ! Pour utiliser cette fonctionnalité, vous devez avoir BuddyPress installé et activé." + +#: admin/wp-security-spam-menu.php:560 +msgid "bbPress spam settings" +msgstr "" + +#: admin/wp-security-spam-menu.php:565 +msgid "Add CAPTCHA to bbPress new topic form" +msgstr "" + +#: admin/wp-security-spam-menu.php:569 +msgid "This feature will add a simple math CAPTCHA field in the bbPress new topic form." +msgstr "" + +#: admin/wp-security-spam-menu.php:570 +msgid "Adding a CAPTCHA field in this form is a simple way of greatly reducing spam submitted from bots." +msgstr "" + +#: admin/wp-security-spam-menu.php:580 +msgid "Enable CAPTCHA on bbPress new topic form" +msgstr "" + +#: admin/wp-security-spam-menu.php:583 +msgid "Check this if you want to insert a CAPTCHA field on the bbPress new topic forms." +msgstr "" + +#: admin/wp-security-spam-menu.php:592 +msgid "bbPress is not active. In order to use this feature you will need to have bbPress installed and activated." +msgstr "" + +#: admin/wp-security-tools-menu.php:34 +msgid "WHOIS lookup" +msgstr "Consultation WHOIS" + +#: admin/wp-security-tools-menu.php:95 +#: admin/wp-security-tools-menu.php:136 +msgid "Querying %s: %s" +msgstr "" + +#: admin/wp-security-tools-menu.php:103 +#: admin/wp-security-tools-menu.php:112 +#: admin/wp-security-tools-menu.php:151 +msgid "Redirected to %s" +msgstr "" + +#: admin/wp-security-tools-menu.php:173 +msgid "The WHOIS lookup feature gives you a way to look up who owns an IP address or domain name." +msgstr "" + +#: admin/wp-security-tools-menu.php:173 +msgid "You can use this to investigate users engaging in malicious activity on your site." +msgstr "" + +#: admin/wp-security-tools-menu.php:176 +msgid "WHOIS lookup on IP or domain" +msgstr "" + +#: admin/wp-security-tools-menu.php:183 +msgid "IP address or domain name:" +msgstr "" + +#: admin/wp-security-tools-menu.php:190 +msgid "Look up IP or domain" +msgstr "" + +#: admin/wp-security-tools-menu.php:219 +msgid "Please enter a valid IP address or domain name to look up." +msgstr "" + +#: admin/wp-security-tools-menu.php:220 +#: admin/wp-security-tools-menu.php:226 +msgid "Nothing to show." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:32 +msgid "WP username" +msgstr "Nom d’utilisateur WP" + +#: admin/wp-security-user-accounts-menu.php:33 +msgid "Display name" +msgstr "Nom affiché" + +#: admin/wp-security-user-accounts-menu.php:34 +msgid "Password" +msgstr "Mot de passe" + +#: admin/wp-security-user-accounts-menu.php:60 +msgid "User accounts" +msgstr "Comptes utilisateur" + +#: admin/wp-security-user-accounts-menu.php:82 +msgid "Admin user security" +msgstr "Sécurité d’Administrateur" + +#: admin/wp-security-user-accounts-menu.php:85 +msgid "By default, WordPress sets the administrator username to \"admin\" at installation time." +msgstr "Par défaut, WordPress définit l’ID administrateur comme « Admin » au moment de l’installation." + +#: admin/wp-security-user-accounts-menu.php:86 +msgid "A lot of hackers try to take advantage of this information by attempting \"Brute force login attacks\" where they repeatedly try to guess the password by using \"admin\" for username." +msgstr "Un grand nombre de pirates tentent de tirer profit de ces informations en tentant des attaques « Brute Force Connexion » où ils tentent à plusieurs reprises de découvrir le mot de passe en utilisant « Admin » comme nom d’utilisateur." + +#: admin/wp-security-user-accounts-menu.php:87 +msgid "From a security perspective, changing the default \"admin\" user name is one of the first and smartest things you should do on your site." +msgstr "Du point de vue sécurité, changer le nom par défaut de l'utilisateur « Admin » est une des premières et des plus intelligentes choses à faire sur votre site." + +#: admin/wp-security-user-accounts-menu.php:88 +msgid "This feature will allow you to change your default \"admin\" user name to a more secure name of your choosing." +msgstr "Cette fonctionnalité permet de changer le nom d'utilisateur « Admin » par défaut pour un ID plus sûr de votre choix." + +#: admin/wp-security-user-accounts-menu.php:95 +msgid "List of administrator accounts" +msgstr "Liste des comptes administrateur" + +#: admin/wp-security-user-accounts-menu.php:104 +#: classes/grade-system/wp-security-feature-item-manager.php:43 +msgid "Change admin username" +msgstr "Changement du nom d’utilisateur Administrateur" + +#: admin/wp-security-user-accounts-menu.php:112 +msgid "Your site currently has an account which uses the default \"admin\" username. It is highly recommended that you change this name to something else. Use the following field to change the admin username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:118 +msgid "New admin username" +msgstr "Nouvel ID d’utilisateur administrateur" + +#: admin/wp-security-user-accounts-menu.php:120 +msgid "Choose a new username for admin." +msgstr "Choisissez un nouveau nom d’utilisateur admin." + +#: admin/wp-security-user-accounts-menu.php:124 +msgid "Change username" +msgstr "Changer d’ID d’utilisateur" + +#: admin/wp-security-user-accounts-menu.php:126 +msgid "NOTE: If you are currently logged in as \"admin\" you will be automatically logged out after changing your username and will be required to log back in." +msgstr "NOTE: Si vous êtes actuellement connecté en tant qu’ »Admin », vous serez automatiquement déconnecté après avoir changé votre nom d’utilisateur et celui-ci sera nécessaire pour rouvrir une session." + +#: admin/wp-security-user-accounts-menu.php:133 +msgid "No action required! " +msgstr "Aucune action n’est requise!" + +#: admin/wp-security-user-accounts-menu.php:135 +msgid "Your site does not have any account which uses the default \"admin\" username. " +msgstr "Votre site n’a pas de compte utilisant la valeur par défaut « Admin » comme nom d’utilisateur." + +#: admin/wp-security-user-accounts-menu.php:136 +msgid "This is good security practice." +msgstr "Ceci est une bonne pratique de sécurité." + +#: admin/wp-security-user-accounts-menu.php:148 +msgid "Display name security" +msgstr "Sécurité de nom d’affichage" + +#: admin/wp-security-user-accounts-menu.php:151 +msgid "When you submit a post or answer a comment, WordPress will usually display your \"nickname\"." +msgstr "Lorsque vous envoyez un message ou répondez à un commentaire WordPress, il sera affiché en tant que « pseudo »." + +#: admin/wp-security-user-accounts-menu.php:152 +msgid "By default the nickname is set to the login (or user) name of your account." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:153 +msgid "From a security perspective, leaving your nickname the same as your user name is bad practice because it gives a hacker at least half of your account's login credentials." +msgstr "Du point de vue de la sécurité, donner votre vrai nom comme nom d'utilisateur est une très mauvaise pratique, car il donne à un pirate la moitié au moins des identifiants de connexion à votre compte." + +#: admin/wp-security-user-accounts-menu.php:154 +msgid "Therefore to further tighten your site's security you are advised to change your nickname and Display name to be different from your Username." +msgstr "Par conséquent, pour resserrer davantage la sécurité de votre site, il est conseillé de changer votre pseudo et nom d’affichage pour qu’il soit différent de votre nom d’utilisateur." + +#: admin/wp-security-user-accounts-menu.php:160 +msgid "Modify accounts with identical login name and display name" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:169 +msgid "Your site currently has the following accounts which have an identical login name and display name." +msgstr "Votre site a actuellement les comptes suivants avec un nom d’utilisateur et le nom d’affichage identiques." + +#: admin/wp-security-user-accounts-menu.php:170 +msgid "Follow the link to edit the user profile of that particular user account, change Nickname, choose a different Display name compared to Username, and press the \"Update User\" button.)" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:185 +msgid "No action required." +msgstr "Aucune action n’est requise." + +#: admin/wp-security-user-accounts-menu.php:186 +msgid "Your site does not have a user account where the display name is identical to the username." +msgstr "Votre site ne contient pas de compte utilisateur dont le nom d’affichage et d’utilisateur sont identiques." + +#: admin/wp-security-user-accounts-menu.php:197 +msgid "Password tool" +msgstr "Outil Mot de passe" + +#: admin/wp-security-user-accounts-menu.php:200 +msgid "Poor password selection is one of the most common weak points of many sites and is usually the first thing a hacker will try to exploit when attempting to break into your site." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:201 +msgid "Many people fall into the trap of using a simple word or series of numbers as their password. Such a predictable and simple password would take a competent hacker merely minutes to guess your password by using a simple script which cycles through the easy and most common combinations." +msgstr "Beaucoup de gens tombent dans le piège de l’utilisation d’un simple mot ou série de numéros comme mot de passe. Un tel mot de passe prévisible et simple ne prendra que quelques minutes à un hacker compétent pour deviner votre mot de passe en utilisant un script simple qui balaye des combinaisons faciles et les plus courantes." + +#: admin/wp-security-user-accounts-menu.php:202 +msgid "The longer and more complex your password is the harder it is for hackers to \"crack\" because more complex passwords require much greater computing power and time." +msgstr "Plus long et complexe sera votre mot de passe, plus il sera difficile aux pirates informatiques de le « cracker » parce que les mots de passe complexes nécessitent une beaucoup plus grande puissance de calcul et de temps, ce qu’ils rechignent à mettre en œuvre [NdT]." + +#: admin/wp-security-user-accounts-menu.php:203 +msgid "This section contains a useful password strength tool which you can use to check whether your password is sufficiently strong enough." +msgstr "Cette section contient un analyseur de mots de passe que vous pouvez utiliser pour vérifier si le mot choisi est suffisamment robuste." + +#: admin/wp-security-user-accounts-menu.php:208 +msgid "Password strength tool" +msgstr "Outil de robustesse de mot de passe" + +#: admin/wp-security-user-accounts-menu.php:210 +msgid "This password tool uses an algorithm which calculates how long it would take for your password to be cracked using the computing power of an off-the-shelf current model desktop PC with high end processor, graphics card and appropriate password cracking software." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:213 +msgid "Start typing a password." +msgstr "Commencez à saisir un mot de passe." + +#: admin/wp-security-user-accounts-menu.php:216 +msgid "It would take a desktop PC approximately" +msgstr "Il faudrait à un PC de bureau environ" + +#: admin/wp-security-user-accounts-menu.php:217 +msgid "1 sec" +msgstr "1 Seconde" + +#: admin/wp-security-user-accounts-menu.php:217 +msgid "to crack your password!" +msgstr "pour casser ce mot de passe !" + +#: admin/wp-security-user-accounts-menu.php:222 +msgid "Password Strength" +msgstr "Complexité du mot de passe" + +#: admin/wp-security-user-accounts-menu.php:245 +msgid "Username " +msgstr "Nom d’utilisateur" + +#: admin/wp-security-user-accounts-menu.php:245 +msgid " already exists. Please enter another value. " +msgstr "existe déjà sur le site. Veuillez entrer une autre valeur." + +#: admin/wp-security-user-accounts-menu.php:262 +msgid "The database update operation of the user account failed!" +msgstr "La mise à jour en BdD du compte utilisateur a échoué !" + +#: admin/wp-security-user-accounts-menu.php:291 +msgid "You entered an invalid username. Please enter another value. " +msgstr "Vous avez saisi un nom d’utilisateur invalide. Veuillez choisir une autre valeur." + +#: admin/wp-security-user-accounts-menu.php:295 +msgid "Please enter a value for your username. " +msgstr "Veuillez entrer une valeur comme nom d’utilisateur." + +#: admin/wp-security-user-accounts-menu.php:302 +msgid "Username successfully changed." +msgstr "Nom d’utilisateur changé avec succès !" + +#: admin/wp-security-user-accounts-menu.php:322 +msgid "Account login name" +msgstr "Nom de connexion du compte" + +#: admin/wp-security-user-accounts-menu.php:331 +msgid "Edit user" +msgstr "" + +#: admin/wp-security-user-login-menu.php:54 +#: admin/wp-security-user-login-menu.php:474 +msgid "Failed login records" +msgstr "Registre des connexions échouées" + +#: admin/wp-security-user-login-menu.php:55 +#: classes/grade-system/wp-security-feature-item-manager.php:51 +msgid "Force logout" +msgstr "Forcer la déconnexion" + +#: admin/wp-security-user-login-menu.php:56 +#: admin/wp-security-user-login-menu.php:632 +msgid "Account activity logs" +msgstr "Journaux d’activité du compte" + +#: admin/wp-security-user-login-menu.php:58 +#: admin/wp-security-user-login-menu.php:769 +msgid "Additional settings" +msgstr "" + +#: admin/wp-security-user-login-menu.php:81 +msgid "User login" +msgstr "Connexion" + +#: admin/wp-security-user-login-menu.php:118 +msgid "You entered a non-numeric value for the max login attempts field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:124 +msgid "You entered a non numeric value for the login retry time period field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:130 +msgid "You entered a non numeric value for the lockout time length field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:136 +msgid "You entered a non numeric value for the maximim lockout time length field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:141 +msgid "You entered an invalid minimum lockout time length, it must be less than the maximum lockout time length value." +msgstr "" + +#: admin/wp-security-user-login-menu.php:141 +msgid "Both have been set to the default values." +msgstr "" + +#: admin/wp-security-user-login-menu.php:160 +msgid "Please fill in one or more email addresses to notify." +msgstr "" + +#: admin/wp-security-user-login-menu.php:162 +msgid "You have entered one or more invalid email addresses." +msgstr "" + +#: admin/wp-security-user-login-menu.php:165 +msgid "It has been set to your WordPress admin email as default." +msgstr "" + +#: admin/wp-security-user-login-menu.php:250 +msgid "Login lockout configuration" +msgstr "" + +#: admin/wp-security-user-login-menu.php:254 +msgid "One of the ways hackers try to compromise sites is via a " +msgstr "L’un des moyens par lesquels les pirates cherchent à pénétrer les sites est" + +#: admin/wp-security-user-login-menu.php:254 +msgid "Brute force login attack" +msgstr "l’attaque « Brute Force » de connexion" + +#: admin/wp-security-user-login-menu.php:254 +msgid "This is where attackers use repeated login attempts until they guess the password." +msgstr "Où les attaquants utilisent les tentatives de connexion répétées jusqu’à ce que le duo nom utilisateur + mot de passe fonctionne." + +#: admin/wp-security-user-login-menu.php:255 +msgid "Apart from choosing strong passwords, monitoring and blocking IP addresses which are involved in repeated login failures in a short period of time is a very effective way to stop these types of attacks." +msgstr "Outre le choix de mots de passe forts, la surveillance et le blocage d’adresses IP qui sont impliquées dans les échecs répétés de connexion en un court laps de temps est un moyen très efficace pour arrêter ce type d’attaques." + +#: admin/wp-security-user-login-menu.php:256 +msgid "You may also want to checkout our %s feature for another secure way to protect against these types of attacks." +msgstr "Vous pouvez également tester notre fonctionnalité de %s comme autre moyen sûr de protection contre ce type d’attaques." + +#: admin/wp-security-user-login-menu.php:261 +msgid "Login lockout options" +msgstr "" + +#: admin/wp-security-user-login-menu.php:272 +msgid "Enable login lockout feature" +msgstr "" + +#: admin/wp-security-user-login-menu.php:275 +msgid "Check this if you want to enable the login lockout feature and apply the settings below" +msgstr "" + +#: admin/wp-security-user-login-menu.php:279 +msgid "Allow unlock requests" +msgstr "Autoriser les requêtes de déverrouillage" + +#: admin/wp-security-user-login-menu.php:282 +msgid "Check this if you want to allow users to generate an automated unlock request link which will unlock their account" +msgstr "Cochez si vous voulez autoriser les utilisateurs à générer une demande de lien de déverrouillage automatique les autorisant à se connecter de nouveau" + +#: admin/wp-security-user-login-menu.php:286 +msgid "Max login attempts" +msgstr "Nombre maximal de tentatives de connexion échouées" + +#: admin/wp-security-user-login-menu.php:288 +msgid "Set the value for the maximum login retries before IP address is locked out" +msgstr "Réglez le nombre maxi de tentatives de connexion avant que l’adresse IP ne soit verrouillée" + +#: admin/wp-security-user-login-menu.php:292 +msgid "Login retry time period (min)" +msgstr "Durée (min) entre les tentatives de connexion" + +#: admin/wp-security-user-login-menu.php:294 +msgid "If the maximum number of failed login attempts for a particular IP address occur within this time period the plugin will lock out that address" +msgstr "Si le nombre maximum de tentatives de connexion infructueuses pour une adresse IP particulière se produit pendant cette période de temps, l’extension la verrouille automatiquement" + +#: admin/wp-security-user-login-menu.php:299 +msgid "Minimum lockout time length" +msgstr "" + +#: admin/wp-security-user-login-menu.php:305 +msgid "Set the minimum time period in minutes of lockout." +msgstr "" + +#: admin/wp-security-user-login-menu.php:306 +msgid "This failed login lockout time will be tripled on each failed login." +msgstr "" + +#: admin/wp-security-user-login-menu.php:313 +msgid "Maximum lockout time length" +msgstr "" + +#: admin/wp-security-user-login-menu.php:318 +msgid "Set the maximum time period in minutes of lockout." +msgstr "" + +#: admin/wp-security-user-login-menu.php:319 +msgid "No IP address will be blocked for more than this time period after making a failed login attempt." +msgstr "" + +#: admin/wp-security-user-login-menu.php:324 +msgid "Display generic error message" +msgstr "Afficher un message d’erreur générique" + +#: admin/wp-security-user-login-menu.php:327 +msgid "Check this if you want to show a generic error message when a login attempt fails" +msgstr "Cochez pour afficher un message d’erreur générique lorsqu’une tentative de connexion a échoué" + +#: admin/wp-security-user-login-menu.php:331 +msgid "Instantly lockout invalid usernames" +msgstr "Verrouillage instantané en cas d’ID utilisateur invalide" + +#: admin/wp-security-user-login-menu.php:334 +msgid "Check this if you want to instantly lockout login attempts with usernames which do not exist on your system" +msgstr "Cochez si vous voulez verrouiller instantanément une tentative de connexion avec une ID d’utilisateur inexistante sur votre système" + +#: admin/wp-security-user-login-menu.php:339 +msgid "Instantly lockout specific usernames" +msgstr "" + +#: admin/wp-security-user-login-menu.php:349 +msgid "Insert one username per line. Existing usernames are not blocked even if present in the list." +msgstr "" + +#: admin/wp-security-user-login-menu.php:354 +msgid "Notify by email" +msgstr "Notifier par courriel" + +#: admin/wp-security-user-login-menu.php:358 +msgid "Check this if you want to receive an email when someone has been locked out due to maximum failed login attempts" +msgstr "Cochez si vous souhaitez recevoir un courriel lorsque quelqu’un a été bloqué suite à un maximum de tentatives de connexion infructueuses" + +#: admin/wp-security-user-login-menu.php:361 +msgid "Fill in one email address per line." +msgstr "" + +#: admin/wp-security-user-login-menu.php:365 +msgid "Each email address must be on a new line." +msgstr "" + +#: admin/wp-security-user-login-menu.php:366 +msgid "If a valid email address has not been filled in, it will not be saved." +msgstr "" + +#: admin/wp-security-user-login-menu.php:367 +msgid "The valid email address format is userid@example.com" +msgstr "" + +#: admin/wp-security-user-login-menu.php:368 +msgid "Example: %s" +msgstr "" + +#: admin/wp-security-user-login-menu.php:375 +msgid "Enable PHP backtrace in email" +msgstr "" + +#: admin/wp-security-user-login-menu.php:379 +msgid "Check this if you want to include the PHP backtrace in notification emails." +msgstr "" + +#: admin/wp-security-user-login-menu.php:379 +msgid "This is internal coding information which makes it easier to investigate where an issued occurred." +msgstr "" + +#: admin/wp-security-user-login-menu.php:389 +msgid "Currently locked out IP address ranges" +msgstr "Plages d’adresses IP actuellement verrouillées" + +#: admin/wp-security-user-login-menu.php:394 +msgid "To see a list of all locked IP addresses and ranges go to the %s tab in the dashboard menu." +msgstr "Pour voir une liste de toutes les adresses et plages d’adresses IP bloquées, aller à l’onglet de %s dans le menu du tableau de bord." + +#: admin/wp-security-user-login-menu.php:399 +msgid "Login lockout IP whitelist settings" +msgstr "" + +#: admin/wp-security-user-login-menu.php:405 +msgid "Enable login lockout IP whitelist" +msgstr "" + +#: admin/wp-security-user-login-menu.php:416 +msgid "The addresses specified here will never be blocked by the login lockout feature." +msgstr "" + +#: admin/wp-security-user-login-menu.php:450 +msgid "User login feature - Delete all failed login records operation failed." +msgstr "Fonctions de connexion utilisateur - L’opération de purge des enregistrement de tentatives de connexions infructueuses a échoué !" + +#: admin/wp-security-user-login-menu.php:452 +msgid "All records from the failed logins table were deleted successfully." +msgstr "Tous les enregistrements de la table des tentatives de connexions infructueuses ont été supprimés avec succès !" + +#: admin/wp-security-user-login-menu.php:467 +msgid "This tab displays the failed login attempts for your site." +msgstr "Cet onglet affiche les tentatives de connexion infructueuses sur votre site." + +#: admin/wp-security-user-login-menu.php:468 +msgid "The information below can be handy if you need to do security investigations because it will show you the IP range, username and ID (if applicable) and the time/date of the failed login attempt." +msgstr "L’information ci-dessous peut être utile si vous avez besoin de faire des enquêtes de sécurité, car elle va vous montrer la plage d’IP, nom d’utilisateur et ID (le cas échéant) et la durée / date de la tentative de connexion infructueuse." + +#: admin/wp-security-user-login-menu.php:469 +msgid "Failed login records that are older than %1$d days are purged automatically." +msgstr "" + +#: admin/wp-security-user-login-menu.php:508 +#: admin/wp-security-user-login-menu.php:517 +msgid "Delete all failed login records" +msgstr "Purger les enregistrements de connexions infructueuses" + +#: admin/wp-security-user-login-menu.php:514 +msgid "Click this button if you wish to delete all failed login records in one go." +msgstr "Cliquez ce bouton si vous souhaitez purger les enregistrements de connexions infructueuses en une seule fois." + +#: admin/wp-security-user-login-menu.php:544 +msgid "You entered a non numeric value for the logout time period field. It has been set to the default value." +msgstr "Valeur non conforme pour la période de neutralisation de relance de connexion. Elle été fixée à sa valeur par défaut." + +#: admin/wp-security-user-login-menu.php:569 +msgid "Setting an expiry period for your WP administration session is a simple way to protect against unauthorized access to your site from your computer." +msgstr "Fixer un délai d’expiration de votre session d’administration WP est un moyen simple de se protéger contre l’accès non autorisé à votre site à partir de votre ordinateur." + +#: admin/wp-security-user-login-menu.php:570 +msgid "This feature allows you to specify a time period in minutes after which the admin session will expire and the user will be forced to log back in." +msgstr "Cette fonction permet de spécifier une période (en min) au bout de laquelle la session Admin expire, l’utilisateur étant forcé de se reconnecter." + +#: admin/wp-security-user-login-menu.php:575 +msgid "Force user logout options" +msgstr "Option forçage de déconnexion de l’utilisateur" + +#: admin/wp-security-user-login-menu.php:587 +msgid "Enable force WP user logout" +msgstr "Activer le forçage de déconnexion de l’utilisateur WP" + +#: admin/wp-security-user-login-menu.php:590 +msgid "Check this if you want to force a wp user to be logged out after a configured amount of time" +msgstr "Cochez si vous voulez forcer un utilisateur WP à être déconnecté après un laps temps configuré" + +#: admin/wp-security-user-login-menu.php:594 +msgid "Logout the WP user after XX minutes" +msgstr "Déconnecter l’utilisateur WP après XX Minutes" + +#: admin/wp-security-user-login-menu.php:596 +msgid "(Minutes) The user will be forced to log back in after this time period has elapased." +msgstr "(Minutes) L’utilisateur sera forcé de se reconnecter après que ce laps de temps soit passé." + +#: admin/wp-security-user-login-menu.php:625 +msgid "This tab displays the activity for accounts registered with your site that have logged in using the WordPress login form." +msgstr "" + +#: admin/wp-security-user-login-menu.php:626 +msgid "The information below can be handy if you need to do security investigations because it will show you the last 100 recent login events by username, IP address and time/date." +msgstr "" + +#: admin/wp-security-user-login-menu.php:627 +msgid "Account activity logs that are older than %1$d days are purged automatically." +msgstr "" + +#: admin/wp-security-user-login-menu.php:697 +msgid "Refresh logged in user data" +msgstr "Recharger les données d'utilisateur connecté" + +#: admin/wp-security-user-login-menu.php:701 +msgid "Refresh data" +msgstr "Actualiser les données" + +#: admin/wp-security-user-login-menu.php:706 +msgid "This tab displays all users who are currently logged into your site." +msgstr "Cet onglet affiche tous les utilisateurs actuellement connectés à votre site." + +#: admin/wp-security-user-login-menu.php:707 +msgid "If you suspect there is a user or users who are logged in which should not be, you can block them by inspecting the IP addresses from the data below and adding them to your blacklist." +msgstr "Si vous suspectez qu'un(des) utilisateur(s) connecté(s) ne le devrai(en)t pas, vous pouvez le(s) bloquer en inspectant l'(es )adresse(s) IP à partir des données ci-dessous et de l'(es )ajouter à votre liste noire." + +#: admin/wp-security-user-login-menu.php:708 +msgid "You can also instantly log them out by clicking on the \"Force logout\" link when you hover over the row in the user id column." +msgstr "" + +#: admin/wp-security-user-login-menu.php:713 +msgid "Currently logged in users" +msgstr "Utilisateurs actuellement connectés" + +#: admin/wp-security-user-login-menu.php:761 +msgid "WordPress 5.6 introduced a new feature called \"Application passwords\"." +msgstr "" + +#: admin/wp-security-user-login-menu.php:762 +msgid "This allows you to create a token from the WordPress dashboard which then can be used in the authorization header." +msgstr "" + +#: admin/wp-security-user-login-menu.php:763 +msgid "This feature allows you to disable application passwords as they can leave your site vulnerable to social engineering and phishing scams." +msgstr "" + +#: admin/wp-security-user-login-menu.php:780 +#: classes/grade-system/wp-security-feature-item-manager.php:53 +msgid "Disable application password" +msgstr "" + +#: admin/wp-security-user-login-menu.php:783 +msgid "Check this if you want to disable the application password." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:27 +msgid "Manual approval" +msgstr "Approbation manuelle" + +#: admin/wp-security-user-registration-menu.php:28 +#: classes/grade-system/wp-security-feature-item-manager.php:59 +msgid "Registration CAPTCHA" +msgstr "Captcha d’inscription" + +#: admin/wp-security-user-registration-menu.php:29 +msgid "Registration honeypot" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:55 +msgid "User registration" +msgstr "Enregistrement de l’utilisateur" + +#: admin/wp-security-user-registration-menu.php:115 +msgid "User registration settings" +msgstr "Paramètres d’inscription utilisateur" + +#: admin/wp-security-user-registration-menu.php:119 +msgid "Manually approve new registrations" +msgstr "Approuver manuellement les nouvelles inscriptions" + +#: admin/wp-security-user-registration-menu.php:123 +msgid "If your site allows people to create their own accounts via the WordPress registration form, then you can minimize spam or bogus registrations by manually approving each registration." +msgstr "Si votre site permet au visiteur de créer son propre compte via le formulaire d’inscription WordPress, vous pouvez réduire le SPAM ou les fausses inscriptions en approuvant manuellement chaque inscription." + +#: admin/wp-security-user-registration-menu.php:124 +msgid "This feature will automatically set a newly registered account to \"pending\" until the administrator activates it. Therefore undesirable registrants will be unable to log in without your express approval." +msgstr "Cette fonction permet de programmer automatiquement un compte nouvellement enregistré « en attente » jusqu’à ce qu’un administrateur l’active. Par conséquent les inscrits indésirables seront incapables de se connecter sans une autorisation expresse." + +#: admin/wp-security-user-registration-menu.php:125 +msgid "You can view all accounts which have been newly registered via the handy table below and you can also perform bulk activation/deactivation/deletion tasks on each account." +msgstr "Vous pouvez voir tous les comptes nouvellement enregistrés via la table ci-dessous et vous pouvez également effectuer des tâches d’activation / désactivation / suppression en masse de chaque compte." + +#: admin/wp-security-user-registration-menu.php:142 +msgid "Enable manual approval of new registrations" +msgstr "Activer l’approbation manuelle des nouvelles inscriptions" + +#: admin/wp-security-user-registration-menu.php:145 +msgid "Check this if you want to automatically disable all newly registered accounts so that you can approve them manually." +msgstr "Cochez si vous souhaitez désactiver automatiquement tous les comptes nouvellement créés, de sorte que vous puissiez les approuver manuellement." + +#: admin/wp-security-user-registration-menu.php:154 +msgid "Approve registered users" +msgstr "Approbation des utilisateurs enregistrés" + +#: admin/wp-security-user-registration-menu.php:206 +msgid "This feature allows you to add a CAPTCHA form on the WordPress registration page." +msgstr "Cette fonctionnalité permet d’ajouter un formulaire Captcha sur la page de connexion de WordPress." + +#: admin/wp-security-user-registration-menu.php:207 +msgid "Users who attempt to register will also need to enter the answer to a simple mathematical question - if they enter the wrong answer, the plugin will not allow them to register." +msgstr "Les utilisateurs tentant de s'enregistrer devront également répondre à une question arithmétique simple, si elles entrent une mauvaise réponse, l'extension ne leur permettra pas d'enregistrer leur demande." + +#: admin/wp-security-user-registration-menu.php:208 +msgid "Therefore, adding a CAPTCHA form on the registration page is another effective yet simple spam registration prevention technique." +msgstr "Donc, l'ajout d'un formulaire de Captcha sur la page d'inscription est une autre technique efficace et simple de prévention du SPAM d'inscription." + +#: admin/wp-security-user-registration-menu.php:212 +msgid "Registration page CAPTCHA settings" +msgstr "Paramètres du Captcha de page d'inscription" + +#: admin/wp-security-user-registration-menu.php:219 +msgid "The core default behaviour for WordPress Multi Site regarding user registration is that all users are registered via the main site." +msgstr "Le comportement de base par défaut pour l’enregistrement des utilisateur sous WordPress Multi Site est que tous soient enregistrés via le site principal." + +#: admin/wp-security-user-registration-menu.php:220 +msgid "Therefore, if you would like to add a CAPTCHA form to the registration page for a Multi Site, please go to \"Registration CAPTCHA\" settings on the main site." +msgstr "Par conséquent, si vous souhaitez ajouter un formulaire de Captcha à la page d’inscription pour un multi site, veuillez aller dans les paramètres « Captcha d’enregistrement » sur le site principal." + +#: admin/wp-security-user-registration-menu.php:235 +msgid "Enable CAPTCHA on registration page" +msgstr "Activer le Captcha sur la page d’inscription" + +#: admin/wp-security-user-registration-menu.php:238 +msgid "Check this if you want to insert a CAPTCHA form on the WordPress user registration page (if you allow user registration)." +msgstr "Cochez cette case pour insérer un Captcha sur la page d’inscription de l’utilisateur WordPress (si vous permettez l’enregistrement des utilisateurs)." + +#: admin/wp-security-user-registration-menu.php:276 +msgid "This feature allows you to add a special hidden \"honeypot\" field on the WordPress registration page. This will only be visible to robots and not humans." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:277 +msgid "Since robots usually fill in every input field from a registration form, they will also submit a value for the special hidden honeypot field." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:279 +msgid "Therefore, if the plugin detects that this field has a value when the registration form is submitted, then the robot which is attempting to register on your site will be redirected to its localhost address - http://127.0.0.1." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:285 +msgid "Registration form honeypot settings" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:296 +msgid "Enable honeypot on registration page" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:299 +msgid "Check this if you want to enable the honeypot feature for the registration page" +msgstr "" + +#: classes/aios-ajax.php:89 +msgid "Invalid IP retrieve method." +msgstr "" + +#: classes/aios-ajax.php:131 +#: wp-security-core.php:258 +msgid "The security check failed; try refreshing the page." +msgstr "" + +#: classes/aios-ajax.php:152 +#: wp-security-core.php:268 +msgid "You are not allowed to run this command." +msgstr "" + +#: classes/aios-ajax.php:173 +#: wp-security-core.php:282 +msgid "Options can only be saved by network admin" +msgstr "" + +#: classes/aios-ajax.php:202 +msgid "The command \"%s\" was not found" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:39 +msgid "Remove WP generator meta tag" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:45 +msgid "Change display name" +msgstr "Changer nom d’affichage" + +#: classes/grade-system/wp-security-feature-item-manager.php:57 +msgid "Registration approval" +msgstr "Approbation d’inscription" + +#: classes/grade-system/wp-security-feature-item-manager.php:61 +msgid "Enable registration honeypot" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:73 +msgid "WordPress files access" +msgstr "Accès aux fichiers WordPress" + +#: classes/grade-system/wp-security-feature-item-manager.php:77 +msgid "IP and user agent blacklisting" +msgstr "IP ou ID d’utilisateur en liste noire" + +#: classes/grade-system/wp-security-feature-item-manager.php:81 +msgid "Enable basic firewall" +msgstr "Activer la protection de base du pare-feu" + +#: classes/grade-system/wp-security-feature-item-manager.php:82 +msgid "Enable pingback vulnerability protection" +msgstr "Activer la protection contre les pingback" + +#: classes/grade-system/wp-security-feature-item-manager.php:83 +msgid "Block accesss to debug log file" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:87 +msgid "Forbid proxy comments" +msgstr "Interdire les commentaires de proxy" + +#: classes/grade-system/wp-security-feature-item-manager.php:88 +msgid "Deny bad queries" +msgstr "Refuser les requêtes douteuses" + +#: classes/grade-system/wp-security-feature-item-manager.php:91 +msgid "5G/6G blacklist" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:97 +msgid "Enable IP blocking for 404 detection" +msgstr "Activer le verrouillage IP pour les événements 404" + +#: classes/grade-system/wp-security-feature-item-manager.php:101 +msgid "Enable rename login page" +msgstr "Activer le renommage de la page de Connexion" + +#: classes/grade-system/wp-security-feature-item-manager.php:106 +msgid "Lost password CAPTCHA" +msgstr "Mot de passe de Captcha perdu" + +#: classes/grade-system/wp-security-feature-item-manager.php:107 +msgid "Custom login CAPTCHA" +msgstr "Captcha de connexion personnalisé" + +#: classes/grade-system/wp-security-feature-item-manager.php:108 +msgid "Woo login CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:109 +msgid "Woo lost password CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:110 +msgid "Woo register CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:112 +msgid "Login IP whitelisting" +msgstr "Connexion IP en liste blanche" + +#: classes/grade-system/wp-security-feature-item-manager.php:114 +msgid "Enable login honeypot" +msgstr "Activer la connexion Honeypot" + +#: classes/grade-system/wp-security-feature-item-manager.php:118 +msgid "Comment CAPTCHA" +msgstr "Captcha de commentaire" + +#: classes/grade-system/wp-security-feature-item-manager.php:119 +msgid "Block spambots" +msgstr "Bloquer les Spambots" + +#: classes/grade-system/wp-security-feature-item-manager.php:121 +msgid "BuddyPress registration CAPTCHA" +msgstr "Captcha d'inscription BuddyPress" + +#: classes/grade-system/wp-security-feature-item-manager.php:123 +msgid "bbPress new topic CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item.php:29 +msgid "Basic" +msgstr "Information" + +#: classes/grade-system/wp-security-feature-item.php:31 +msgid "Intermediate" +msgstr "Intermédiaire" + +#: classes/grade-system/wp-security-feature-item.php:33 +msgid "Advanced" +msgstr "Avancée" + +#: classes/wp-security-captcha.php:47 +#: classes/wp-security-general-init-tasks.php:407 +msgid "Please enter an answer in digits:" +msgstr "Saisissez votre réponse en chiffres" + +#: classes/wp-security-captcha.php:127 +msgid "one" +msgstr "un" + +#: classes/wp-security-captcha.php:128 +msgid "two" +msgstr "deux" + +#: classes/wp-security-captcha.php:129 +msgid "three" +msgstr "trois" + +#: classes/wp-security-captcha.php:130 +msgid "four" +msgstr "quatre" + +#: classes/wp-security-captcha.php:131 +msgid "five" +msgstr "cinq" + +#: classes/wp-security-captcha.php:132 +msgid "six" +msgstr "six" + +#: classes/wp-security-captcha.php:133 +msgid "seven" +msgstr "sept" + +#: classes/wp-security-captcha.php:134 +msgid "eight" +msgstr "huit" + +#: classes/wp-security-captcha.php:135 +msgid "nine" +msgstr "neuf" + +#: classes/wp-security-captcha.php:136 +msgid "ten" +msgstr "dix" + +#: classes/wp-security-captcha.php:137 +msgid "eleven" +msgstr "onze" + +#: classes/wp-security-captcha.php:138 +msgid "twelve" +msgstr "douze" + +#: classes/wp-security-captcha.php:139 +msgid "thirteen" +msgstr "treize" + +#: classes/wp-security-captcha.php:140 +msgid "fourteen" +msgstr "quatorze" + +#: classes/wp-security-captcha.php:141 +msgid "fifteen" +msgstr "quinze" + +#: classes/wp-security-captcha.php:142 +msgid "sixteen" +msgstr "seize" + +#: classes/wp-security-captcha.php:143 +msgid "seventeen" +msgstr "dix-sept" + +#: classes/wp-security-captcha.php:144 +msgid "eighteen" +msgstr "dix-huit" + +#: classes/wp-security-captcha.php:145 +msgid "nineteen" +msgstr "dix-neuf" + +#: classes/wp-security-captcha.php:146 +msgid "twenty" +msgstr "vingt" + +#: classes/wp-security-cronjob-handler.php:34 +msgid "Every 15 minutes" +msgstr "" + +#: classes/wp-security-debug-logger.php:46 +msgid "Unable to get the reason why" +msgstr "" + +#: classes/wp-security-debug-logger.php:47 +msgid "Unable to clear the logs" +msgstr "" + +#: classes/wp-security-file-scan.php:85 +msgid "All In One WP Security - File change detected!" +msgstr "All In One WP Security - Changement détecté dans les fichiers !" + +#: classes/wp-security-file-scan.php:87 +msgid "A file change was detected on your system for site URL" +msgstr "Un changement dans les fichiers a été détecté sur votre système à l’URL" + +#: classes/wp-security-file-scan.php:87 +msgid ". Scan was generated on" +msgstr ". Un balayage a été généré sur" + +#: classes/wp-security-file-scan.php:88 +msgid "A summary of the scan results is shown below:" +msgstr "" + +#: classes/wp-security-file-scan.php:91 +msgid "Login to your site to view the scan details." +msgstr "Connectez-vous à votre site pour voir les détails du balayage." + +#: classes/wp-security-file-scan.php:313 +msgid "The following files were added to your host" +msgstr "Les fichiers suivants ont été ajoutés à votre hôte :" + +#: classes/wp-security-file-scan.php:315 +#: classes/wp-security-file-scan.php:323 +#: classes/wp-security-file-scan.php:332 +msgid "modified on: " +msgstr "" + +#: classes/wp-security-file-scan.php:321 +msgid "The following files were removed from your host" +msgstr "Les fichiers suivants ont été supprimés de votre hôte :" + +#: classes/wp-security-file-scan.php:330 +msgid "The following files were changed on your host" +msgstr "Les fichiers suivants ont été modifiés sur votre hôte :" + +#: classes/wp-security-general-init-tasks.php:212 +#: classes/wp-security-general-init-tasks.php:481 +msgid "Application passwords have been disabled by All In One WP Security & Firewall plugin." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:428 +#: classes/wp-security-general-init-tasks.php:541 +#: classes/wp-security-general-init-tasks.php:574 +#: classes/wp-security-user-login.php:137 +#: classes/wp-security-user-registration.php:74 +msgid "ERROR: Your answer was incorrect - please try again." +msgstr "ERREUR: La réponse à la question est incorrecte –veuillez réessayer" + +#: classes/wp-security-general-init-tasks.php:463 +msgid "Enter something special:" +msgstr "Entrez quelque chose de spécial :" + +#: classes/wp-security-general-init-tasks.php:476 +msgid "Application passwords" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:485 +msgid "Change setting" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:487 +msgid "Site admin can only change this setting." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:516 +msgid "Error: You entered an incorrect CAPTCHA answer. Please go back and try again." +msgstr "Erreur : réponse CAPTCHA incorrecte. Réessayez." + +#: classes/wp-security-general-init-tasks.php:558 +msgid "Your CAPTCHA answer was incorrect - please try again." +msgstr "Réponse Captcha incorrecte - Veuillez réessayer" + +#: classes/wp-security-general-init-tasks.php:567 +msgid "ERROR: Your IP address is currently locked please contact the administrator!" +msgstr "" + +#. translators: %s: Admin Dashboard > WP Security > Brute Force > Login CAPTCHA Tab Link +#: classes/wp-security-general-init-tasks.php:642 +msgid "Your Google reCAPTCHA site key is wrong. Please fill the correct reCAPTCHA keys %s to use the Google reCAPTCHA feature." +msgstr "" + +#. translators: %s: Admin Dashboard > WP Security > Brute Force > Login CAPTCHA Tab Link +#: classes/wp-security-general-init-tasks.php:642 +#: classes/wp-security-notices.php:99 +msgid "here" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +msgid "Would you like All In One WP Security & Firewall to re-insert the security rules in your .htaccess file which were cleared when you deactivated the plugin?" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +#: templates/may-also-like.php:40 +#: templates/may-also-like.php:43 +#: templates/may-also-like.php:54 +#: templates/may-also-like.php:57 +#: templates/may-also-like.php:68 +#: templates/may-also-like.php:71 +#: templates/may-also-like.php:91 +#: templates/may-also-like.php:103 +#: templates/may-also-like.php:115 +#: templates/may-also-like.php:127 +#: templates/may-also-like.php:139 +#: templates/may-also-like.php:151 +#: templates/may-also-like.php:168 +#: templates/may-also-like.php:171 +#: templates/may-also-like.php:183 +#: templates/may-also-like.php:195 +#: templates/may-also-like.php:207 +#: templates/may-also-like.php:219 +#: templates/may-also-like.php:231 +#: templates/may-also-like.php:243 +#: templates/may-also-like.php:252 +#: templates/may-also-like.php:255 +#: templates/may-also-like.php:264 +#: templates/may-also-like.php:267 +#: templates/may-also-like.php:279 +#: templates/may-also-like.php:297 +#: templates/may-also-like.php:309 +#: templates/may-also-like.php:327 +#: templates/may-also-like.php:339 +#: templates/may-also-like.php:351 +#: templates/may-also-like.php:368 +#: templates/may-also-like.php:380 +msgid "Yes" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +#: templates/may-also-like.php:88 +#: templates/may-also-like.php:100 +#: templates/may-also-like.php:112 +#: templates/may-also-like.php:124 +#: templates/may-also-like.php:136 +#: templates/may-also-like.php:148 +#: templates/may-also-like.php:180 +#: templates/may-also-like.php:192 +#: templates/may-also-like.php:204 +#: templates/may-also-like.php:216 +#: templates/may-also-like.php:228 +#: templates/may-also-like.php:240 +#: templates/may-also-like.php:276 +#: templates/may-also-like.php:294 +#: templates/may-also-like.php:306 +#: templates/may-also-like.php:324 +#: templates/may-also-like.php:336 +#: templates/may-also-like.php:348 +#: templates/may-also-like.php:365 +#: templates/may-also-like.php:377 +#: templates/notices/custom-notice.php:27 +msgid "No" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:674 +msgid "Your registration is pending approval." +msgstr "" + +#: classes/wp-security-notices.php:25 +msgid "The All in One Security plugin has disabled the login whitelist setting that you have enabled in the past." +msgstr "" + +#: classes/wp-security-notices.php:29 +msgid "Your website is running on an Apache webserver, the login whitelisting might not be functional until the recent update of AIOS (because it relied upon Apache-specific module features)." +msgstr "" + +#: classes/wp-security-notices.php:31 +msgid "Your website is running on a non-Apache webserver, so the login whitelisting was not functional until the recent update of AIOS (because it relied upon Apache-specific features)." +msgstr "" + +#: classes/wp-security-notices.php:33 +msgid "It began working with AIOS version 5.0.8." +msgstr "" + +#: classes/wp-security-notices.php:33 +msgid "We have disabled it so that your login page will not be blocked unexpectedly." +msgstr "" + +#: classes/wp-security-notices.php:42 +msgid "Would you like to re-enable login whitelisting?" +msgstr "" + +#: classes/wp-security-notices.php:48 +msgid "Removed database backup feature from the All In One WP Security & Firewall plugin" +msgstr "" + +#: classes/wp-security-notices.php:50 +msgid "Beginning with version 5.0.0, AIOS has replaced the AIOS backup method with the superior UpdraftPlus method." +msgstr "" + +#: classes/wp-security-notices.php:51 +msgid "It remains free and is fully supported by the UpdraftPlus team." +msgstr "" + +#: classes/wp-security-notices.php:54 +msgid "You are seeing this notice because you have previously set up automated database backups in AIOS." +msgstr "" + +#: classes/wp-security-notices.php:55 +msgid "Would you like to set up scheduled backups with UpdraftPlus?" +msgstr "" + +#: classes/wp-security-notices.php:61 +msgid "Setup UpdraftPlus backup plugin" +msgstr "" + +#: classes/wp-security-notices.php:67 +msgid "Important: set up your IP address detection settings" +msgstr "" + +#: classes/wp-security-notices.php:69 +msgid "The All in One Security plugin couldn't be certain about the correct method to detect the IP address for your site visitors with your currently-configured IP address detection settings." +msgstr "" + +#: classes/wp-security-notices.php:70 +msgid "It is important for your security to set the IP address detection settings properly." +msgstr "" + +#: classes/wp-security-notices.php:73 +msgid "Please go to the settings and set them now." +msgstr "" + +#: classes/wp-security-notices.php:79 +msgid "Setup IP address detection settings" +msgstr "" + +#: classes/wp-security-notices.php:85 +msgid "Important: Disabled login whitelist setting" +msgstr "" + +#: classes/wp-security-notices.php:91 +msgid "Turn it back on" +msgstr "" + +#: classes/wp-security-notices.php:92 +msgid "Edit the settings" +msgstr "" + +#: classes/wp-security-notices.php:95 +msgid "Keep it off" +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Hey - We noticed All In One WP Security & Firewall has kept your site safe for a while. If you like us, please consider leaving a positive review to spread the word. Or if you have any issues or questions please leave us a support message %s." +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Thank you so much!" +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Team All In One WP Security & Firewall" +msgstr "" + +#: classes/wp-security-notices.php:109 +msgid "Enhance your security even more by backing up your site" +msgstr "" + +#: classes/wp-security-notices.php:110 +msgid "UpdraftPlus is the world's most trusted backup plugin from the owners of All In One WP Security & Firewall" +msgstr "" + +#: classes/wp-security-notices.php:121 +msgid "After you've secured your site, we recommend you install our WP-Optimize plugin to streamline it for better website performance." +msgstr "" + +#: classes/wp-security-process-renamed-login-page.php:152 +msgid "Not available." +msgstr "" + +#: classes/wp-security-two-factor-login.php:34 +msgid "Two factor authentication - Admin settings" +msgstr "" + +#: classes/wp-security-two-factor-login.php:97 +msgid "Two Factor Auth" +msgstr "" + +#: classes/wp-security-two-factor-login.php:153 +msgid "PHP OpenSSL or mcrypt module required" +msgstr "" + +#: classes/wp-security-two-factor-login.php:153 +msgid "The All In One WP Security plugin's Two Factor Authentication module requires either the PHP openssl (preferred) or mcrypt module to be installed. Please ask your web hosting company to install one of them." +msgstr "" + +#: classes/wp-security-user-login.php:71 +msgid "You have disabled login lockout by defining the AIOS_DISABLE_LOGIN_LOCKOUT constant value as true, and the login lockout setting has enabled it." +msgstr "" + +#. translators: 1: Locked IP Addresses admin page link +#: classes/wp-security-user-login.php:73 +msgid "Delete your login lockout IP from %s and define the AIOS_DISABLE_LOGIN_LOCKOUT constant value as false." +msgstr "" + +#: classes/wp-security-user-login.php:100 +msgid "ERROR: Access from your IP address has been blocked for security reasons. Please contact the administrator." +msgstr "" + +#: classes/wp-security-user-login.php:108 +msgid "Service temporarily unavailable" +msgstr "" + +#: classes/wp-security-user-login.php:163 +msgid "ACCOUNT PENDING: Your account is currently not active. An administrator needs to activate your account before you can login." +msgstr "Compte en attente : Votre compte n'est pas actif actuellement. Un administrateur doit l'activer avant que vous ne puissiez vous connecter." + +#: classes/wp-security-user-login.php:242 +msgid "ERROR: Invalid login credentials." +msgstr "ERREUR : Identifiants de connexion invalides." + +#: classes/wp-security-user-login.php:392 +msgid "Site Lockout Notification" +msgstr "Notification de site verrouillé" + +#: classes/wp-security-user-login.php:393 +msgid "User login lockout events had occurred due to too many failed login attempts or invalid username:" +msgstr "" + +#: classes/wp-security-user-login.php:396 +msgid "Username:" +msgstr "" + +#: classes/wp-security-user-login.php:397 +msgid "IP address:" +msgstr "" + +#: classes/wp-security-user-login.php:399 +msgid "IP range:" +msgstr "" + +#: classes/wp-security-user-login.php:404 +msgid "Log into your site WordPress administration panel to see the duration of the lockout or to unlock the user." +msgstr "" + +#: classes/wp-security-user-login.php:515 +msgid "Unlock request notification" +msgstr "Notification de demande de déblocage" + +#: classes/wp-security-user-login.php:516 +msgid "You have requested for the account with email address %s to be unlocked. Please click the link below to unlock your account:" +msgstr "" + +#: classes/wp-security-user-login.php:516 +msgid "Unlock link: %s" +msgstr "" + +#: classes/wp-security-user-login.php:516 +msgid "After clicking the above link you will be able to login to the WordPress administration panel." +msgstr "Après avoir cliqué le lien ci-dessus, vous serez en mesure de vous connecter au panneau d'administration WordPress." + +#: classes/wp-security-user-login.php:739 +msgid "Your session has expired because it has been over %d minutes since your last login." +msgstr "Votre session a expiré (plus de %d minutes depuis votre connexion)." + +#: classes/wp-security-user-login.php:740 +#: classes/wp-security-user-login.php:744 +msgid "Please log back in to continue." +msgstr "Veuillez vous reconnecter pour continuer." + +#: classes/wp-security-user-login.php:743 +msgid "You were logged out because you just changed the \"admin\" username." +msgstr "Vous avez été déconnecté parce que vous venez de modifier le nom d’utilisateur « Admin »." + +#: classes/wp-security-user-login.php:773 +msgid "Request unlock" +msgstr "Recevoir un lien de déblocage." + +#: classes/wp-security-user-registration.php:68 +msgid "ERROR: You are not allowed to register because your IP address is currently locked!" +msgstr "" + +#: classes/wp-security-utility-ip-address.php:217 +#: classes/wp-security-utility-ip-address.php:231 +#: classes/wp-security-utility-ip-address.php:245 +#: classes/wp-security-utility-ip-address.php:257 +#: classes/wp-security-utility-ip-address.php:269 +msgid " is not a valid ip address format." +msgstr "n'est pas un format d'adresse IP valide." + +#: classes/wp-security-utility-ip-address.php:274 +msgid "You cannot ban your own IP address: " +msgstr "vous ne pouvez bannir votre propre adresse IP :" + +#: classes/wp-security-utility.php:254 +msgid "This feature can only be configured by the \"superadmin\" on the main site." +msgstr "ne peut être configuré(e) que par le « super Admin » sur le site principal." + +#: other-includes/wp-security-unlock-request.php:32 +msgid "ERROR: Unable to process your request!" +msgstr "" + +#: other-includes/wp-security-unlock-request.php:45 +msgid "Please enter a valid email address" +msgstr "Veuillez fournir une adresse courriel valide" + +#: other-includes/wp-security-unlock-request.php:57 +msgid "User account not found!" +msgstr "Compte utilisateur introuvable." + +#: other-includes/wp-security-unlock-request.php:71 +msgid "Error: No locked entry was found in the database with your IP address range." +msgstr "Erreur : Aucune entrée verrouillée n’a été trouvé dans la BdD avec votre plage d’IP !" + +#: other-includes/wp-security-unlock-request.php:76 +msgid "An email has been sent to you with the unlock instructions." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:93 +msgid "You are here because you have been locked out due to too many incorrect login attempts." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:94 +msgid "Please enter your email address and you will receive an email with instructions on how to unlock yourself." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:104 +msgid "Email Address" +msgstr "Email" + +#: other-includes/wp-security-unlock-request.php:108 +msgid "Send unlock request" +msgstr "" + +#: templates/admin/incompatible-plugin.php:6 +msgid "Two Factor Authentication" +msgstr "" + +#: templates/admin/incompatible-plugin.php:10 +msgid "Two Factor Authentication currently disabled" +msgstr "" + +#: templates/admin/incompatible-plugin.php:12 +#: templates/admin/incompatible-plugin.php:16 +msgid "Two factor authentication in All In One WP Security is currently disabled because the incompatible plugin %s is active." +msgstr "" + +#: templates/automated-database-backup.php:4 +msgid "Automated scheduled backups" +msgstr "Sauvegardes automatiques planifiées" + +#: templates/automated-database-backup.php:9 +msgid "Automate backup in the UpdraftPlus plugin" +msgstr "" + +#: templates/automated-database-backup.php:19 +msgid "The AIOS 5.0.0 version release has removed the automated backup feature." +msgstr "" + +#: templates/automated-database-backup.php:20 +msgid "The AIOS automated backup had issues that made it less robust than we could be happy with." +msgstr "" + +#: templates/automated-database-backup.php:21 +msgid "Follow this link to automate backups in the superior UpdraftPlus backup plugin." +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:5 +msgid "Each IP address must be on a new line." +msgstr "Chaque adresse IP doit figurer sur une nouvelle ligne." + +#: templates/info/ip-address-ip-range-info.php:6 +msgid "To specify an IPv4 range use a wildcard \"*\" character. Acceptable ways to use wildcards is shown in the examples below:" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:7 +msgid "Example 1: 195.47.89.*" +msgstr "Exemple 1 : 195.47.89.*" + +#: templates/info/ip-address-ip-range-info.php:8 +msgid "Example 2: 195.47.*.*" +msgstr "Exemple 2 : 195.47.*.*" + +#: templates/info/ip-address-ip-range-info.php:9 +msgid "Example 3: 195.*.*.*" +msgstr "Exemple 3 : 195.*.*.*" + +#: templates/info/ip-address-ip-range-info.php:10 +msgid "To specify an IPv6 range use CIDR format as shown in the examples below:" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:11 +msgid "Example 4: 2401:4900:54c3:af15:2:2:5dc0:0/112" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:12 +msgid "Example 5: 2001:db8:1263::/48" +msgstr "" + +#: templates/may-also-like.php:5 +msgid "All-In-One Security (AIOS) Free vs Premium Comparison Chart" +msgstr "" + +#: templates/may-also-like.php:7 +msgid "FAQs" +msgstr "" + +#: templates/may-also-like.php:9 +msgid "Ask a pre-sales question" +msgstr "" + +#: templates/may-also-like.php:17 +msgid "All In One WP Security & Firewall Free" +msgstr "" + +#: templates/may-also-like.php:26 +#: templates/may-also-like.php:386 +msgid "Installed" +msgstr "" + +#: templates/may-also-like.php:29 +#: templates/may-also-like.php:389 +msgid "Upgrade now" +msgstr "" + +#: templates/may-also-like.php:34 +msgid "Login security feature suite" +msgstr "" + +#: templates/may-also-like.php:35 +msgid "Protect against brute-force attacks and keep bots at bay." +msgstr "" + +#: templates/may-also-like.php:35 +msgid "AIOS takes WordPress' default login security features to a whole new level." +msgstr "" + +#: templates/may-also-like.php:37 +msgid "To see all login security features, visit %s" +msgstr "" + +#: templates/may-also-like.php:48 +msgid "Firewall and file protection feature suite" +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Protection from the latest exploits." +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Activate firewall settings ranging from basic, intermediate and advanced." +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Get comprehensive, instant protection with All-in-One Security." +msgstr "" + +#: templates/may-also-like.php:51 +msgid "To see all firewall and file protection features, visit %s" +msgstr "" + +#: templates/may-also-like.php:62 +msgid "Content protection feature suite" +msgstr "" + +#: templates/may-also-like.php:63 +msgid "Eliminate spam and protect your content to dramatically improve your website's interactions with search engines." +msgstr "" + +#: templates/may-also-like.php:65 +msgid "To see all content protection features, visit %s" +msgstr "" + +#: templates/may-also-like.php:76 +msgid "Malware scanning" +msgstr "" + +#: templates/may-also-like.php:77 +msgid "Finding out by accident that your site has been infected with malware is too late." +msgstr "" + +#: templates/may-also-like.php:79 +msgid "Malware can have a dramatic effect on your site's search rankings and you may not even know about it." +msgstr "" + +#: templates/may-also-like.php:79 +msgid "It can slow your website down, access customer data, send unsolicited emails, change your content or prevent users from accessing it." +msgstr "" + +#: templates/may-also-like.php:84 +msgid "Automatic malware scanning" +msgstr "" + +#: templates/may-also-like.php:85 +msgid "Best-in-class scanning for the latest malware, trojans and spyware 24/7." +msgstr "" + +#: templates/may-also-like.php:96 +msgid "Response time monitoring" +msgstr "" + +#: templates/may-also-like.php:97 +msgid "You'll know immediately if your website's response time is negatively affected." +msgstr "" + +#: templates/may-also-like.php:108 +msgid "Up-time monitoring" +msgstr "" + +#: templates/may-also-like.php:109 +msgid "AIOS checks your website's uptime every 5 minutes." +msgstr "" + +#: templates/may-also-like.php:109 +msgid "We'll notify you straight away if your site/server goes down." +msgstr "" + +#: templates/may-also-like.php:120 +msgid "Prevents blacklisting by search engines" +msgstr "" + +#: templates/may-also-like.php:121 +msgid "AIOS monitors your site's blacklist status daily." +msgstr "" + +#: templates/may-also-like.php:121 +msgid "We'll notify you within 24 hours if something's amiss so you can take action, before it's too late." +msgstr "" + +#: templates/may-also-like.php:132 +msgid "Flexible assignment" +msgstr "" + +#: templates/may-also-like.php:133 +msgid "Register and remove websites from the scanning service at any time." +msgstr "" + +#: templates/may-also-like.php:144 +msgid "Malware reports" +msgstr "" + +#: templates/may-also-like.php:145 +msgid "Reports are available via the 'My Account' page and directly via email." +msgstr "" + +#: templates/may-also-like.php:156 +msgid "Flexible two-factor authentication" +msgstr "" + +#: templates/may-also-like.php:157 +msgid "With Two-Factor Authentication (TFA) users enter their username and password and a one-time code sent to a device to login." +msgstr "" + +#: templates/may-also-like.php:159 +msgid "TFA is a feature in both our free and premium packages, but AIOS Premium affords whole new levels of control over how TFA is implemented." +msgstr "" + +#: templates/may-also-like.php:164 +msgid "Authenticator apps" +msgstr "" + +#: templates/may-also-like.php:165 +msgid "Supports TOTP and HOTP protocols." +msgstr "" + +#: templates/may-also-like.php:165 +msgid "TFA Can be used with Google Authenticator, Microsoft Authenticator, Authy and many more." +msgstr "" + +#: templates/may-also-like.php:176 +msgid "Role specific configuration" +msgstr "" + +#: templates/may-also-like.php:177 +msgid "Make it compulsory for certain roles e.g. for admin and editor roles." +msgstr "" + +#: templates/may-also-like.php:188 +msgid "Require TFA after a set time period" +msgstr "" + +#: templates/may-also-like.php:189 +msgid "For example you could require all admins to have TFA once their accounts are a week old." +msgstr "" + +#: templates/may-also-like.php:200 +msgid "Trusted devices - control how often TFA is required" +msgstr "" + +#: templates/may-also-like.php:201 +msgid "Ask for TFA after a chosen number of days for trusted devices instead of on every login." +msgstr "" + +#: templates/may-also-like.php:212 +msgid "Anti-bot protection" +msgstr "" + +#: templates/may-also-like.php:213 +msgid "Option to hide the existence of forms on WooCommerce login pages unless JavaScript is active." +msgstr "" + +#: templates/may-also-like.php:224 +msgid "Customise TFA design layout" +msgstr "" + +#: templates/may-also-like.php:225 +msgid "Customise the design of TFA so it aligns with your existing web design." +msgstr "" + +#: templates/may-also-like.php:236 +msgid "TFA emergency codes" +msgstr "" + +#: templates/may-also-like.php:237 +msgid "Generate a one-time use emergency code to allow access if your device is lost." +msgstr "" + +#: templates/may-also-like.php:248 +msgid "TFA multisite compatibility" +msgstr "" + +#: templates/may-also-like.php:249 +msgid "TFA is Compatible with multisite networks and sub-sites." +msgstr "" + +#: templates/may-also-like.php:260 +msgid "TFA support for common login forms" +msgstr "" + +#: templates/may-also-like.php:261 +msgid "Supports WooCommerce, Affiliates-WP and Theme my Login login forms." +msgstr "" + +#: templates/may-also-like.php:272 +msgid "TFA support for other login forms" +msgstr "" + +#: templates/may-also-like.php:273 +msgid "Supports Elementor Pro, bbPress and all third-party login forms without any further coding needed." +msgstr "" + +#: templates/may-also-like.php:284 +msgid "Smart 404 blocking" +msgstr "" + +#: templates/may-also-like.php:285 +msgid "404 errors can occur when someone legitimately mistypes a URL, but they're also generated by hackers searching for weaknesses in your site." +msgstr "" + +#: templates/may-also-like.php:290 +msgid "Automatically and permanently blocks bots producing 404s" +msgstr "" + +#: templates/may-also-like.php:291 +msgid "AIOS Premium provides more protection than the competition by automatically and permanently blocking IP addresses of bots and hackers based on how many 404 errors they generate." +msgstr "" + +#: templates/may-also-like.php:302 +msgid "404 error charts" +msgstr "" + +#: templates/may-also-like.php:303 +msgid "Handy charts keep you informed of how many 404s have occurred and which IP address or country is producing them." +msgstr "" + +#: templates/may-also-like.php:314 +msgid "Country blocking" +msgstr "" + +#: templates/may-also-like.php:315 +msgid "Most malicious attacks come from a handful of countries and so it's possible to prevent most attacks with our country blocking tool." +msgstr "" + +#: templates/may-also-like.php:320 +msgid "Block traffic based on country of origin" +msgstr "" + +#: templates/may-also-like.php:321 +msgid "AIOS Premium utilises an IP database that promises 99.5% accuracy." +msgstr "" + +#: templates/may-also-like.php:332 +msgid "Block traffic to specific pages based on country of origin" +msgstr "" + +#: templates/may-also-like.php:333 +msgid "Block access to your whole site or on a page-by-page basis." +msgstr "" + +#: templates/may-also-like.php:344 +msgid "Whitelist some users from blocked countries" +msgstr "" + +#: templates/may-also-like.php:345 +msgid "Whitelist IP addresses or IP ranges even if they are part of a blocked country." +msgstr "" + +#: templates/may-also-like.php:356 +msgid "Premium support" +msgstr "" + +#: templates/may-also-like.php:361 +msgid "Unlimited support" +msgstr "" + +#: templates/may-also-like.php:362 +msgid "Personalised, email support from our team of Security experts, as and when you need it." +msgstr "" + +#: templates/may-also-like.php:373 +msgid "Guaranteed response time" +msgstr "" + +#: templates/may-also-like.php:374 +msgid "We offer a guaranteed response time of three days." +msgstr "" + +#: templates/may-also-like.php:374 +msgid "99% of our Premium customers receive a response to their enquiry within 24 hours during the working week." +msgstr "" + +#: templates/may-also-like.php:397 +msgid "Our other plugins" +msgstr "" + +#: templates/may-also-like.php:411 +msgid "UpdraftPlus – the ultimate protection for your site, hard work and business" +msgstr "" + +#: templates/may-also-like.php:412 +msgid "Simplifies backups and restoration." +msgstr "" + +#: templates/may-also-like.php:412 +msgid "It is the world's highest ranking and most popular scheduled backup plugin, with over three million currently-active installs." +msgstr "" + +#: templates/may-also-like.php:413 +#: templates/may-also-like.php:419 +#: templates/may-also-like.php:425 +#: templates/may-also-like.php:431 +msgid "Try for free" +msgstr "" + +#: templates/may-also-like.php:417 +msgid "WP-Optimize – keep your database fast and efficient" +msgstr "" + +#: templates/may-also-like.php:418 +msgid "Makes your site fast and efficient." +msgstr "" + +#: templates/may-also-like.php:418 +msgid "It cleans the database, compresses images and caches pages for ultimate speed." +msgstr "" + +#: templates/may-also-like.php:423 +msgid "UpdraftCentral – save hours managing multiple WP sites from one place" +msgstr "" + +#: templates/may-also-like.php:424 +msgid "Highly efficient way to manage, optimize, update and backup multiple websites from one place." +msgstr "" + +#: templates/may-also-like.php:429 +msgid "Easy Updates Manager" +msgstr "" + +#: templates/may-also-like.php:430 +msgid "Keeps your WordPress site up to date and bug free." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:2 +msgid "IP address detection settings" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:6 +msgid "The IP address detection settings allow you to specify how visitors' IP addresses are made known to PHP (and hence to WordPress and its plugins)." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:7 +msgid "Usually, this is automatic and there is only one choice." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:8 +msgid "However in some setups, such as those using proxies (including load-balancers and security firewalls like Cloudflare), it may be necessary to set this manually." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "Attention" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "It is important to set this correctly - otherwise you may make it possible for a hacker to ban all your visitors (e.g. via banning Cloudflare from connecting to you) instead of being banned himself." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "The default is to use the REMOTE_ADDR PHP server variable. If this variable does not contain the visitor's IP address, then whilst you can make a different selection below, it is better to ask your web hosting company to have it correctly set." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:10 +msgid "This is the most secure setup, because when set correctly it is immune from being spoofed by an attacker." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:16 +msgid "You have no available IP address detection method(s); you must contact your web hosting company." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:22 +#: templates/menus/settings/advanced-settings.php:27 +#: templates/menus/settings/advanced-settings.php:32 +msgid "Your detected IP address according to %s:" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:38 +msgid "If your site is setup on localhost, you won't see your external IP address using your server's IP detection setting; but on a localhost-served site (not available to the outside world), the setting is irrelevant and can be ignored." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:61 +msgid "Choose a $_SERVER variable you would like to detect visitors' IP address using." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:67 +msgid "If your chosen server variable fails the plugin will automatically fall back to retrieving the IP address from $_SERVER[\"REMOTE_ADDR\"]" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:73 +msgid "Your IP address if using this setting:" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:75 +msgid "fetching..." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:81 +#: templates/menus/settings/advanced-settings.php:190 +msgid "getting..." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:89 +msgid "look-up possibly blocked by an ad-blocker or similar tool" +msgstr "" + +#: templates/notices/cookie-based-brute-force-prevention-disabled.php:4 +msgid "Cookie based brute force login prevention currently disabled" +msgstr "" + +#: templates/notices/cookie-based-brute-force-prevention-disabled.php:6 +msgid "Cookie based brute force login prevention is currently disabled via the AIOS_DISABLE_COOKIE_BRUTE_FORCE_PREVENTION constant (which is mostly likely to be defined in your wp-config.php)" +msgstr "" + +#: templates/notices/disable-login-whitelist.php:4 +msgid "Login whitelisting currently disabled" +msgstr "" + +#: templates/notices/disable-login-whitelist.php:6 +msgid "Login whitelisting is currently disabled via the AIOS_DISABLE_LOGIN_WHITELIST constant (which is mostly likely to be defined in your wp-config.php)" +msgstr "" + +#: templates/notices/horizontal-notice.php:8 +#: templates/notices/horizontal-notice.php:40 +msgid "notice image" +msgstr "" + +#: templates/notices/horizontal-notice.php:18 +msgid "Ok, you deserve it" +msgstr "" + +#: templates/notices/horizontal-notice.php:22 +msgid "Maybe later" +msgstr "" + +#: templates/notices/horizontal-notice.php:26 +msgid "Never" +msgstr "" + +#: templates/notices/horizontal-notice.php:66 +msgid "Get UpdraftCentral" +msgstr "" + +#: templates/notices/horizontal-notice.php:68 +msgid "Get UpdraftPlus" +msgstr "" + +#: templates/notices/horizontal-notice.php:70 +msgid "Get WP-Optimize" +msgstr "" + +#: templates/notices/horizontal-notice.php:72 +msgid "Find out more." +msgstr "" + +#: templates/notices/horizontal-notice.php:74 +msgid "Sign up" +msgstr "" + +#: templates/notices/horizontal-notice.php:76 +msgid "Go there" +msgstr "" + +#: templates/notices/horizontal-notice.php:78 +msgid "Read more" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:4 +msgid "Dismiss (for %s months)" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:6 +msgid "Thank you for installing All In One WP Security & Firewall!" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:13 +msgid "Super-charge and secure your WordPress site even more with our other top plugins:" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:17 +msgid "%s makes your site fast and efficient. It cleans the database, compresses images and caches pages for ultimate speed." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:21 +msgid "%s simplifies backups and restoration. It is the world's highest ranking and most popular scheduled backup plugin, with over three million currently-active installs." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:25 +msgid "%s is a highly efficient way to manage, optimize, update and backup multiple websites from one place." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:29 +msgid "%s is a WordPress subscription extension for WooCommerce store owners." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:33 +msgid "More quality plugins" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:33 +msgid "Premium WooCommerce plugins" +msgstr "" + +#: templates/partials/non-apache-feature-notice.php:9 +msgid "This feature works only on the Apache server." +msgstr "" + +#: templates/partials/non-apache-feature-notice.php:10 +msgid "You are using the non-apache server %s, so this feature won't work on your site." +msgstr "" + +#: wp-security-core.php:236 +#: wp-security.php:45 +msgid "This plugin requires PHP version %s." +msgstr "" + +#: wp-security-core.php:237 +msgid "Current site PHP version is %s." +msgstr "" + +#: wp-security-core.php:238 +#: wp-security.php:47 +msgid "You will need to ask your web hosting company to upgrade." +msgstr "" + +#: wp-security-core.php:397 +msgid "Error:" +msgstr "" + +#: wp-security-core.php:397 +msgid "template not found" +msgstr "" + +#: wp-security.php:44 +msgid "All In One WP Security and Firewall plugin has been deactivated." +msgstr "" + +#: wp-security.php:46 +msgid "Your current PHP version is %s." +msgstr "" diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-hu_HU.mo b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-hu_HU.mo new file mode 100755 index 0000000000000000000000000000000000000000..3114647c25dbc6f85de6fdf2843afe383579e977 GIT binary patch literal 1933 zcmZ{k&u<$=6vvlRez~^_B!m!py-_vm+DU+FlT>wFCoyRfD{%;*ifHT|ugANdwPwe5 zZK;S82q7e@3Lzv8_u?i(SZ6vWT^ z1+NpV;WzLh?2i$=3jPW1g0CUz6VL^1Fb0j@zhDmh4>WZyp}64{(CEGjnz+|N6ZaN~ zQ0qE)1uTFjZWT1^zXO`}R5Je_X!H)U`TL;BW1!LLX0`@RozF7==b*J3X%$NEcBx$6 zJKU{Pt+IQ!y1Ti0GxIz2QP@|+n$55;HHnCteWke6!H8t2F`>nP=cy!#xm_Uz@|X@4 zNzUDfbeKjk&1p0*)Znd9B|d60NkQldnLqEQvcJE#Ki5N54p<=EG>n>xyXZi$Ai6ju zZCge|u4u?260#Yh@unu5dI4tU!7*6EvbY4Ly$fR<=!W45rRRtwveyb_lb zl3V7LSRsrkNlD&`FA@(dJjqx?M7M=Xjke<4(nB6V6_9!agjP+39qfl)b?pzhibNK1oT+A18k2j7OhsI;9o9GOTeCRR zM~f@Ff-~U?={a<(A#|=5^c4&2jZk$Xhh#4?qqW5q92hgR_O_&JYgD|xlKar!R z-Jx2@U7@L%e>cC3nbfq`am0E|w;jsQoZEaf43!(*!##26_;}@*&n6EzQ_Xe_Id;Kh zonMEIYW#ScHsT*PH=lj8UfG?y86|3o_{{Gx>fjK`fP1)kU1GkDPX~FbcsSzey&P*5 zpJ4AL^U3EyU}D4|J_)2?3)B@nc=kwZYVaVQ^dz6%tgY&LX|7`Yr5eN&Int&c!jrn% z=i_)12^7Qk^)E~=k*Ua{F|~P+N!aAa6V-{I`U})k@mT{ASWg#AiJx>D@mY|!wnT$D zv~`{{y^on1{tvk!nnzBawlg(YvV#_JJfkrqw0EKWG-UxgS!p)yR8usLPr4oMjku4E zb1XRugQlg$n9I2#=2Kt%tG3J|z5TA~xb0;e7 UA~-=(+~-<9dj!{$Xl!N1|C(t&TL1t6 literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-hu_HU.po b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-hu_HU.po new file mode 100755 index 00000000..96a9555f --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-hu_HU.po @@ -0,0 +1,5991 @@ +msgid "" +msgstr "" +"Project-Id-Version: AIOWPS\n" +"POT-Creation-Date: 2013-12-03 12:53+1000\n" +"PO-Revision-Date: 2014-04-17 20:34+0100\n" +"Last-Translator: I♥WP \n" +"Language-Team: \n" +"Language: hu_HU\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 1.6.4\n" +"X-Poedit-Basepath: .\n" +"X-Poedit-KeywordsList: __;_e\n" +"X-Poedit-SearchPath-0: .\n" + +#. Plugin Name of the plugin +msgid "All In One WP Security" +msgstr "" + +#. Plugin URI of the plugin +msgid "https://wordpress.org/plugins/all-in-one-wp-security-and-firewall/" +msgstr "" + +#. Description of the plugin +msgid "All round best WordPress security plugin!" +msgstr "" + +#. Author of the plugin +msgid "All In One WP Security & Firewall Team" +msgstr "" + +#. Author URI of the plugin +msgid "https://teamupdraft.com/" +msgstr "" + +#: admin/general/wp-security-list-table.php:483 +msgid "Are you sure you want to perform this bulk action?" +msgstr "" + +#: admin/wp-security-admin-init.php:259 +msgid "Unexpected response:" +msgstr "" + +#: admin/wp-security-admin-init.php:290 +msgid "Enjoyed %1$s? Please leave us a %2$s rating. We really appreciate your support!" +msgstr "" + +#: admin/wp-security-admin-init.php:414 +#: classes/wp-security-two-factor-login.php:95 +msgid "WP Security" +msgstr "" + +#: admin/wp-security-admin-init.php:415 +#: admin/wp-security-dashboard-menu.php:26 +#: admin/wp-security-dashboard-menu.php:76 +msgid "Dashboard" +msgstr "" + +#: admin/wp-security-admin-init.php:416 +#: admin/wp-security-settings-menu.php:95 +msgid "Settings" +msgstr "" + +#: admin/wp-security-admin-init.php:417 +msgid "User Accounts" +msgstr "" + +#: admin/wp-security-admin-init.php:418 +msgid "User Login" +msgstr "" + +#: admin/wp-security-admin-init.php:419 +msgid "User Registration" +msgstr "" + +#: admin/wp-security-admin-init.php:420 +msgid "Database Security" +msgstr "" + +#: admin/wp-security-admin-init.php:424 +msgid "Filesystem Security" +msgstr "" + +#: admin/wp-security-admin-init.php:429 +msgid "Blacklist Manager" +msgstr "" + +#: admin/wp-security-admin-init.php:434 +#: admin/wp-security-firewall-menu.php:60 +msgid "Firewall" +msgstr "" + +#: admin/wp-security-admin-init.php:436 +msgid "Brute Force" +msgstr "" + +#: admin/wp-security-admin-init.php:437 +msgid "Spam Prevention" +msgstr "" + +#: admin/wp-security-admin-init.php:441 +#: admin/wp-security-filescan-menu.php:53 +msgid "Scanner" +msgstr "" + +#: admin/wp-security-admin-init.php:443 +#: admin/wp-security-maintenance-menu.php:51 +msgid "Maintenance" +msgstr "" + +#: admin/wp-security-admin-init.php:444 +#: admin/wp-security-misc-options-menu.php:57 +msgid "Miscellaneous" +msgstr "" + +#: admin/wp-security-admin-init.php:445 +#: admin/wp-security-tools-menu.php:64 +msgid "Tools" +msgstr "" + +#: admin/wp-security-admin-init.php:457 +msgid "Premium Upgrade" +msgstr "" + +#: admin/wp-security-admin-menu.php:67 +msgid "Settings successfully updated." +msgstr "" + +#: admin/wp-security-admin-menu.php:77 +msgid "Successfully deleted the selected record(s)." +msgstr "" + +#: admin/wp-security-admin-menu.php:86 +msgid "Failed to delete the selected record(s)." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:25 +msgid "Ban users" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:51 +msgid "Blacklist manager" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:132 +#: admin/wp-security-firewall-menu.php:1233 +#: admin/wp-security-list-404.php:234 +#: admin/wp-security-list-comment-spammer-ip.php:205 +msgid "The plugin was unable to write to the .htaccess file. Please edit file manually." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:139 +msgid "Ban IPs or user agents" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:142 +msgid "The All In One WP Security Blacklist feature gives you the option of banning certain host IP addresses or ranges and also user agents." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:143 +msgid "This feature will deny total site access for users which have IP addresses or user agents matching those which you have configured in the settings below." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:144 +msgid "The plugin achieves this by making appropriate modifications to your .htaccess file." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:145 +msgid "By blocking people, you are using the most secure first line of defence, which denies all access to blacklisted visitors as soon as they hit your hosting server." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:154 +#: admin/wp-security-firewall-menu.php:1055 +#: templates/may-also-like.php:20 +msgid "All In One WP Security & Firewall Premium" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:155 +#: admin/wp-security-firewall-menu.php:1056 +msgid "You may also be interested in %s." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "This plugin adds a number of extra features including %s and %s." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "smart 404 blocking" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "country IP blocking" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:170 +msgid "IP hosts and user agent blacklist settings" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:182 +#: admin/wp-security-brute-force-menu.php:193 +#: admin/wp-security-brute-force-menu.php:331 +msgid "must read this message" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:183 +#: admin/wp-security-brute-force-menu.php:194 +msgid "This feature can lock you out of admin if it doesn't work correctly on your site. You %s before activating this feature." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:189 +msgid "Enable IP or user agent blacklisting" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:192 +msgid "Check this if you want to enable the banning (or blacklisting) of selected IP addresses and/or user agents specified in the settings below" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:196 +msgid "Enter IP addresses:" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:200 +msgid "Enter one or more IP addresses or IP ranges." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:205 +msgid "Enter user agents:" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:210 +msgid "Enter one or more user agent strings." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:211 +#: admin/wp-security-brute-force-menu.php:374 +#: admin/wp-security-brute-force-menu.php:408 +#: admin/wp-security-brute-force-menu.php:431 +#: admin/wp-security-brute-force-menu.php:452 +#: admin/wp-security-filescan-menu.php:309 +#: admin/wp-security-filescan-menu.php:326 +#: admin/wp-security-firewall-menu.php:175 +#: admin/wp-security-firewall-menu.php:212 +#: admin/wp-security-firewall-menu.php:232 +#: admin/wp-security-firewall-menu.php:258 +#: admin/wp-security-firewall-menu.php:385 +#: admin/wp-security-firewall-menu.php:415 +#: admin/wp-security-firewall-menu.php:446 +#: admin/wp-security-firewall-menu.php:474 +#: admin/wp-security-firewall-menu.php:503 +#: admin/wp-security-firewall-menu.php:681 +#: admin/wp-security-firewall-menu.php:699 +#: admin/wp-security-firewall-menu.php:737 +#: admin/wp-security-firewall-menu.php:868 +#: admin/wp-security-firewall-menu.php:1087 +#: admin/wp-security-firewall-menu.php:1110 +#: admin/wp-security-spam-menu.php:186 +#: admin/wp-security-spam-menu.php:221 +#: admin/wp-security-spam-menu.php:390 +#: admin/wp-security-spam-menu.php:430 +#: admin/wp-security-user-login-menu.php:362 +#: templates/info/ip-address-ip-range-info.php:2 +#: templates/menus/settings/advanced-settings.php:63 +msgid "More info" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:214 +msgid "Each user agent string must be on a new line." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:215 +msgid "Example 1 - A single user agent string to block:" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:217 +msgid "Example 2 - A list of more than 1 user agent strings to block" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:225 +#: admin/wp-security-brute-force-menu.php:213 +#: admin/wp-security-brute-force-menu.php:686 +#: admin/wp-security-brute-force-menu.php:806 +#: admin/wp-security-brute-force-menu.php:868 +#: admin/wp-security-filescan-menu.php:351 +#: admin/wp-security-filesystem-menu.php:242 +#: admin/wp-security-firewall-menu.php:945 +#: admin/wp-security-firewall-menu.php:1129 +#: admin/wp-security-misc-options-menu.php:167 +#: admin/wp-security-misc-options-menu.php:218 +#: admin/wp-security-misc-options-menu.php:278 +#: admin/wp-security-settings-menu.php:619 +#: admin/wp-security-settings-menu.php:680 +#: admin/wp-security-spam-menu.php:233 +#: admin/wp-security-spam-menu.php:407 +#: admin/wp-security-spam-menu.php:526 +#: admin/wp-security-spam-menu.php:588 +#: admin/wp-security-user-login-menu.php:384 +#: admin/wp-security-user-login-menu.php:422 +#: admin/wp-security-user-login-menu.php:601 +#: admin/wp-security-user-login-menu.php:788 +#: admin/wp-security-user-registration-menu.php:150 +#: admin/wp-security-user-registration-menu.php:242 +#: admin/wp-security-user-registration-menu.php:305 +#: templates/menus/settings/advanced-settings.php:217 +msgid "Save settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:33 +#: admin/wp-security-brute-force-menu.php:759 +#: admin/wp-security-dashboard-menu.php:651 +msgid "Rename login page" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:34 +#: admin/wp-security-brute-force-menu.php:154 +msgid "Cookie based brute force prevention" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:35 +#: classes/grade-system/wp-security-feature-item-manager.php:105 +msgid "Login CAPTCHA" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:36 +#: admin/wp-security-brute-force-menu.php:746 +msgid "Login whitelist" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:37 +msgid "Honeypot" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:67 +msgid "Brute force" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:105 +msgid "Please enter a value for your login page slug." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:109 +msgid "You cannot use the value \"wp-admin\" for your login page slug." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:111 +msgid "You must use alpha numeric characters for your login page slug." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:116 +#: admin/wp-security-filescan-menu.php:174 +#: admin/wp-security-firewall-menu.php:151 +#: admin/wp-security-firewall-menu.php:1011 +#: admin/wp-security-spam-menu.php:101 +#: admin/wp-security-spam-menu.php:270 +#: admin/wp-security-spam-menu.php:302 +#: admin/wp-security-user-login-menu.php:184 +#: admin/wp-security-user-login-menu.php:553 +#: templates/partials/non-apache-feature-notice.php:9 +msgid "Attention:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:133 +msgid "Could not delete the Cookie-based directives from the .htaccess file. Please check the file permissions." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:155 +msgid "Login page white list" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:156 +msgid "An effective Brute Force prevention technique is to change the default WordPress login page URL." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:157 +msgid "Normally if you wanted to login to WordPress you would type your site's home URL followed by wp-login.php." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:158 +msgid "This feature allows you to change the login URL by setting your own slug and renaming the last portion of the login URL which contains the wp-login.php to any string that you like." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:159 +msgid "By doing this, malicious bots and hackers will not be able to access your login page because they will not know the correct login page URL." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:161 +msgid "You may also be interested in the following alternative brute force prevention features:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:172 +msgid "Your WordPress login page URL has been renamed." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:173 +msgid "Your current login URL is:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:181 +msgid "Rename login page settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:195 +msgid "NOTE: If you are hosting your site on WPEngine or a provider which performs server caching, you will need to ask the host support people to NOT cache your renamed login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:200 +msgid "Enable rename login page feature" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:203 +msgid "Check this if you want to enable the rename login page feature" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:207 +msgid "Login page URL" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:209 +msgid "Enter a string which will represent your secure login page slug. You are encouraged to choose something which is hard to guess and only you will remember." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:243 +msgid "Settings have not been saved - your secret word must consist only of alphanumeric characters, ie, letters and/or numbers only." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:257 +msgid "You have successfully enabled the cookie based brute force prevention feature" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:258 +msgid "From now on you will need to log into your WP Admin using the following URL:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:260 +msgid "It is important that you save this URL value somewhere in case you forget it, OR," +msgstr "" + +#: admin/wp-security-brute-force-menu.php:261 +msgid "simply remember to add a \"?%s=1\" to your current site URL address." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:265 +msgid "You have successfully saved cookie based brute force prevention feature settings." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:295 +msgid "Brute force prevention firewall settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:300 +msgid "A Brute Force Attack is when a hacker tries many combinations of usernames and passwords until they succeed in guessing the right combination." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:301 +msgid "Due to the fact that at any one time there may be many concurrent login attempts occurring on your site via malicious automated robots, this also has a negative impact on your server's memory and performance." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:302 +msgid "The features in this tab will stop the majority of brute force login attacks thus providing even better protection for your WP login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:307 +#: admin/wp-security-firewall-menu.php:654 +msgid "backup" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:308 +msgid "video tutorial" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:309 +msgid "To learn more about how to use this feature, please watch the following %s." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:310 +#: admin/wp-security-brute-force-menu.php:758 +msgid "Cookie-Based Brute Force Login Prevention" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:320 +#: admin/wp-security-user-login-menu.php:253 +msgid "Cookie based brute force login prevention" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:331 +msgid "This feature can lock you out of admin if it doesn't work correctly on your site. You " +msgstr "" + +#: admin/wp-security-brute-force-menu.php:342 +msgid "The cookie test was successful. You can now enable this feature." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:350 +msgid "The cookie test failed on this server. Consequently, this feature cannot be used on this site." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:357 +msgid "Before using this feature, you must perform a cookie test first." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:359 +msgid "This ensures that your browser cookie is working correctly and that you won't lock yourself out." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:364 +msgid "Perform cookie test" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:370 +#: classes/grade-system/wp-security-feature-item-manager.php:103 +msgid "Enable brute force attack prevention" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:373 +msgid "Check this if you want to protect your login page from Brute Force Attack." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:378 +msgid "This feature will deny access to your WordPress login page for all people except those who have a special cookie in their browser." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:380 +msgid "To use this feature do the following:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:382 +msgid "1) Enable the checkbox." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:384 +msgid "2) Enter a secret word consisting of alphanumeric characters which will be difficult to guess. This secret word will be useful whenever you need to know the special URL which you will use to access the login page (see point below)." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:386 +msgid "3) You will then be provided with a special login URL. You will need to use this URL to login to your WordPress site instead of the usual login URL. NOTE: The system will deposit a special cookie in your browser which will allow you access to the WordPress administration login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:388 +msgid "Any person trying to access your login page who does not have the special cookie in their browser will be automatically blocked." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:395 +msgid "Secret word" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:397 +msgid "Choose a secret word consisting of alphanumeric characters which you can use to access your special URL. Your are highly encouraged to choose a word which will be difficult to guess." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:401 +msgid "Re-direct URL" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:405 +msgid "Specify a URL to redirect a hacker to when they try to access your WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:412 +msgid "The URL specified here can be any site's URL and does not have to be your own. For example you can be as creative as you like and send hackers to the CIA or NSA home page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:414 +msgid "This field will default to: http://127.0.0.1 if you do not enter a value." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:416 +msgid "Useful Tip:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:418 +msgid "It's a good idea to not redirect attempted brute force login attempts to your site because it increases the load on your server." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:420 +msgid "Redirecting a hacker or malicious bot back to \"http://127.0.0.1\" is ideal because it deflects them back to their own local host and puts the load on their server instead of yours." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:427 +msgid "My site has posts or pages which are password protected" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:430 +msgid "Check this if you are using the native WordPress password protection feature for some or all of your blog posts or pages." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:435 +msgid "In the cases where you are protecting some of your posts or pages using the in-built WordPress password protection feature, a few extra lines of directives and exceptions need to be added so that people trying to access pages are not automatically blocked." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:437 +msgid "By enabling this checkbox, the plugin will add the necessary rules and exceptions so that people trying to access these pages are not automatically blocked." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:439 +msgid "Helpful Tip:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:441 +msgid "If you do not use the WordPress password protection feature for your posts or pages then it is highly recommended that you leave this checkbox disabled." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:448 +msgid "My site has a theme or plugins which use AJAX" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:451 +msgid "Check this if your site uses AJAX functionality." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:456 +msgid "In the cases where your WordPress installation has a theme or plugin that uses AJAX, a few extra lines of directives and exceptions need to be added to prevent AJAX requests from being automatically blocked by the brute force prevention feature." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:458 +msgid "By enabling this checkbox, the plugin will add the necessary rules and exceptions so that AJAX operations will work as expected." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:467 +msgid "Save feature settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:525 +msgid "This feature allows you to add a CAPTCHA form on various WordPress login pages and forms." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:526 +msgid "Adding a CAPTCHA form on a login page or form is another effective yet simple \"Brute Force\" prevention technique." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:527 +msgid "You have the option of using either %s or a plain maths CAPTCHA form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:528 +msgid "If you enable Google reCAPTCHA the reCAPTCHA widget will be displayed for all forms the CAPTCHA settings below." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:529 +msgid "If Google reCAPTCHA is disabled the simple maths CAPTCHA form will apply and users will need to enter the answer to a simple mathematical question." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:535 +msgid "Google reCAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:540 +msgid "By enabling these settings the Google reCAPTCHA v2 widget will be applied by default for all forms with CAPTCHA enabled." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:549 +msgid "reCAPTCHA will not work because you have disabled login lockout by activating the AIOS_DISABLE_LOGIN_LOCKOUT constant value in a configuration file." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:550 +msgid "To enable it, define AIOS_DISABLE_LOGIN_LOCKOUT constant value as false, or remove it." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:558 +msgid "Use Google reCAPTCHA as default" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:561 +msgid "Check this if you want to default to Google reCAPTCHA for all settings below. (If this is left unchecked, all CAPTCHA forms will revert to the plain maths CAPTCHA)" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:565 +msgid "Site key" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:571 +msgid "Secret key" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:580 +msgid "Login form CAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:589 +msgid "Enable CAPTCHA on login page" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:592 +msgid "Check this if you want to insert a CAPTCHA form on the login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:598 +msgid "Lost password form CAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:608 +msgid "Enable CAPTCHA on lost password page" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:611 +msgid "Check this if you want to insert a CAPTCHA form on the lost password page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:617 +msgid "Custom login form CAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:626 +msgid "Enable CAPTCHA on custom login form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:629 +msgid "Check this if you want to insert CAPTCHA on a custom login form generated by the following WP function: wp_login_form()" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:639 +msgid "WooCommerce forms CAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:648 +msgid "Enable CAPTCHA on WooCommerce login form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:651 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce login form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:661 +msgid "Enable CAPTCHA on WooCommerce lost password form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:664 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce lost password form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:674 +msgid "Enable CAPTCHA on WooCommerce registration form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:677 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce registration form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:749 +msgid "The All In One WP Security Whitelist feature gives you the option of only allowing certain IP addresses or ranges to have access to your WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:750 +msgid "This feature will deny login access for all IP addresses which are not in your whitelist as configured in the settings below." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:751 +msgid "The plugin achieves this by writing the appropriate directives to your .htaccess file." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:752 +msgid "By allowing/blocking IP addresses, you are using the most secure first line of defence because login access will only be granted to whitelisted IP addresses and other addresses will be blocked as soon as they try to access your login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:760 +msgid "Attention: If in addition to enabling the white list feature, you also have one of the %s or %s features enabled, you will still need to use your secret word or special slug in the URL when trying to access your WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:761 +msgid "These features are NOT functionally related. Having both of them enabled on your site means you are creating 2 layers of security." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:772 +msgid "Login IP whitelist settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:783 +msgid "Enable IP whitelisting" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:786 +#: admin/wp-security-user-login-menu.php:408 +msgid "Check this if you want to enable the whitelisting of selected IP addresses specified in the settings below" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:790 +msgid "Your current IP address" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:793 +msgid "You can copy and paste this address in the text box below if you want to include it in your login whitelist." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:797 +#: admin/wp-security-user-login-menu.php:412 +msgid "Enter whitelisted IP addresses:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:801 +#: admin/wp-security-user-login-menu.php:416 +msgid "Enter one or more IP addresses or IP ranges you wish to include in your whitelist." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:801 +msgid "Only the addresses specified here will have access to the WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:839 +msgid "This feature allows you to add a special hidden \"honeypot\" field on the WordPress login page. This will only be visible to robots and not humans." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:840 +msgid "Since robots usually fill in every input field from a login form, they will also submit a value for the special hidden honeypot field." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:841 +#: admin/wp-security-user-registration-menu.php:278 +msgid "The way honeypots work is that a hidden field is placed somewhere inside a form which only robots will submit. If that field contains a value when the form is submitted then a robot has most likely submitted the form and it is consequently dealt with." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:842 +msgid "Therefore, if the plugin detects that this field has a value when the login form is submitted, then the robot which is attempting to login to your site will be redirected to its localhost address - http://127.0.0.1." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:848 +msgid "Login form honeypot settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:859 +msgid "Enable honeypot on login page" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:862 +msgid "Check this if you want to enable the honeypot feature for the login page" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:27 +#: admin/wp-security-dashboard-menu.php:374 +#: classes/wp-security-user-login.php:74 +msgid "Locked IP addresses" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:28 +msgid "Permanent block list" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:29 +msgid "Logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:33 +msgid "Premium upgrade" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:131 +#: admin/wp-security-dashboard-menu.php:518 +#: admin/wp-security-user-login-menu.php:53 +#: classes/grade-system/wp-security-feature-item-manager.php:49 +msgid "Login lockout" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:132 +msgid "This tab displays the list of all IP addresses which are currently temporarily locked out due to the login lockout feature:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:138 +msgid "Currently locked out IP addresses and ranges" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:183 +msgid "This tab displays the list of all permanently blocked IP addresses." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:184 +#: admin/wp-security-spam-menu.php:339 +msgid "NOTE: This feature does NOT use the .htaccess file to permanently block the IP addresses so it should be compatible with all web servers running WordPress." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:189 +msgid "Permanently blocked IP addresses" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:200 +#: admin/wp-security-firewall-menu.php:1151 +#: admin/wp-security-user-login-menu.php:485 +#: admin/wp-security-user-login-menu.php:643 +#: admin/wp-security-user-registration-menu.php:164 +msgid "Search" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:238 +#: admin/wp-security-dashboard-menu.php:249 +#: admin/wp-security-dashboard-menu.php:260 +msgid "All In One WP Security & Firewall" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:250 +msgid "Debug logs have been cleared." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:261 +msgid "Unable to clear the logs; an invalid nonce was provided" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:274 +msgid "Debug log options" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:281 +msgid "Clear logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:289 +msgid "Debug logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:362 +msgid "Security strength meter" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:363 +msgid "Security points breakdown" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:364 +msgid "Spread the word" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:365 +msgid "Get to know the developers" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:366 +msgid "Critical feature status" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:367 +msgid "Last 5 logins" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:368 +msgid "Maintenance mode status" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:373 +#: admin/wp-security-dashboard-menu.php:664 +#: admin/wp-security-user-login-menu.php:57 +msgid "Logged in users" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:417 +msgid "Total Achievable Points: " +msgstr "" + +#: admin/wp-security-dashboard-menu.php:419 +msgid "Current Score of Your Site: " +msgstr "" + +#: admin/wp-security-dashboard-menu.php:472 +msgid "We are working hard to make your WordPress site more secure. Please support us, here is how:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:473 +msgid "Follow us on" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:477 +msgid "Post to Twitter" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:481 +msgid "Give us a good rating" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:488 +msgid "Wanna know more about the developers behind this plugin?" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:499 +msgid "Below is the current status of the critical features that you should activate on your site to achieve a minimum level of recommended security" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:503 +msgid "Admin username" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:533 +msgid "File permission" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:548 +msgid "Basic firewall" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:577 +msgid "No data found." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:581 +msgid "Last 5 logins summary:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:585 +msgid "User" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:586 +#: admin/wp-security-list-404.php:95 +#: admin/wp-security-list-login-fails.php:56 +#: admin/wp-security-list-permanent-blocked-ip.php:68 +msgid "Date" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:587 +msgid "IP" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:608 +msgid "Maintenance mode is currently enabled. Remember to turn it off when you are done" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:610 +msgid "Maintenance mode is currently off." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:614 +msgid "Maintenance mode" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:632 +msgid "Cookie based brute force" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:636 +#: admin/wp-security-dashboard-menu.php:654 +msgid "The %s feature is currently active." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:637 +#: admin/wp-security-dashboard-menu.php:655 +msgid "Your new WordPress login URL is now:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:666 +msgid "Number of users currently logged into your site (including you) is:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:667 +msgid "There are no other users currently logged in." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:680 +msgid "Number of users currently logged in site-wide (including you) is:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:681 +msgid "There are no other site-wide users currently logged in." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:694 +#: admin/wp-security-dashboard-menu.php:711 +msgid "Go to the %s menu to see more details" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:707 +msgid "There are no IP addresses currently locked out." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:710 +msgid "Number of temporarily locked out IP addresses: " +msgstr "" + +#: admin/wp-security-database-menu.php:52 +msgid "UpdraftPlus is installed but currently not active." +msgstr "" + +#: admin/wp-security-database-menu.php:52 +msgid "Follow this link to activate UpdraftPlus, to take a backup." +msgstr "" + +#: admin/wp-security-database-menu.php:57 +msgid "Follow this link to install UpdraftPlus, to take a database backup." +msgstr "" + +#: admin/wp-security-database-menu.php:87 +#: admin/wp-security-database-menu.php:92 +msgid "Database backup" +msgstr "" + +#: admin/wp-security-database-menu.php:91 +#: classes/grade-system/wp-security-feature-item-manager.php:65 +msgid "Database prefix" +msgstr "" + +#: admin/wp-security-database-menu.php:119 +msgid "Database security" +msgstr "" + +#: admin/wp-security-database-menu.php:147 +msgid "Nonce check failed for DB prefix change operation!" +msgstr "" + +#: admin/wp-security-database-menu.php:155 +msgid "The plugin has detected that it cannot write to the wp-config.php file. This feature can only be used if the plugin can successfully write to the wp-config.php file." +msgstr "" + +#: admin/wp-security-database-menu.php:168 +msgid "Please enter a value for the DB prefix." +msgstr "" + +#: admin/wp-security-database-menu.php:177 +msgid "ERROR: The table prefix can only contain numbers, letters, and underscores." +msgstr "" + +#: admin/wp-security-database-menu.php:186 +#: admin/wp-security-database-menu.php:245 +msgid "Change database prefix" +msgstr "" + +#: admin/wp-security-database-menu.php:189 +msgid "Your WordPress database is the most important asset of your website because it contains a lot of your site's precious information." +msgstr "" + +#: admin/wp-security-database-menu.php:190 +msgid "The database is also a target for hackers via methods such as SQL injections and malicious and automated code which targets certain tables." +msgstr "" + +#: admin/wp-security-database-menu.php:191 +msgid "One way to add a layer of protection for your DB is to change the default WordPress table prefix from \"wp_\" to something else which will be difficult for hackers to guess." +msgstr "" + +#: admin/wp-security-database-menu.php:192 +msgid "This feature allows you to easily change the prefix to a value of your choice or to a random value set by this plugin." +msgstr "" + +#: admin/wp-security-database-menu.php:198 +msgid "Database prefix options" +msgstr "" + +#: admin/wp-security-database-menu.php:210 +msgid "database backup" +msgstr "" + +#: admin/wp-security-database-menu.php:211 +msgid "It is recommended that you perform a %s before using this feature" +msgstr "" + +#: admin/wp-security-database-menu.php:221 +msgid "Current database table prefix" +msgstr "" + +#: admin/wp-security-database-menu.php:227 +msgid "Your site is currently using the default WordPress database prefix value of \"wp_\"." +msgstr "" + +#: admin/wp-security-database-menu.php:227 +msgid "To increase your site's security you should consider changing the database prefix value to another value." +msgstr "" + +#: admin/wp-security-database-menu.php:234 +msgid "Generate new database table prefix" +msgstr "" + +#: admin/wp-security-database-menu.php:238 +msgid "Check this if you want the plugin to generate a random 6 character string for the table prefix" +msgstr "" + +#: admin/wp-security-database-menu.php:239 +msgid "OR" +msgstr "" + +#: admin/wp-security-database-menu.php:241 +msgid "Choose your own database prefix by specifying a string which contains letters and/or numbers and/or underscores. Example: xyz_" +msgstr "" + +#: admin/wp-security-database-menu.php:265 +msgid "Take a database backup using UpdraftPlus" +msgstr "" + +#: admin/wp-security-database-menu.php:270 +msgid "Manual backup" +msgstr "" + +#: admin/wp-security-database-menu.php:274 +msgid "UpdraftPlus Backup/Restore" +msgstr "" + +#: admin/wp-security-database-menu.php:274 +msgid "Your backups are on the UpdraftPlus Backup/Restore admin page." +msgstr "" + +#: admin/wp-security-database-menu.php:276 +msgid "Create database backup now" +msgstr "" + +#: admin/wp-security-database-menu.php:308 +msgid "Error - Could not get tables or no tables found!" +msgstr "" + +#: admin/wp-security-database-menu.php:312 +msgid "Starting DB prefix change operations....." +msgstr "" + +#: admin/wp-security-database-menu.php:314 +msgid "Your WordPress system has a total of %s tables and your new DB prefix will be: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:320 +#: classes/wp-security-utility.php:306 +msgid "Failed to make a backup of the wp-config.php file. This operation will not go ahead." +msgstr "" + +#: admin/wp-security-database-menu.php:324 +msgid "A backup copy of your wp-config.php file was created successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:351 +msgid "%s table name update failed" +msgstr "" + +#: admin/wp-security-database-menu.php:363 +msgid "Please change the prefix manually for the above tables to: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:366 +msgid "%s tables had their prefix updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:387 +msgid "wp-config.php file was updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:390 +msgid "The \"wp-config.php\" file was not able to be modified." +msgstr "" + +#: admin/wp-security-database-menu.php:390 +msgid "Please modify this file manually using your favourite editor and search for variable \"$table_prefix\" and assign the following value to that variable: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:401 +#: admin/wp-security-database-menu.php:420 +msgid "Update of table %s failed: unable to change %s to %s" +msgstr "" + +#: admin/wp-security-database-menu.php:405 +msgid "The options table records which had references to the old DB prefix were updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:424 +msgid "The %s table records which had references to the old DB prefix were updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:452 +msgid "Error updating user_meta table where new meta_key = %s, old meta_key = %s and user_id = %s." +msgstr "" + +#: admin/wp-security-database-menu.php:457 +msgid "The usermeta table records which had references to the old DB prefix were updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:459 +msgid "The database prefix change tasks have been completed." +msgstr "" + +#: admin/wp-security-database-menu.php:503 +msgid "Checking for MySQL tables of type \"view\"....." +msgstr "" + +#: admin/wp-security-database-menu.php:520 +msgid "Update of the following MySQL view definition failed: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:527 +msgid "%s view definitions were updated successfully!" +msgstr "" + +#: admin/wp-security-filescan-menu.php:26 +#: classes/grade-system/wp-security-feature-item-manager.php:127 +msgid "File change detection" +msgstr "" + +#: admin/wp-security-filescan-menu.php:27 +msgid "Malware scan" +msgstr "" + +#: admin/wp-security-filescan-menu.php:88 +msgid "There have been no file changes since the last scan." +msgstr "" + +#: admin/wp-security-filescan-menu.php:98 +msgid "Nonce check failed for manual file change detection scan operation!" +msgstr "" + +#: admin/wp-security-filescan-menu.php:104 +msgid "There was an error during the file change detection scan. Please check the AIOS logs." +msgstr "" + +#: admin/wp-security-filescan-menu.php:110 +msgid "The plugin has detected that this is your first file change detection scan. The file details from this scan will be used to detect file changes for future scans." +msgstr "" + +#: admin/wp-security-filescan-menu.php:112 +msgid "Scan complete - There were no file changes detected!" +msgstr "" + +#: admin/wp-security-filescan-menu.php:133 +msgid "You entered a non numeric value for the \"backup time interval\" field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-filescan-menu.php:167 +msgid "The following address was removed because it is not a valid email address: " +msgstr "" + +#: admin/wp-security-filescan-menu.php:206 +msgid "NEW SCAN COMPLETED: The plugin has detected that you have made changes to the \"File Types To Ignore\" or \"Files To Ignore\" fields." +msgstr "" + +#: admin/wp-security-filescan-menu.php:206 +msgid "In order to ensure that future scan results are accurate, the old scan data has been refreshed." +msgstr "" + +#: admin/wp-security-filescan-menu.php:215 +msgid "All In One WP Security & Firewall has detected that there was a change in your host's files." +msgstr "" + +#: admin/wp-security-filescan-menu.php:217 +msgid "View scan details and clear this message" +msgstr "" + +#: admin/wp-security-filescan-menu.php:226 +msgid "If given an opportunity hackers can insert their code or files into your system which they can then use to carry out malicious acts on your site." +msgstr "" + +#: admin/wp-security-filescan-menu.php:227 +msgid "Being informed of any changes in your files can be a good way to quickly prevent a hacker from causing damage to your website." +msgstr "" + +#: admin/wp-security-filescan-menu.php:228 +msgid "In general, WordPress core and plugin files and file types such as \".php\" or \".js\" should not change often and when they do, it is important that you are made aware when a change occurs and which file was affected." +msgstr "" + +#: admin/wp-security-filescan-menu.php:229 +msgid "The \"File Change Detection Feature\" will notify you of any file change which occurs on your system, including the addition and deletion of files by performing a regular automated or manual scan of your system's files." +msgstr "" + +#: admin/wp-security-filescan-menu.php:230 +msgid "This feature also allows you to exclude certain files or folders from the scan in cases where you know that they change often as part of their normal operation. (For example log files and certain caching plugin files may change often and hence you may choose to exclude such files from the file change detection scan)" +msgstr "" + +#: admin/wp-security-filescan-menu.php:241 +msgid "It appears that your server is using an old PHP version which is missing the %s. The file scanner feature needs this class in order to work. If you would like to use this feature please upgrade your server PHP version to 5.3 or greater." +msgstr "" + +#: admin/wp-security-filescan-menu.php:249 +msgid "Manual file change detection scan" +msgstr "" + +#: admin/wp-security-filescan-menu.php:255 +msgid "To perform a manual file change detection scan click on the button below." +msgstr "" + +#: admin/wp-security-filescan-menu.php:258 +msgid "Perform scan now" +msgstr "" + +#: admin/wp-security-filescan-menu.php:262 +msgid "View last saved file change results" +msgstr "" + +#: admin/wp-security-filescan-menu.php:268 +msgid "Click the button below to view the saved file change results from the last scan." +msgstr "" + +#: admin/wp-security-filescan-menu.php:271 +msgid "View last file change" +msgstr "" + +#: admin/wp-security-filescan-menu.php:275 +msgid "File change detection settings" +msgstr "" + +#: admin/wp-security-filescan-menu.php:287 +msgid "Enable automated file change detection scan" +msgstr "" + +#: admin/wp-security-filescan-menu.php:290 +msgid "Check this if you want the system to automatically/periodically scan your files to check for file changes based on the settings below" +msgstr "" + +#: admin/wp-security-filescan-menu.php:294 +msgid "Scan time interval" +msgstr "" + +#: admin/wp-security-filescan-menu.php:297 +msgid "Hours" +msgstr "" + +#: admin/wp-security-filescan-menu.php:298 +msgid "Days" +msgstr "" + +#: admin/wp-security-filescan-menu.php:299 +msgid "Weeks" +msgstr "" + +#: admin/wp-security-filescan-menu.php:301 +msgid "Set the value for how often you would like a scan to occur" +msgstr "" + +#: admin/wp-security-filescan-menu.php:305 +msgid "File types to ignore" +msgstr "" + +#: admin/wp-security-filescan-menu.php:308 +msgid "Enter each file type or extension on a new line which you wish to exclude from the file change detection scan." +msgstr "" + +#: admin/wp-security-filescan-menu.php:312 +msgid "You can exclude file types from the scan which would not normally pose any security threat if they were changed. These can include things such as image files." +msgstr "" + +#: admin/wp-security-filescan-menu.php:313 +msgid "Example: If you want the scanner to ignore files of type jpg, png, and bmp, then you would enter the following:" +msgstr "" + +#: admin/wp-security-filescan-menu.php:314 +msgid "jpg" +msgstr "" + +#: admin/wp-security-filescan-menu.php:315 +msgid "png" +msgstr "" + +#: admin/wp-security-filescan-menu.php:316 +msgid "bmp" +msgstr "" + +#: admin/wp-security-filescan-menu.php:322 +msgid "Files/Directories to ignore" +msgstr "" + +#: admin/wp-security-filescan-menu.php:325 +msgid "Enter each file or directory on a new line which you wish to exclude from the file change detection scan." +msgstr "" + +#: admin/wp-security-filescan-menu.php:329 +msgid "You can exclude specific files/directories from the scan which would not normally pose any security threat if they were changed. These can include things such as log files." +msgstr "" + +#: admin/wp-security-filescan-menu.php:330 +msgid "Example: If you want the scanner to ignore certain files in different directories or whole directories, then you would enter the following:" +msgstr "" + +#: admin/wp-security-filescan-menu.php:331 +msgid "cache/config/master.php" +msgstr "" + +#: admin/wp-security-filescan-menu.php:332 +msgid "somedirectory" +msgstr "" + +#: admin/wp-security-filescan-menu.php:339 +msgid "Send email when change detected" +msgstr "" + +#: admin/wp-security-filescan-menu.php:343 +msgid "Check this if you want the system to email you if a file change was detected" +msgstr "" + +#: admin/wp-security-filescan-menu.php:347 +msgid "Enter one or more email addresses on a new line." +msgstr "" + +#: admin/wp-security-filescan-menu.php:364 +msgid "What is malware?" +msgstr "" + +#: admin/wp-security-filescan-menu.php:365 +msgid "The word malware stands for Malicious Software. It can consist of things like trojan horses, adware, worms, spyware and any other undesirable code which a hacker will try to inject into your website." +msgstr "" + +#: admin/wp-security-filescan-menu.php:366 +msgid "Often when malware code has been inserted into your site you will normally not notice anything out of the ordinary based on appearances, but it can have a dramatic effect on your site's search ranking." +msgstr "" + +#: admin/wp-security-filescan-menu.php:367 +msgid "This is because the bots and spiders from search engines such as Google have the capability to detect malware when they are indexing the pages on your site, and consequently they can blacklist your website which will in turn affect your search rankings." +msgstr "" + +#: admin/wp-security-filescan-menu.php:369 +msgid "CLICK HERE" +msgstr "" + +#: admin/wp-security-filescan-menu.php:371 +msgid "Scanning for malware" +msgstr "" + +#: admin/wp-security-filescan-menu.php:372 +msgid "Due to the constantly changing and complex nature of Malware, scanning for such things using a standalone plugin will not work reliably. This is something best done via an external scan of your site regularly." +msgstr "" + +#: admin/wp-security-filescan-menu.php:373 +msgid "This is why we have created an easy-to-use scanning service which is hosted off our own server which will scan your site for malware once every day and notify you if it finds anything." +msgstr "" + +#: admin/wp-security-filescan-menu.php:374 +msgid "When you sign up for this service you will get the following:" +msgstr "" + +#: admin/wp-security-filescan-menu.php:376 +msgid "Automatic daily scan of 1 website" +msgstr "" + +#: admin/wp-security-filescan-menu.php:377 +msgid "Automatic malware and blacklist monitoring" +msgstr "" + +#: admin/wp-security-filescan-menu.php:378 +msgid "Automatic email alerting" +msgstr "" + +#: admin/wp-security-filescan-menu.php:379 +msgid "Site uptime monitoring" +msgstr "" + +#: admin/wp-security-filescan-menu.php:380 +msgid "Site response time monitoring" +msgstr "" + +#: admin/wp-security-filescan-menu.php:381 +msgid "We provide advice for malware cleanup" +msgstr "" + +#: admin/wp-security-filescan-menu.php:382 +msgid "Blacklist removal" +msgstr "" + +#: admin/wp-security-filescan-menu.php:383 +msgid "No contract (cancel anytime)" +msgstr "" + +#: admin/wp-security-filescan-menu.php:385 +msgid "To learn more please %s." +msgstr "" + +#: admin/wp-security-filescan-menu.php:406 +msgid "Latest file change scan results" +msgstr "" + +#: admin/wp-security-filescan-menu.php:416 +msgid "The following files were added to your host." +msgstr "" + +#: admin/wp-security-filescan-menu.php:419 +#: admin/wp-security-filescan-menu.php:440 +#: admin/wp-security-filescan-menu.php:464 +msgid "File" +msgstr "" + +#: admin/wp-security-filescan-menu.php:420 +#: admin/wp-security-filescan-menu.php:441 +#: admin/wp-security-filescan-menu.php:465 +msgid "File size" +msgstr "" + +#: admin/wp-security-filescan-menu.php:421 +#: admin/wp-security-filescan-menu.php:442 +#: admin/wp-security-filescan-menu.php:466 +msgid "File modified" +msgstr "" + +#: admin/wp-security-filescan-menu.php:437 +msgid "The following files were removed from your host." +msgstr "" + +#: admin/wp-security-filescan-menu.php:461 +msgid "The following files were changed on your host." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:26 +#: classes/grade-system/wp-security-feature-item-manager.php:69 +msgid "File permissions" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:27 +msgid "PHP file editing" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:28 +msgid "WP file access" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:29 +msgid "Host system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:55 +msgid "Filesystem security" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:80 +msgid "Nonce check failed for manual DB backup operation!" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:90 +msgid "The permissions for %s were successfully changed to %s" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:94 +msgid "Unable to change permissions for %s!" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:100 +msgid "File permissions scan" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:103 +msgid "Your WordPress file and folder permission settings govern the accessibility and read/write privileges of the files and folders which make up your WP installation." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:104 +msgid "Your WP installation already comes with reasonably secure file permission settings for the filesystem." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:105 +msgid "However, sometimes people or other plugins modify the various permission settings of certain core WP folders or files such that they end up making their site less secure because they chose the wrong permission values." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:106 +msgid "This feature will scan the critical WP core folders and files and will highlight any permission settings which are insecure." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:114 +msgid "This plugin has detected that your site is running on a Windows server." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:115 +msgid "This feature is not applicable for Windows server installations." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:121 +msgid "WP directory and file permissions scan results" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:133 +#: admin/wp-security-filesystem-menu.php:152 +msgid "Name" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:134 +#: admin/wp-security-filesystem-menu.php:153 +msgid "File/Folder" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:135 +#: admin/wp-security-filesystem-menu.php:154 +msgid "Current permissions" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:136 +#: admin/wp-security-filesystem-menu.php:155 +msgid "Recommended permissions" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:137 +#: admin/wp-security-filesystem-menu.php:156 +msgid "Recommended action" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:195 +msgid "Your PHP file editing settings were saved successfully." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:199 +msgid "Operation failed! Unable to modify or make a backup of wp-config.php file!" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:212 +#: classes/grade-system/wp-security-feature-item-manager.php:71 +msgid "File editing" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:215 +msgid "The WordPress Dashboard by default allows administrators to edit PHP files, such as plugin and theme files." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:216 +msgid "This is often the first tool an attacker will use if able to login, since it allows code execution." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:217 +msgid "This feature will disable the ability for people to edit PHP files via the dashboard." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:223 +msgid "Disable PHP file editing" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:235 +msgid "Disable ability to edit PHP files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:238 +msgid "Check this if you want to remove the ability for people to edit PHP files via the WP dashboard" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:282 +msgid "You have successfully saved the Prevent Access to Default WP Files configuration." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:286 +#: admin/wp-security-firewall-menu.php:126 +#: admin/wp-security-firewall-menu.php:346 +#: admin/wp-security-firewall-menu.php:613 +#: admin/wp-security-firewall-menu.php:912 +#: admin/wp-security-settings-menu.php:772 +#: admin/wp-security-spam-menu.php:124 +msgid "Could not write to the .htaccess file. Please check the file permissions." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:291 +msgid "WordPress files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:294 +msgid "This feature allows you to prevent access to files such as %s, %s and %s which are delivered with all WP installations." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:295 +msgid "By preventing access to these files you are hiding some key pieces of information (such as WordPress version info) from potential hackers." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:300 +msgid "Prevent access to default WP files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:311 +msgid "Prevent access to WP default install files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:314 +msgid "Check this if you want to prevent access to readme.html, license.txt and wp-config-sample.php." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:318 +msgid "Save setting" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:342 +msgid "System logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:345 +msgid "Sometimes your hosting platform will produce error or warning logs in a file called \"error_log\"." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:346 +msgid "Depending on the nature and cause of the error or warning, your hosting server can create multiple instances of this file in numerous directory locations of your WordPress installation." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:347 +msgid "By occasionally viewing the contents of these logs files you can keep informed of any underlying problems on your system which you might need to address." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:353 +msgid "View system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:355 +msgid "Please click the button below to view the latest system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:358 +msgid "Enter System Log File Name" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:360 +msgid "Enter your system log file name. (Defaults to error_log)" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:363 +msgid "View latest system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:365 +msgid "Loading..." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:382 +msgid "No system logs were found." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:435 +msgid "Set recommended permissions" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:441 +msgid "No action required" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:481 +msgid "Showing latest entries of error_log file: %s" +msgstr "" + +#: admin/wp-security-firewall-menu.php:28 +msgid "Basic firewall rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:29 +msgid "Additional firewall rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:30 +msgid "6G Blacklist firewall rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:31 +msgid "Internet bots" +msgstr "" + +#: admin/wp-security-firewall-menu.php:32 +msgid "Prevent hotlinks" +msgstr "" + +#: admin/wp-security-firewall-menu.php:33 +msgid "404 detection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:34 +msgid "Custom rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:122 +#: admin/wp-security-firewall-menu.php:908 +#: admin/wp-security-spam-menu.php:120 +#: admin/wp-security-spam-menu.php:494 +#: admin/wp-security-spam-menu.php:556 +#: admin/wp-security-user-registration-menu.php:95 +msgid "Settings were successfully saved" +msgstr "" + +#: admin/wp-security-firewall-menu.php:131 +#: admin/wp-security-firewall-menu.php:651 +msgid "Firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:138 +msgid "This should not have any impact on your site's general functionality but if you wish you can take a %s of your .htaccess file before proceeding." +msgstr "" + +#: admin/wp-security-firewall-menu.php:139 +msgid "The features in this tab allow you to activate some basic firewall security protection rules for your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:140 +msgid "The firewall functionality is achieved via the insertion of special code into your currently active .htaccess file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:151 +msgid "You have enabled the \"Completely Block Access To XMLRPC\" checkbox which means all XMLRPC functionality will be blocked." +msgstr "" + +#: admin/wp-security-firewall-menu.php:152 +msgid "By leaving this feature enabled you will prevent Jetpack or Wordpress iOS or other apps which need XMLRPC from working correctly on your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:153 +msgid "If you still need XMLRPC then uncheck the \"Completely Block Access To XMLRPC\" checkbox and enable only the \"Disable Pingback Functionality From XMLRPC\" checkbox." +msgstr "" + +#: admin/wp-security-firewall-menu.php:163 +msgid "Basic firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:171 +msgid "Enable basic firewall protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:174 +msgid "Check this if you want to apply basic firewall protection to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:178 +msgid "This setting will implement the following basic firewall protection mechanisms on your site:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:179 +msgid "1) Protect your htaccess file by denying access to it." +msgstr "" + +#: admin/wp-security-firewall-menu.php:180 +msgid "2) Disable the server signature." +msgstr "" + +#: admin/wp-security-firewall-menu.php:181 +msgid "3) Limit file upload size (%sMB)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:182 +msgid "4) Protect your wp-config.php file by denying access to it." +msgstr "" + +#: admin/wp-security-firewall-menu.php:183 +msgid "The above firewall features will be applied via your .htaccess file and should not affect your site's overall functionality." +msgstr "" + +#: admin/wp-security-firewall-menu.php:184 +msgid "You are still advised to take a backup of your active .htaccess file just in case." +msgstr "" + +#: admin/wp-security-firewall-menu.php:190 +msgid "Max file upload size (MB)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:192 +msgid "The value for the maximum file upload size used in the .htaccess file. (Defaults to %sMB if left blank)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:200 +msgid "WordPress XMLRPC and pingback vulnerability protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:208 +msgid "Completely block access to XMLRPC" +msgstr "" + +#: admin/wp-security-firewall-menu.php:211 +msgid "Check this if you are not using the WP XML-RPC functionality and you want to completely block external access to XMLRPC." +msgstr "" + +#: admin/wp-security-firewall-menu.php:215 +msgid "This setting will add a directive in your .htaccess to disable access to the WordPress xmlrpc.php file which is responsible for the XML-RPC functionality in WordPress." +msgstr "" + +#: admin/wp-security-firewall-menu.php:216 +msgid "Hackers can exploit various vulnerabilities in the WordPress XML-RPC API in a number of ways such as:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:217 +msgid "1) Denial of Service (DoS) attacks" +msgstr "" + +#: admin/wp-security-firewall-menu.php:218 +msgid "2) Hacking internal routers." +msgstr "" + +#: admin/wp-security-firewall-menu.php:219 +msgid "3) Scanning ports in internal networks to get info from various hosts." +msgstr "" + +#: admin/wp-security-firewall-menu.php:220 +msgid "Apart from the security protection benefit, this feature may also help reduce load on your server, particularly if your site currently has a lot of unwanted traffic hitting the XML-RPC API on your installation." +msgstr "" + +#: admin/wp-security-firewall-menu.php:221 +msgid "NOTE: You should only enable this feature if you are not currently using the XML-RPC functionality on your WordPress installation." +msgstr "" + +#: admin/wp-security-firewall-menu.php:222 +msgid "Leave this feature disabled and use the feature below if you want pingback protection but you still need XMLRPC." +msgstr "" + +#: admin/wp-security-firewall-menu.php:228 +msgid "Disable pingback functionality from XMLRPC" +msgstr "" + +#: admin/wp-security-firewall-menu.php:231 +msgid "If you use Jetpack or WP iOS or other apps which need WP XML-RPC functionality then check this. This will enable protection against WordPress pingback vulnerabilities." +msgstr "" + +#: admin/wp-security-firewall-menu.php:235 +msgid "NOTE: If you use Jetpack or the Wordpress iOS or other apps then you should enable this feature but leave the \"Completely Block Access To XMLRPC\" checkbox unchecked." +msgstr "" + +#: admin/wp-security-firewall-menu.php:236 +msgid "The feature will still allow XMLRPC functionality on your site but will disable the pingback methods." +msgstr "" + +#: admin/wp-security-firewall-menu.php:237 +msgid "This feature will also remove the \"X-Pingback\" header if it is present." +msgstr "" + +#: admin/wp-security-firewall-menu.php:246 +msgid "Block access to debug log file" +msgstr "" + +#: admin/wp-security-firewall-menu.php:254 +msgid "Block access to debug.log file" +msgstr "" + +#: admin/wp-security-firewall-menu.php:257 +msgid "Check this if you want to block access to the debug.log file that WordPress creates when debug logging is enabled." +msgstr "" + +#: admin/wp-security-firewall-menu.php:261 +msgid "WordPress has an option to turn on the debug logging to a file located in wp-content/debug.log. This file may contain sensitive information." +msgstr "" + +#: admin/wp-security-firewall-menu.php:262 +msgid "Using this option will block external access to this file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:262 +msgid "You can still access this file by logging into your site via FTP." +msgstr "" + +#: admin/wp-security-firewall-menu.php:270 +msgid "Save basic firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:342 +msgid "You have successfully saved the Additional Firewall Protection configuration" +msgstr "" + +#: admin/wp-security-firewall-menu.php:356 +msgid "Additional firewall protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:360 +msgid "Due to the nature of the code being inserted to the .htaccess file, this feature may break some functionality for certain plugins and you are therefore advised to take a %s of .htaccess before applying this configuration." +msgstr "" + +#: admin/wp-security-firewall-menu.php:362 +msgid "This feature allows you to activate more advanced firewall settings to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:363 +msgid "The advanced firewall rules are applied via the insertion of special code to your currently active .htaccess file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:372 +msgid "Listing of directory contents" +msgstr "" + +#: admin/wp-security-firewall-menu.php:381 +#: classes/grade-system/wp-security-feature-item-manager.php:85 +msgid "Disable index views" +msgstr "" + +#: admin/wp-security-firewall-menu.php:384 +msgid "Check this if you want to disable directory and file listing." +msgstr "" + +#: admin/wp-security-firewall-menu.php:389 +msgid "By default, an Apache server will allow the listing of the contents of a directory if it doesn't contain an index.php file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:391 +msgid "This feature will prevent the listing of contents for all directories." +msgstr "" + +#: admin/wp-security-firewall-menu.php:393 +msgid "NOTE: In order for this feature to work \"AllowOverride\" of the Indexes directive must be enabled in your httpd.conf file. Ask your hosting provider to check this if you don't have access to httpd.conf" +msgstr "" + +#: admin/wp-security-firewall-menu.php:402 +msgid "Trace and track" +msgstr "" + +#: admin/wp-security-firewall-menu.php:411 +#: classes/grade-system/wp-security-feature-item-manager.php:86 +msgid "Disable trace and track" +msgstr "" + +#: admin/wp-security-firewall-menu.php:414 +msgid "Check this if you want to disable trace and track." +msgstr "" + +#: admin/wp-security-firewall-menu.php:419 +msgid "HTTP Trace attack (XST) can be used to return header requests and grab cookies and other information." +msgstr "" + +#: admin/wp-security-firewall-menu.php:421 +msgid "This hacking technique is usually used together with cross site scripting attacks (XSS)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:423 +msgid "Disabling trace and track on your site will help prevent HTTP Trace attacks." +msgstr "" + +#: admin/wp-security-firewall-menu.php:432 +msgid "Proxy comment posting" +msgstr "" + +#: admin/wp-security-firewall-menu.php:442 +msgid "Forbid proxy comment posting" +msgstr "" + +#: admin/wp-security-firewall-menu.php:445 +msgid "Check this if you want to forbid proxy comment posting." +msgstr "" + +#: admin/wp-security-firewall-menu.php:450 +msgid "This setting will deny any requests that use a proxy server when posting comments." +msgstr "" + +#: admin/wp-security-firewall-menu.php:451 +msgid "By forbidding proxy comments you are in effect eliminating some spam and other proxy requests." +msgstr "" + +#: admin/wp-security-firewall-menu.php:460 +msgid "Bad query strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:470 +msgid "Deny bad query strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:473 +msgid "This will help protect you against malicious queries via XSS." +msgstr "" + +#: admin/wp-security-firewall-menu.php:478 +msgid "This feature will write rules in your .htaccess file to prevent malicious string attacks on your site using XSS." +msgstr "" + +#: admin/wp-security-firewall-menu.php:479 +msgid "NOTE: Some of these strings might be used for plugins or themes and hence this might break some functionality." +msgstr "" + +#: admin/wp-security-firewall-menu.php:480 +#: admin/wp-security-firewall-menu.php:510 +msgid "You are therefore strongly advised to take a backup of your active .htaccess file before applying this feature." +msgstr "" + +#: admin/wp-security-firewall-menu.php:489 +#: classes/grade-system/wp-security-feature-item-manager.php:89 +msgid "Advanced character string filter" +msgstr "" + +#: admin/wp-security-firewall-menu.php:499 +msgid "Enable advanced character string filter" +msgstr "" + +#: admin/wp-security-firewall-menu.php:502 +msgid "This will block bad character matches from XSS." +msgstr "" + +#: admin/wp-security-firewall-menu.php:507 +msgid "This is an advanced character string filter to prevent malicious string attacks on your site coming from Cross Site Scripting (XSS)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:508 +msgid "This setting matches for common malicious string patterns and exploits and will produce a 403 error for the hacker attempting the query." +msgstr "" + +#: admin/wp-security-firewall-menu.php:509 +msgid "NOTE: Some strings for this setting might break some functionality." +msgstr "" + +#: admin/wp-security-firewall-menu.php:518 +msgid "Save additional firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:609 +msgid "You have successfully saved the 5G/6G Firewall Protection configuration" +msgstr "" + +#: admin/wp-security-firewall-menu.php:633 +msgid "All in One WP Security and Firewall" +msgstr "" + +#: admin/wp-security-firewall-menu.php:634 +msgid "We were unable to access the firewall's configuration file:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:636 +msgid "As a result, the firewall will be unavailable." +msgstr "" + +#: admin/wp-security-firewall-menu.php:637 +msgid "Please check your PHP error log for further information." +msgstr "" + +#: admin/wp-security-firewall-menu.php:638 +msgid "If you're unable to locate your PHP log file, please contact your web hosting company to ask them where it can be found on their setup." +msgstr "" + +#: admin/wp-security-firewall-menu.php:655 +msgid "This feature allows you to activate the %s (or legacy %s) firewall security protection rules designed and produced by %s." +msgstr "" + +#: admin/wp-security-firewall-menu.php:656 +msgid "The 6G Blacklist is updated and improved version of 5G Blacklist. If you have 5G Blacklist active, you might consider activating 6G Blacklist instead." +msgstr "" + +#: admin/wp-security-firewall-menu.php:657 +msgid "The 6G Blacklist is a simple, flexible blacklist that helps reduce the number of malicious URL requests that hit your website." +msgstr "" + +#: admin/wp-security-firewall-menu.php:658 +msgid "The added advantage of applying the 6G firewall to your site is that it has been tested and confirmed by the people at PerishablePress.com to be an optimal and least disruptive set of .htaccess security rules for general WP sites running on an Apache server or similar." +msgstr "" + +#: admin/wp-security-firewall-menu.php:659 +msgid "Therefore the 6G firewall rules should not have any impact on your site's general functionality but if you wish you can take a %s of your .htaccess file before proceeding." +msgstr "" + +#: admin/wp-security-firewall-menu.php:665 +msgid "6G blacklist/firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:677 +msgid "Enable 6G firewall protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:680 +msgid "Check this if you want to apply the 6G Blacklist firewall protection from perishablepress.com to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:684 +msgid "This setting will implement the 6G security firewall protection mechanisms on your site which include the following things:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:685 +#: admin/wp-security-firewall-menu.php:703 +msgid "1) Block forbidden characters commonly used in exploitative attacks." +msgstr "" + +#: admin/wp-security-firewall-menu.php:686 +#: admin/wp-security-firewall-menu.php:704 +msgid "2) Block malicious encoded URL characters such as the \".css(\" string." +msgstr "" + +#: admin/wp-security-firewall-menu.php:687 +#: admin/wp-security-firewall-menu.php:705 +msgid "3) Guard against the common patterns and specific exploits in the root portion of targeted URLs." +msgstr "" + +#: admin/wp-security-firewall-menu.php:688 +#: admin/wp-security-firewall-menu.php:706 +msgid "4) Stop attackers from manipulating query strings by disallowing illicit characters." +msgstr "" + +#: admin/wp-security-firewall-menu.php:689 +#: admin/wp-security-firewall-menu.php:707 +msgid "....and much more." +msgstr "" + +#: admin/wp-security-firewall-menu.php:695 +msgid "Enable legacy 5G firewall protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:698 +msgid "Check this if you want to apply the 5G Blacklist firewall protection from perishablepress.com to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:702 +msgid "This setting will implement the 5G security firewall protection mechanisms on your site which include the following things:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:713 +msgid "Save 5G/6G firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:721 +msgid "6G block request methods" +msgstr "" + +#: admin/wp-security-firewall-menu.php:725 +msgid "HTTP Request methods are used by browsers and clients to communicate with servers to get responses." +msgstr "" + +#: admin/wp-security-firewall-menu.php:726 +msgid "GET and POST are the most commonly used methods to request and submit data for specified resources of the server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:732 +msgid "Block %s method" +msgstr "" + +#: admin/wp-security-firewall-menu.php:735 +msgid "Check this to block the %s request method" +msgstr "" + +#: admin/wp-security-firewall-menu.php:740 +msgid "Some WooCommerce extensions use the PUT request method in addition to GET and POST." +msgstr "" + +#: admin/wp-security-firewall-menu.php:740 +msgid "This means WooCommerce users shouldn't block the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:741 +msgid "A few REST requests use the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:741 +msgid "If your site is communicated by the WP REST API, you should not block the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:749 +msgid "Save request methods settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:757 +msgid "6G other settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:761 +msgid "Block query strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:764 +msgid "Check this to block all query strings recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:768 +msgid "Block request strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:771 +msgid "Check this to block all request strings recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:775 +msgid "Block referrers" +msgstr "" + +#: admin/wp-security-firewall-menu.php:778 +msgid "Check this to block all referrers recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:782 +msgid "Block user-agents" +msgstr "" + +#: admin/wp-security-firewall-menu.php:785 +msgid "Check this to block all user-agents recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:789 +msgid "Save other settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:823 +msgid "The Internet bot settings were successfully saved" +msgstr "" + +#: admin/wp-security-firewall-menu.php:827 +msgid "Internet bot settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:833 +msgid "What is an Internet Bot" +msgstr "" + +#: admin/wp-security-firewall-menu.php:834 +msgid "%s?" +msgstr "" + +#: admin/wp-security-firewall-menu.php:836 +msgid "A bot is a piece of software which runs on the Internet and performs automatic tasks. For example when Google indexes your pages it uses automatic bots to achieve this task." +msgstr "" + +#: admin/wp-security-firewall-menu.php:837 +msgid "A lot of bots are legitimate and non-malicious but not all bots are good and often you will find some which try to impersonate legitimate bots such as \"Googlebot\" but in reality they have nohing to do with Google at all." +msgstr "" + +#: admin/wp-security-firewall-menu.php:838 +msgid "Although most of the bots out there are relatively harmless sometimes website owners want to have more control over which bots they allow into their site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:839 +msgid "This feature allows you to block bots which are impersonating as a Googlebot but actually aren't. (In other words they are fake Google bots)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:840 +msgid "Googlebots have a unique identity which cannot easily be forged and this feature will identify any fake Google bots and block them from reading your site's pages." +msgstr "" + +#: admin/wp-security-firewall-menu.php:846 +msgid "Attention: Sometimes non-malicious Internet organizations might have bots which impersonate as a \"Googlebot\"." +msgstr "" + +#: admin/wp-security-firewall-menu.php:847 +msgid "Just be aware that if you activate this feature the plugin will block all bots which use the \"Googlebot\" string in their User Agent information but are NOT officially from Google (irrespective whether they are malicious or not)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:848 +msgid "All other bots from other organizations such as \"Yahoo\", \"Bing\" etc will not be affected by this feature." +msgstr "" + +#: admin/wp-security-firewall-menu.php:854 +#: admin/wp-security-firewall-menu.php:864 +#: classes/grade-system/wp-security-feature-item-manager.php:93 +msgid "Block fake Googlebots" +msgstr "" + +#: admin/wp-security-firewall-menu.php:867 +msgid "Check this if you want to block all fake Googlebots." +msgstr "" + +#: admin/wp-security-firewall-menu.php:871 +msgid "This feature will check if the User Agent information of a bot contains the string \"Googlebot\"." +msgstr "" + +#: admin/wp-security-firewall-menu.php:872 +msgid "It will then perform a few tests to verify if the bot is legitimately from Google and if so it will allow the bot to proceed." +msgstr "" + +#: admin/wp-security-firewall-menu.php:873 +msgid "If the bot fails the checks then the plugin will mark it as being a fake Googlebot and it will block it" +msgstr "" + +#: admin/wp-security-firewall-menu.php:880 +msgid "Save internet bot settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:916 +#: admin/wp-security-firewall-menu.php:938 +#: classes/grade-system/wp-security-feature-item-manager.php:95 +msgid "Prevent image hotlinking" +msgstr "" + +#: admin/wp-security-firewall-menu.php:919 +msgid "A Hotlink is where someone displays an image on their site which is actually located on your site by using a direct link to the source of the image on your server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:920 +msgid "Due to the fact that the image being displayed on the other person's site is coming from your server, this can cause leaking of bandwidth and resources for you because your server has to present this image for the people viewing it on someone elses's site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:921 +msgid "This feature will prevent people from directly hotlinking images from your site's pages by writing some directives in your .htaccess file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:926 +msgid "Prevent hotlinking" +msgstr "" + +#: admin/wp-security-firewall-menu.php:941 +msgid "Check this if you want to prevent hotlinking to images on your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:961 +msgid "Nonce check failed for delete all 404 event logs operation!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:972 +msgid "404 Detection Feature - Delete all 404 event logs operation failed!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:976 +msgid "All 404 event logs were deleted from the DB successfully!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1000 +msgid "You entered a non numeric value for the lockout time length field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1006 +msgid "You entered an incorrect format for the \"Redirect URL\" field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1039 +msgid "404 detection configuration" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1042 +msgid "A 404 or Not Found error occurs when somebody tries to access a non-existent page on your website." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1043 +msgid "Typically, most 404 errors happen quite innocently when people have mis-typed a URL or used an old link to page which doesn't exist anymore." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1044 +msgid "However, in some cases you may find many repeated 404 errors which occur in a relatively short space of time and from the same IP address which are all attempting to access a variety of non-existent page URLs." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1045 +msgid "Such behaviour can mean that a hacker might be trying to find a particular page or URL for sinister reasons." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1046 +msgid "This feature allows you to monitor all 404 events which occur on your site, and it also gives you the option of blocking IP addresses for a configured length of time." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1047 +msgid "If you want to temporarily block or blacklist an IP address, simply click the \"Temp Block\" or \"Blacklist IP\" link for the applicable IP entry in the \"404 Event Logs\" table below." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1071 +msgid "404 detection options" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1083 +msgid "Enable 404 IP detection and lockout" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1086 +msgid "Check this if you want to enable the lockout of selected IP addresses." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1091 +msgid "When you enable this checkbox, all 404 events on your site will be logged in the table below. You can monitor these events and select some IP addresses listed in the table below and block them for a specified amount of time. All IP addresses you select to be blocked from the \"404 Event Logs\" table section will be unable to access your site during the time specified." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1099 +msgid "Enable 404 event logging" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1102 +msgid "Check this if you want to enable the logging of 404 events" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1107 +msgid "Time length of 404 lockout (minutes)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1109 +msgid "Set the length of time for which a blocked IP address will be prevented from visiting your site" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1114 +msgid "You can lock any IP address which is recorded in the \"404 Event Logs\" table section below." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1116 +msgid "To temporarily lock an IP address, hover over the ID column and click the \"Temp Block\" link for the applicable IP entry." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1123 +msgid "404 lockout redirect URL" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1125 +msgid "A blocked visitor will be automatically redirected to this URL." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1135 +msgid "This list displays the 404 event logs when somebody tries to access a non-existent page on your website." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1136 +msgid "404 event logs that are older than %1$d days are purged automatically." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1141 +msgid "404 event logs" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1163 +#: admin/wp-security-firewall-menu.php:1172 +#: admin/wp-security-user-login-menu.php:495 +#: admin/wp-security-user-login-menu.php:504 +#: admin/wp-security-user-login-menu.php:653 +#: admin/wp-security-user-login-menu.php:662 +msgid "Export to CSV" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1169 +#: admin/wp-security-user-login-menu.php:501 +#: admin/wp-security-user-login-menu.php:659 +msgid "Click this button if you wish to download this log in CSV format." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1176 +#: admin/wp-security-firewall-menu.php:1185 +msgid "Delete all 404 event logs" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1182 +msgid "Click this button if you wish to purge all 404 event logs from the DB." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1241 +msgid "Custom .htaccess rules settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1248 +msgid "This feature can be used to apply your own custom .htaccess rules and directives." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1249 +msgid "It is useful for when you want to tweak our existing firewall rules or when you want to add your own." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1250 +msgid "NOTE: This feature can only be used if your site is hosted in an apache or similar web server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1256 +msgid "Warning: Only use this feature if you know what you are doing." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1257 +msgid "Incorrect .htaccess rules or directives can break or prevent access to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1258 +msgid "It is your responsibility to ensure that you are entering the correct code!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1259 +msgid "If you break your site you will need to access your server via FTP or something similar and then edit your .htaccess file and delete the changes you made." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1265 +msgid "Custom .htaccess rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1269 +msgid "Enable custom .htaccess rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1272 +msgid "Check this if you want to enable custom rules entered in the text box below" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1276 +msgid "Place custom rules at the top" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1279 +msgid "Check this if you want to place your custom rules at the beginning of all the rules applied by this plugin" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1283 +msgid "Enter custom .htaccess rules:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1287 +msgid "Enter your custom .htaccess rules/directives." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1292 +msgid "Save custom rules" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:338 +#: admin/wp-security-firewall-setup-notice.php:407 +#: admin/wp-security-firewall-setup-notice.php:479 +#: admin/wp-security-firewall-setup-notice.php:595 +#: wp-security.php:43 +msgid "All In One WP Security and Firewall" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:340 +msgid "We were unable to create the file necessary to give you the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:341 +msgid "Your firewall will have reduced protection which means some of your firewall's functionality will be unavailable." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:342 +msgid "If you would like to manually set up the necessary file, please follow these steps:" +msgstr "" + +#. translators: %s Bootstrap file name. +#. translators: %s Firewall file name. +#: admin/wp-security-firewall-setup-notice.php:346 +#: admin/wp-security-firewall-setup-notice.php:453 +msgid "1. Create a file with the name %s in the same directory as your WordPress install is in, i.e.:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:350 +msgid "2. Paste in the following code:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:352 +#: admin/wp-security-firewall-setup-notice.php:462 +msgid "3. Save the file and press the 'Try again' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:372 +msgid "1. Open the following file:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:378 +msgid "2. Look for the auto_prepend_file directive." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:382 +msgid "2. Look for the following:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:388 +msgid "3. Change it to the following:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:392 +msgid "4. Save the file and press the 'Try again' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:392 +#: admin/wp-security-firewall-setup-notice.php:441 +msgid "You may have to wait up to 5 minutes before the settings take effect." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:410 +msgid "Your firewall has been installed with the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:411 +msgid "You may have to wait 5 minutes for the changes to take effect." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:434 +msgid "1. Open your php.ini file." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:437 +msgid "2. Set the auto_prepend_file directive like below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:441 +msgid "3. Restart the webserver and refresh the page" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:458 +msgid "2. Paste in the following directives:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:482 +msgid "We were unable to set up your firewall with the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:483 +msgid "Your firewall will have reduced functionality." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:487 +msgid "To give your site the highest level of protection, please follow these steps:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:500 +msgid "Note: if you're unable to perform any of the aforementioned steps, please ask your web hosting provider for further assistance." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:517 +msgid "Try again" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:539 +msgid "We have detected that your AIOS firewall is not fully installed, and therefore does not have the highest level of protection. " +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:540 +msgid "Your firewall will have reduced functionality until it has been upgraded. " +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:542 +msgid "Upgrade your protection now" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:598 +msgid "Our PHP-based firewall has been created to give you even greater protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:602 +msgid "If you already have our .htaccess-based firewall enabled, you will still need to set up the PHP-based firewall to benefit from its protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:605 +msgid "To set up the PHP-based firewall, press the 'Set up now' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:608 +msgid "Set up now" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:614 +#: templates/notices/custom-notice.php:10 +#: templates/notices/custom-notice.php:12 +#: templates/notices/horizontal-notice.php:50 +#: templates/notices/horizontal-notice.php:52 +#: templates/notices/htaccess-to-php-feature-notice.php:10 +#: templates/notices/htaccess-to-php-feature-notice.php:12 +msgid "Dismiss" +msgstr "" + +#: admin/wp-security-list-404.php:91 +msgid "Event type" +msgstr "" + +#: admin/wp-security-list-404.php:92 +#: admin/wp-security-list-logged-in-users.php:46 +#: admin/wp-security-list-registered-users.php:74 +msgid "IP address" +msgstr "" + +#: admin/wp-security-list-404.php:93 +msgid "Attempted URL" +msgstr "" + +#: admin/wp-security-list-404.php:94 +msgid "Referer" +msgstr "" + +#: admin/wp-security-list-404.php:96 +msgid "Lock status" +msgstr "" + +#: admin/wp-security-list-404.php:118 +msgid "Temp block IP" +msgstr "" + +#: admin/wp-security-list-404.php:119 +msgid "Blacklist IP" +msgstr "" + +#: admin/wp-security-list-404.php:120 +#: admin/wp-security-list-acct-activity.php:82 +#: admin/wp-security-list-locked-ip.php:37 +#: admin/wp-security-list-locked-ip.php:84 +#: admin/wp-security-list-login-fails.php:73 +#: admin/wp-security-list-registered-users.php:93 +msgid "Delete" +msgstr "" + +#: admin/wp-security-list-404.php:128 +#: admin/wp-security-list-404.php:136 +#: admin/wp-security-list-404.php:143 +#: admin/wp-security-list-acct-activity.php:92 +#: admin/wp-security-list-comment-spammer-ip.php:95 +#: admin/wp-security-list-locked-ip.php:97 +#: admin/wp-security-list-locked-ip.php:105 +#: admin/wp-security-list-login-fails.php:85 +#: admin/wp-security-list-permanent-blocked-ip.php:96 +#: admin/wp-security-list-registered-users.php:107 +#: admin/wp-security-list-registered-users.php:115 +#: admin/wp-security-list-registered-users.php:123 +msgid "Please select some records using the checkboxes" +msgstr "" + +#: admin/wp-security-list-404.php:278 +msgid "Nonce check failed for delete selected 404 event logs operation!" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:35 +msgid "Are you sure you want to delete this item?" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:46 +msgid "Login session still active" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:60 +#: admin/wp-security-list-locked-ip.php:60 +#: admin/wp-security-list-logged-in-users.php:44 +#: admin/wp-security-list-login-fails.php:54 +#: admin/wp-security-list-registered-users.php:69 +msgid "User ID" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:61 +#: admin/wp-security-list-locked-ip.php:61 +#: admin/wp-security-list-login-fails.php:55 +msgid "Username" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:62 +msgid "Login date" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:63 +msgid "Logout date" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:136 +msgid "Nonce check failed for delete selected account activity logs operation!" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:59 +msgid "Spammer IP" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:60 +msgid "Number of spam comments from this IP" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:61 +msgid "Status" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:81 +msgid "Block" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:130 +#: admin/wp-security-list-comment-spammer-ip.php:179 +msgid "Nonce check failed for delete selected blocked IP operation!" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:137 +msgid "The selected IP addresses are now permanently blocked!" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:193 +msgid "The selected IP addresses were saved in the blacklist configuration settings." +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:201 +msgid "The .htaccess file was successfully modified to include the selected IP addresses." +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:212 +msgid "NOTE: The .htaccess file was not modified because you have disabled the \"Enable IP or User Agent Blacklisting\" check box." +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:213 +msgid "To block these IP addresses you will need to enable the above flag in the %s menu" +msgstr "" + +#: admin/wp-security-list-debug.php:47 +msgid "Level" +msgstr "" + +#: admin/wp-security-list-debug.php:48 +msgid "Message" +msgstr "" + +#: admin/wp-security-list-debug.php:49 +msgid "Type" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:36 +#: admin/wp-security-list-locked-ip.php:83 +msgid "Unlock" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:59 +msgid "Locked IP/range" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:62 +#: admin/wp-security-list-permanent-blocked-ip.php:67 +msgid "Reason" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:63 +msgid "Date locked" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:64 +msgid "Release date" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:134 +msgid "The selected IP entries were unlocked successfully." +msgstr "" + +#: admin/wp-security-list-locked-ip.php:140 +msgid "Nonce check failed for unlock IP operation!" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:147 +msgid "The selected IP entry was unlocked successfully." +msgstr "" + +#: admin/wp-security-list-logged-in-users.php:45 +#: admin/wp-security-list-registered-users.php:70 +msgid "Login name" +msgstr "" + +#: admin/wp-security-list-logged-in-users.php:87 +msgid "Nonce check failed for force user logout operation!" +msgstr "" + +#: admin/wp-security-list-logged-in-users.php:96 +msgid "The selected user was logged out successfully!" +msgstr "" + +#: admin/wp-security-list-login-fails.php:53 +msgid "Login IP range" +msgstr "" + +#: admin/wp-security-list-login-fails.php:130 +msgid "Nonce check failed for delete failed login record operation!" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:66 +msgid "Blocked IP" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:87 +msgid "Unblock" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:122 +#: admin/wp-security-list-permanent-blocked-ip.php:139 +msgid "Successfully unblocked and deleted the selected record(s)." +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:126 +#: admin/wp-security-list-permanent-blocked-ip.php:143 +msgid "Failed to unblock and delete the selected record(s)." +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:133 +msgid "Nonce check failed for unblock IP operation!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:71 +msgid "Email" +msgstr "" + +#: admin/wp-security-list-registered-users.php:72 +msgid "Register date" +msgstr "" + +#: admin/wp-security-list-registered-users.php:73 +msgid "Account status" +msgstr "" + +#: admin/wp-security-list-registered-users.php:92 +msgid "Approve" +msgstr "" + +#: admin/wp-security-list-registered-users.php:94 +msgid "Block IP" +msgstr "" + +#: admin/wp-security-list-registered-users.php:159 +msgid "The selected accounts were approved successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:163 +msgid "The following accounts failed to update successfully: " +msgstr "" + +#: admin/wp-security-list-registered-users.php:171 +msgid "The selected account was approved successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:190 +msgid "Your account is now active" +msgstr "" + +#: admin/wp-security-list-registered-users.php:191 +msgid "Your account with username: " +msgstr "" + +#: admin/wp-security-list-registered-users.php:191 +msgid " is now active" +msgstr "" + +#: admin/wp-security-list-registered-users.php:222 +msgid "The selected accounts were deleted successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:230 +msgid "Nonce check failed for delete registered user account operation!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:238 +msgid "The selected account was deleted successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:264 +msgid "The selected IP addresses were successfully added to the permanent block list!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:265 +#: admin/wp-security-list-registered-users.php:282 +msgid "View Blocked IPs" +msgstr "" + +#: admin/wp-security-list-registered-users.php:274 +msgid "Nonce check failed for block IP operation of registered user!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:281 +msgid "The selected IP was successfully added to the permanent block list!" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:25 +msgid "Visitor lockout" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:85 +msgid "Site lockout feature settings saved!" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:92 +msgid "General visitor lockout" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:98 +msgid "This feature allows you to put your site into \"maintenance mode\" by locking down the front-end to all visitors except logged in users with super admin privileges." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:99 +msgid "Locking your site down to general visitors can be useful if you are investigating some issues on your site or perhaps you might be doing some maintenance and wish to keep out all traffic for security reasons." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:104 +msgid "Enable front-end lockout" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:107 +msgid "Check this if you want all visitors except those who are logged in as administrator to be locked out of the front-end of your site." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:111 +msgid "Enter a message:" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:123 +msgid "Enter a message you wish to display to visitors when your site is in maintenance mode." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:130 +msgid "Save site lockout settings" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:28 +msgid "Copy protection" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:29 +msgid "Frames" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:30 +msgid "Users enumeration" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:31 +msgid "WP REST API" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:89 +msgid "Copy Protection feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:94 +msgid "Disable the ability to copy text" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:100 +msgid "This feature allows you to disable the ability to select and copy text from your front end." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:101 +msgid "When admin user is logged in, the feature is automatically disabled for his session." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:106 +msgid "Enable copy protection" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:109 +msgid "Check this if you want to disable the \"Right click\", \"Text selection\" and \"Copy\" option on the front end of your site." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:116 +msgid "Save copy protection settings" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:140 +msgid "Frame Display Prevention feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:145 +msgid "Prevent your site from being displayed in a frame" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:151 +msgid "This feature allows you to prevent other sites from displaying any of your content via a frame or iframe." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:152 +msgid "When enabled, this feature will set the \"X-Frame-Options\" parameter to \"sameorigin\" in the HTTP header." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:157 +msgid "Enable iFrame protection" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:160 +msgid "Check this if you want to stop other sites from displaying your content in a frame or iframe." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:191 +msgid "Users Enumeration Prevention feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:196 +msgid "Prevent users enumeration" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:202 +msgid "This feature allows you to prevent external users/bots from fetching the user info with urls like \"/?author=1\"." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:203 +msgid "When enabled, this feature will print a \"forbidden\" error rather than the user information." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:208 +msgid "Disable users enumeration" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:211 +msgid "Check this if you want to stop users enumeration." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:242 +msgid "WP REST API Security feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:253 +msgid "This feature allows you to block WordPress REST API access for unauthorized requests." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:254 +msgid "When enabled this feature will only allow REST requests to be processed if the user is logged in." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:260 +msgid "Beware that if you are using other plugins which have registered REST endpoints (eg, Contact Form 7), then this feature will also block REST requests used by these plugins if the user is not logged in. It is recommended that you leave this feature disabled if you want uninterrupted functionality for such plugins." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:268 +msgid "Disallow unauthorized REST requests" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:271 +msgid "Check this if you want to stop REST API access for non-logged in requests." +msgstr "" + +#: admin/wp-security-settings-menu.php:25 +msgid "General settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:29 +#: admin/wp-security-settings-menu.php:33 +msgid "file" +msgstr "" + +#: admin/wp-security-settings-menu.php:37 +msgid "Delete plugin settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:41 +msgid "WP version info" +msgstr "" + +#: admin/wp-security-settings-menu.php:45 +msgid "Import/Export" +msgstr "" + +#: admin/wp-security-settings-menu.php:52 +msgid "Advanced settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:128 +msgid "All the security features have been disabled successfully!" +msgstr "" + +#: admin/wp-security-settings-menu.php:132 +#: admin/wp-security-settings-menu.php:159 +msgid "Could not write to the .htaccess file. Please restore your .htaccess file manually using the restore functionality in the \".htaccess File\"." +msgstr "" + +#: admin/wp-security-settings-menu.php:137 +msgid "Could not write to the wp-config.php. Please restore your wp-config.php file manually using the restore functionality in the \"wp-config.php File\"." +msgstr "" + +#: admin/wp-security-settings-menu.php:155 +msgid "All firewall rules have been disabled successfully!" +msgstr "" + +#: admin/wp-security-settings-menu.php:177 +msgid "Deletion of aio_wp_security_configs option and .htaccess directives failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:179 +msgid "Reset of aio_wp_security_configs option failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:181 +msgid "Deletion of .htaccess directives failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:183 +msgid "All settings have been successfully reset." +msgstr "" + +#: admin/wp-security-settings-menu.php:203 +msgid "For information, updates and documentation, please visit the" +msgstr "" + +#: admin/wp-security-settings-menu.php:203 +msgid "Page" +msgstr "" + +#: admin/wp-security-settings-menu.php:204 +msgid "Follow us" +msgstr "" + +#: admin/wp-security-settings-menu.php:204 +msgid "on Twitter, Google+ or via Email to stay up to date about the new security features of this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:208 +msgid "WP Security plugin" +msgstr "" + +#: admin/wp-security-settings-menu.php:212 +msgid "Thank you for using the AIOS security plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:216 +msgid "There are a lot of security features in this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:221 +msgid "To start, go through each security option and enable the \"basic\" options." +msgstr "" + +#: admin/wp-security-settings-menu.php:225 +msgid "The more features you enable, the more security points you will achieve." +msgstr "" + +#: admin/wp-security-settings-menu.php:228 +msgid "Before doing anything we advise taking a backup of your .htaccess file, database and wp-config.php." +msgstr "" + +#: admin/wp-security-settings-menu.php:231 +msgid "Backup your database" +msgstr "" + +#: admin/wp-security-settings-menu.php:232 +#: admin/wp-security-settings-menu.php:433 +msgid "Backup .htaccess file" +msgstr "" + +#: admin/wp-security-settings-menu.php:233 +#: admin/wp-security-settings-menu.php:534 +msgid "Backup wp-config.php file" +msgstr "" + +#: admin/wp-security-settings-menu.php:240 +msgid "Disable security features" +msgstr "" + +#: admin/wp-security-settings-menu.php:246 +msgid "If you think that some plugin functionality on your site is broken due to a security feature you enabled in this plugin, then use the following option to turn off all the security features of this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:250 +msgid "Disable all security features" +msgstr "" + +#: admin/wp-security-settings-menu.php:257 +#: admin/wp-security-settings-menu.php:267 +msgid "Disable all firewall rules" +msgstr "" + +#: admin/wp-security-settings-menu.php:263 +msgid "This feature will disable all firewall rules which are currently active in this plugin and it will also delete these rules from your .htacess file. Use it if you think one of the firewall rules is causing an issue on your site." +msgstr "" + +#: admin/wp-security-settings-menu.php:274 +#: admin/wp-security-settings-menu.php:287 +msgid "Reset settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:279 +msgid "This button click will delete all of your settings related to the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:280 +msgid "This button click will reset/empty all the database tables of the security plugin also." +msgstr "" + +#: admin/wp-security-settings-menu.php:281 +msgid "Use this plugin if you were locked out by the All In One WP Security & Firewall Plugin and/or you are having issues logging in when that plugin is activated." +msgstr "" + +#: admin/wp-security-settings-menu.php:282 +msgid "In addition to the settings it will also delete any directives which were added to the .htaccess file by the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:283 +msgid "%1$sNOTE: %2$sAfter deleting the settings you will need to re-configure the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:295 +msgid "Debug settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:301 +msgid "This setting allows you to enable/disable debug for this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:307 +msgid "Enable debug" +msgstr "" + +#: admin/wp-security-settings-menu.php:310 +msgid "Check this if you want to enable debug. You should keep this option disabled after you have finished debugging the issue." +msgstr "" + +#: admin/wp-security-settings-menu.php:314 +msgid "Save debug settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:350 +msgid "Your .htaccess file was successfully backed up! Using an FTP program go to the \"/wp-content/aiowps_backups\" directory to save a copy of the file to your computer." +msgstr "" + +#: admin/wp-security-settings-menu.php:356 +msgid "htaccess file rename failed during backup. Please check your root directory for the backup file using FTP." +msgstr "" + +#: admin/wp-security-settings-menu.php:362 +msgid "htaccess backup failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:377 +msgid "Please choose a .htaccess to restore from." +msgstr "" + +#: admin/wp-security-settings-menu.php:392 +msgid "htaccess file restore failed. Please attempt to restore the .htaccess manually using FTP." +msgstr "" + +#: admin/wp-security-settings-menu.php:396 +msgid "Your .htaccess file has successfully been restored!" +msgstr "" + +#: admin/wp-security-settings-menu.php:402 +msgid "htaccess Restore operation failed! Please check the contents of the file you are trying to restore from." +msgstr "" + +#: admin/wp-security-settings-menu.php:408 +msgid ".htaccess file operations" +msgstr "" + +#: admin/wp-security-settings-menu.php:411 +msgid "Your \".htaccess\" file is a key component of your website's security and it can be modified to implement various levels of protection mechanisms." +msgstr "" + +#: admin/wp-security-settings-menu.php:412 +msgid "This feature allows you to backup and save your currently active .htaccess file should you need to re-use the the backed up file in the future." +msgstr "" + +#: admin/wp-security-settings-menu.php:413 +msgid "You can also restore your site's .htaccess settings using a backed up .htaccess file." +msgstr "" + +#: admin/wp-security-settings-menu.php:428 +msgid "Save the current .htaccess file" +msgstr "" + +#: admin/wp-security-settings-menu.php:432 +msgid "Click the button below to backup and save the currently active .htaccess file." +msgstr "" + +#: admin/wp-security-settings-menu.php:437 +msgid "Restore from a backed up .htaccess file" +msgstr "" + +#: admin/wp-security-settings-menu.php:443 +msgid ".htaccess file to restore from" +msgstr "" + +#: admin/wp-security-settings-menu.php:445 +msgid "Select Your htaccess File" +msgstr "" + +#: admin/wp-security-settings-menu.php:449 +msgid "After selecting your file, click the button below to restore your site using the backed up htaccess file (htaccess_backup.txt)." +msgstr "" + +#: admin/wp-security-settings-menu.php:455 +msgid "Restore .htaccess file" +msgstr "" + +#: admin/wp-security-settings-menu.php:477 +msgid "Please choose a wp-config.php file to restore from." +msgstr "" + +#: admin/wp-security-settings-menu.php:493 +msgid "wp-config.php file restore failed. Please attempt to restore this file manually using FTP." +msgstr "" + +#: admin/wp-security-settings-menu.php:497 +msgid "Your wp-config.php file has successfully been restored!" +msgstr "" + +#: admin/wp-security-settings-menu.php:503 +msgid "wp-config.php Restore operation failed! Please check the contents of the file you are trying to restore from." +msgstr "" + +#: admin/wp-security-settings-menu.php:509 +msgid "wp-config.php file operations" +msgstr "" + +#: admin/wp-security-settings-menu.php:512 +msgid "Your \"wp-config.php\" file is one of the most important in your WordPress installation. It is a primary configuration file and contains crucial things such as details of your database and other critical components." +msgstr "" + +#: admin/wp-security-settings-menu.php:513 +msgid "This feature allows you to backup and save your currently active wp-config.php file should you need to re-use the the backed up file in the future." +msgstr "" + +#: admin/wp-security-settings-menu.php:514 +msgid "You can also restore your site's wp-config.php settings using a backed up wp-config.php file." +msgstr "" + +#: admin/wp-security-settings-menu.php:529 +msgid "Save the current wp-config.php file" +msgstr "" + +#: admin/wp-security-settings-menu.php:533 +msgid "Click the button below to backup and download the contents of the currently active wp-config.php file." +msgstr "" + +#: admin/wp-security-settings-menu.php:539 +msgid "Restore from a backed up wp-config file" +msgstr "" + +#: admin/wp-security-settings-menu.php:545 +msgid "wp-config file to restore from" +msgstr "" + +#: admin/wp-security-settings-menu.php:547 +msgid "Select Your wp-config File" +msgstr "" + +#: admin/wp-security-settings-menu.php:551 +msgid "After selecting your file click the button below to restore your site using the backed up wp-config file (wp-config.php.backup.txt)." +msgstr "" + +#: admin/wp-security-settings-menu.php:557 +msgid "Restore wp-config file" +msgstr "" + +#: admin/wp-security-settings-menu.php:591 +msgid "Manage delete plugin settings saved." +msgstr "" + +#: admin/wp-security-settings-menu.php:596 +msgid "Manage delete plugin tasks" +msgstr "" + +#: admin/wp-security-settings-menu.php:603 +msgid "Delete database tables" +msgstr "" + +#: admin/wp-security-settings-menu.php:606 +msgid "Check this if you want to remove database tables when the plugin is uninstalled." +msgstr "" + +#: admin/wp-security-settings-menu.php:610 +msgid "Delete settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:613 +msgid "Check this if you want to remove all plugin settings when uninstalling the plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:613 +msgid "It will also remove all custom htaccess rules that were added by this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:647 +msgid "WP generator meta tag and version info" +msgstr "" + +#: admin/wp-security-settings-menu.php:650 +msgid "WordPress generator automatically adds some meta information inside the \"head\" tags of every page on your site's front end. Below is an example of this:" +msgstr "" + +#: admin/wp-security-settings-menu.php:652 +msgid "The above meta information shows which version of WordPress your site is currently running and thus can help hackers or crawlers scan your site to see if you have an older version of WordPress or one with a known exploit." +msgstr "" + +#: admin/wp-security-settings-menu.php:653 +msgid "There are also other ways wordpress reveals version info such as during style and script loading. An example of this is:" +msgstr "" + +#: admin/wp-security-settings-menu.php:655 +msgid "This feature will allow you to remove the WP generator meta info and other version info from your site's pages." +msgstr "" + +#: admin/wp-security-settings-menu.php:661 +msgid "WP generator meta info" +msgstr "" + +#: admin/wp-security-settings-menu.php:673 +msgid "Remove WP generator meta info" +msgstr "" + +#: admin/wp-security-settings-menu.php:676 +msgid "Check this if you want to remove the version and meta info produced by WP from all pages" +msgstr "" + +#: admin/wp-security-settings-menu.php:704 +msgid "Please choose a file to import your settings from." +msgstr "" + +#: admin/wp-security-settings-menu.php:736 +msgid "Import AIOS settings from " +msgstr "" + +#: admin/wp-security-settings-menu.php:742 +#: admin/wp-security-settings-menu.php:786 +msgid "The deletion of the import file failed. Please delete this file manually via the media menu for security purposes." +msgstr "" + +#: admin/wp-security-settings-menu.php:744 +#: admin/wp-security-settings-menu.php:788 +msgid "The file you uploaded was also deleted for security purposes because it contains security settings details." +msgstr "" + +#: admin/wp-security-settings-menu.php:759 +msgid "Your AIOS settings were successfully imported via file input." +msgstr "" + +#: admin/wp-security-settings-menu.php:760 +msgid "The deletion of the import file failed. Please delete this file manually via the media menu for security purposes because it contains security settings details." +msgstr "" + +#: admin/wp-security-settings-menu.php:762 +msgid "Your AIOS settings were successfully imported. The file you uploaded was also deleted for security purposes because it contains security settings details." +msgstr "" + +#: admin/wp-security-settings-menu.php:765 +msgid "Your AIOS settings were successfully imported via text entry." +msgstr "" + +#: admin/wp-security-settings-menu.php:780 +msgid "The contents of your settings file appear invalid. Please check the contents of the file you are trying to import settings from." +msgstr "" + +#: admin/wp-security-settings-menu.php:797 +msgid "Export or import your AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:800 +msgid "This section allows you to export or import your All In One WP Security & Firewall settings." +msgstr "" + +#: admin/wp-security-settings-menu.php:801 +msgid "This can be handy if you wanted to save time by applying the settings from one site to another site." +msgstr "" + +#: admin/wp-security-settings-menu.php:802 +msgid "NOTE: Before importing, it is your responsibility to know what settings you are trying to import. Importing settings blindly can cause you to be locked out of your site." +msgstr "" + +#: admin/wp-security-settings-menu.php:803 +msgid "For Example: If a settings item relies on the domain URL then it may not work correctly when imported into a site with a different domain." +msgstr "" + +#: admin/wp-security-settings-menu.php:809 +#: admin/wp-security-settings-menu.php:818 +msgid "Export AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:815 +msgid "To export your All In One WP Security & Firewall settings click the button below." +msgstr "" + +#: admin/wp-security-settings-menu.php:822 +#: admin/wp-security-settings-menu.php:851 +msgid "Import AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:828 +msgid "Use this section to import your All In One WP Security & Firewall settings from a file. Alternatively, copy/paste the contents of your import file into the textarea below." +msgstr "" + +#: admin/wp-security-settings-menu.php:830 +msgid "Import file" +msgstr "" + +#: admin/wp-security-settings-menu.php:833 +msgid "Select Your Import Settings File" +msgstr "" + +#: admin/wp-security-settings-menu.php:837 +msgid "After selecting your file, click the button below to apply the settings to your site." +msgstr "" + +#: admin/wp-security-settings-menu.php:844 +msgid "Copy/Paste import data" +msgstr "" + +#: admin/wp-security-settings-menu.php:893 +msgid "Default - if correct, then this is the best option" +msgstr "" + +#: admin/wp-security-settings-menu.php:894 +msgid "Only use if you're using Cloudflare." +msgstr "" + +#: admin/wp-security-settings-menu.php:902 +msgid "(current value: %s)" +msgstr "" + +#: admin/wp-security-settings-menu.php:905 +msgid "no value (i.e. empty) on your server" +msgstr "" + +#: admin/wp-security-spam-menu.php:28 +msgid "Comment spam" +msgstr "" + +#: admin/wp-security-spam-menu.php:29 +msgid "Comment spam IP monitoring" +msgstr "" + +#: admin/wp-security-spam-menu.php:30 +msgid "BuddyPress" +msgstr "" + +#: admin/wp-security-spam-menu.php:31 +msgid "bbPress" +msgstr "" + +#: admin/wp-security-spam-menu.php:57 +msgid "Spam prevention" +msgstr "" + +#: admin/wp-security-spam-menu.php:99 +msgid "You entered a non numeric value for the \"move spam comments to trash after number of days\" field." +msgstr "" + +#: admin/wp-security-spam-menu.php:99 +#: admin/wp-security-spam-menu.php:297 +#: admin/wp-security-user-login-menu.php:118 +#: admin/wp-security-user-login-menu.php:124 +#: admin/wp-security-user-login-menu.php:130 +#: admin/wp-security-user-login-menu.php:136 +msgid "It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:129 +msgid "Comment spam settings" +msgstr "" + +#: admin/wp-security-spam-menu.php:134 +msgid "Add CAPTCHA to comments form" +msgstr "" + +#: admin/wp-security-spam-menu.php:138 +msgid "This feature will add a CAPTCHA field in the WordPress comments form." +msgstr "" + +#: admin/wp-security-spam-menu.php:139 +msgid "Adding a CAPTCHA field in the comment form is a simple way of greatly reducing spam comments from bots without using .htaccess rules." +msgstr "" + +#: admin/wp-security-spam-menu.php:148 +msgid "Enable CAPTCHA on comment forms" +msgstr "" + +#: admin/wp-security-spam-menu.php:151 +msgid "Check this if you want to insert a CAPTCHA field on the comment forms." +msgstr "" + +#: admin/wp-security-spam-menu.php:158 +msgid "Block spambot comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:162 +msgid "A large portion of WordPress blog comment spam is mainly produced by automated bots and not necessarily by humans." +msgstr "" + +#: admin/wp-security-spam-menu.php:163 +msgid "This feature will greatly minimize the useless and unnecessary traffic and load on your server resulting from spam comments by blocking all comment requests which do not originate from your domain." +msgstr "" + +#: admin/wp-security-spam-menu.php:164 +msgid "In other words, if the comment was not submitted by a human who physically submitted the comment on your site, the request will be blocked." +msgstr "" + +#: admin/wp-security-spam-menu.php:182 +msgid "Block spambots from posting comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:185 +msgid "Check this if you want to apply a firewall rule which will block comments originating from spambots." +msgstr "" + +#: admin/wp-security-spam-menu.php:189 +msgid "This feature will implement a firewall rule to block all comment attempts which do not originate from your domain." +msgstr "" + +#: admin/wp-security-spam-menu.php:190 +msgid "A legitimate comment is one which is submitted by a human who physically fills out the comment form and clicks the submit button. For such events, the HTTP_REFERRER is always set to your own domain." +msgstr "" + +#: admin/wp-security-spam-menu.php:191 +msgid "A comment submitted by a spambot is done by directly calling the comments.php file, which usually means that the HTTP_REFERRER value is not your domain and often times empty." +msgstr "" + +#: admin/wp-security-spam-menu.php:192 +msgid "This feature will check and block comment requests which are not referred by your domain thus greatly reducing your overall blog spam and PHP requests done by the server to process these comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:202 +msgid "Comment processing" +msgstr "" + +#: admin/wp-security-spam-menu.php:207 +msgid "Trash spam comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:216 +msgid "Move spam comments to trash after %s days." +msgstr "" + +#: admin/wp-security-spam-menu.php:224 +msgid "Enable this feature in order to move the spam comments to trash after given number of days." +msgstr "" + +#: admin/wp-security-spam-menu.php:262 +msgid "You entered a non numeric value for the minimum number of spam comments field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:265 +msgid "You must enter an integer greater than zero for minimum number of spam comments field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:292 +msgid "Nonce check failed for list spam comment IPs." +msgstr "" + +#: admin/wp-security-spam-menu.php:297 +msgid "You entered a non numeric value for the minimum spam comments per IP field." +msgstr "" + +#: admin/wp-security-spam-menu.php:308 +msgid "Displaying results for IP addresses which have posted a minimum of %s spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:323 +msgid "Auto block spammer IPs" +msgstr "" + +#: admin/wp-security-spam-menu.php:328 +msgid "This feature has detected that %s is not active. It is highly recommended that you activate the Akismet plugin to make the most of this feature." +msgstr "" + +#: admin/wp-security-spam-menu.php:337 +msgid "This feature allows you to automatically and permanently block IP addresses which have exceeded a certain number of comments labelled as spam." +msgstr "" + +#: admin/wp-security-spam-menu.php:338 +msgid "Comments are usually labelled as spam either by the Akismet plugin or manually by the WP administrator when they mark a comment as \"spam\" from the WordPress Comments menu." +msgstr "" + +#: admin/wp-security-spam-menu.php:352 +msgid "You currently have no IP addresses permanently blocked due to spam." +msgstr "" + +#: admin/wp-security-spam-menu.php:365 +msgid "Spammer IPs added to permanent block list today: " +msgstr "" + +#: admin/wp-security-spam-menu.php:366 +msgid "All time total: " +msgstr "" + +#: admin/wp-security-spam-menu.php:367 +msgid "View blocked IPs" +msgstr "" + +#: admin/wp-security-spam-menu.php:380 +msgid "Enable auto block of spam comment IPs" +msgstr "" + +#: admin/wp-security-spam-menu.php:383 +msgid "Check this box if you want this plugin to automatically block IP addresses which submit spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:387 +msgid "Minimum number of spam comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:389 +msgid "Specify the minimum number of spam comments for an IP address before it is permanently blocked." +msgstr "" + +#: admin/wp-security-spam-menu.php:393 +msgid "Example 1: Setting this value to \"1\" will block ALL IP addresses which were used to submit at least one spam comment." +msgstr "" + +#: admin/wp-security-spam-menu.php:394 +msgid "Example 2: Setting this value to \"5\" will block only those IP addresses which were used to submit 5 spam comments or more on your site." +msgstr "" + +#: admin/wp-security-spam-menu.php:412 +msgid "List spammer IP addresses" +msgstr "" + +#: admin/wp-security-spam-menu.php:416 +msgid "This section displays a list of the IP addresses of the people or bots who have left spam comments on your site." +msgstr "" + +#: admin/wp-security-spam-menu.php:417 +msgid "This information can be handy for identifying the most persistent IP addresses or ranges used by spammers." +msgstr "" + +#: admin/wp-security-spam-menu.php:418 +msgid "By inspecting the IP address data coming from spammers you will be in a better position to determine which addresses or address ranges you should block by adding them to the permanent block list." +msgstr "" + +#: admin/wp-security-spam-menu.php:419 +msgid "To add one or more of the IP addresses displayed in the table below to your blacklist, simply click the \"Block\" link for the individual row or select more than one address using the checkboxes and then choose the \"block\" option from the Bulk Actions dropdown list and click the \"Apply\" button." +msgstr "" + +#: admin/wp-security-spam-menu.php:427 +msgid "Minimum number of spam comments per IP" +msgstr "" + +#: admin/wp-security-spam-menu.php:429 +msgid "This field allows you to list only those IP addresses which have been used to post X or more spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:433 +msgid "Example 1: Setting this value to \"0\" or \"1\" will list ALL IP addresses which were used to submit spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:434 +msgid "Example 2: Setting this value to \"5\" will list only those IP addresses which were used to submit 5 spam comments or more on your site." +msgstr "" + +#: admin/wp-security-spam-menu.php:441 +msgid "Find IP addresses" +msgstr "" + +#: admin/wp-security-spam-menu.php:445 +msgid "Spammer IP address results" +msgstr "" + +#: admin/wp-security-spam-menu.php:451 +#: classes/wp-security-utility.php:253 +msgid "The plugin has detected that you are using a Multi-Site WordPress installation." +msgstr "" + +#: admin/wp-security-spam-menu.php:452 +msgid "Only the \"superadmin\" can block IP addresses from the main site." +msgstr "" + +#: admin/wp-security-spam-menu.php:453 +msgid "Take note of the IP addresses you want blocked and ask the superadmin to add these to the blacklist using the \"Blacklist Manager\" on the main site." +msgstr "" + +#: admin/wp-security-spam-menu.php:498 +msgid "BuddyPress spam settings" +msgstr "" + +#: admin/wp-security-spam-menu.php:503 +msgid "Add CAPTCHA to BuddyPress registration form" +msgstr "" + +#: admin/wp-security-spam-menu.php:507 +msgid "This feature will add a simple math CAPTCHA field in the BuddyPress registration form." +msgstr "" + +#: admin/wp-security-spam-menu.php:508 +msgid "Adding a CAPTCHA field in the registration form is a simple way of greatly reducing spam signups from bots without using .htaccess rules." +msgstr "" + +#: admin/wp-security-spam-menu.php:518 +msgid "Enable CAPTCHA on BuddyPress registration form" +msgstr "" + +#: admin/wp-security-spam-menu.php:521 +msgid "Check this if you want to insert a CAPTCHA field on the BuddyPress registration forms." +msgstr "" + +#: admin/wp-security-spam-menu.php:530 +msgid "BuddyPress is not active! In order to use this feature you will need to have BuddyPress installed and activated." +msgstr "" + +#: admin/wp-security-spam-menu.php:560 +msgid "bbPress spam settings" +msgstr "" + +#: admin/wp-security-spam-menu.php:565 +msgid "Add CAPTCHA to bbPress new topic form" +msgstr "" + +#: admin/wp-security-spam-menu.php:569 +msgid "This feature will add a simple math CAPTCHA field in the bbPress new topic form." +msgstr "" + +#: admin/wp-security-spam-menu.php:570 +msgid "Adding a CAPTCHA field in this form is a simple way of greatly reducing spam submitted from bots." +msgstr "" + +#: admin/wp-security-spam-menu.php:580 +msgid "Enable CAPTCHA on bbPress new topic form" +msgstr "" + +#: admin/wp-security-spam-menu.php:583 +msgid "Check this if you want to insert a CAPTCHA field on the bbPress new topic forms." +msgstr "" + +#: admin/wp-security-spam-menu.php:592 +msgid "bbPress is not active. In order to use this feature you will need to have bbPress installed and activated." +msgstr "" + +#: admin/wp-security-tools-menu.php:34 +msgid "WHOIS lookup" +msgstr "" + +#: admin/wp-security-tools-menu.php:95 +#: admin/wp-security-tools-menu.php:136 +msgid "Querying %s: %s" +msgstr "" + +#: admin/wp-security-tools-menu.php:103 +#: admin/wp-security-tools-menu.php:112 +#: admin/wp-security-tools-menu.php:151 +msgid "Redirected to %s" +msgstr "" + +#: admin/wp-security-tools-menu.php:173 +msgid "The WHOIS lookup feature gives you a way to look up who owns an IP address or domain name." +msgstr "" + +#: admin/wp-security-tools-menu.php:173 +msgid "You can use this to investigate users engaging in malicious activity on your site." +msgstr "" + +#: admin/wp-security-tools-menu.php:176 +msgid "WHOIS lookup on IP or domain" +msgstr "" + +#: admin/wp-security-tools-menu.php:183 +msgid "IP address or domain name:" +msgstr "" + +#: admin/wp-security-tools-menu.php:190 +msgid "Look up IP or domain" +msgstr "" + +#: admin/wp-security-tools-menu.php:219 +msgid "Please enter a valid IP address or domain name to look up." +msgstr "" + +#: admin/wp-security-tools-menu.php:220 +#: admin/wp-security-tools-menu.php:226 +msgid "Nothing to show." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:32 +msgid "WP username" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:33 +msgid "Display name" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:34 +msgid "Password" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:60 +msgid "User accounts" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:82 +msgid "Admin user security" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:85 +msgid "By default, WordPress sets the administrator username to \"admin\" at installation time." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:86 +msgid "A lot of hackers try to take advantage of this information by attempting \"Brute force login attacks\" where they repeatedly try to guess the password by using \"admin\" for username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:87 +msgid "From a security perspective, changing the default \"admin\" user name is one of the first and smartest things you should do on your site." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:88 +msgid "This feature will allow you to change your default \"admin\" user name to a more secure name of your choosing." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:95 +msgid "List of administrator accounts" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:104 +#: classes/grade-system/wp-security-feature-item-manager.php:43 +msgid "Change admin username" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:112 +msgid "Your site currently has an account which uses the default \"admin\" username. It is highly recommended that you change this name to something else. Use the following field to change the admin username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:118 +msgid "New admin username" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:120 +msgid "Choose a new username for admin." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:124 +msgid "Change username" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:126 +msgid "NOTE: If you are currently logged in as \"admin\" you will be automatically logged out after changing your username and will be required to log back in." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:133 +msgid "No action required! " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:135 +msgid "Your site does not have any account which uses the default \"admin\" username. " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:136 +msgid "This is good security practice." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:148 +msgid "Display name security" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:151 +msgid "When you submit a post or answer a comment, WordPress will usually display your \"nickname\"." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:152 +msgid "By default the nickname is set to the login (or user) name of your account." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:153 +msgid "From a security perspective, leaving your nickname the same as your user name is bad practice because it gives a hacker at least half of your account's login credentials." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:154 +msgid "Therefore to further tighten your site's security you are advised to change your nickname and Display name to be different from your Username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:160 +msgid "Modify accounts with identical login name and display name" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:169 +msgid "Your site currently has the following accounts which have an identical login name and display name." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:170 +msgid "Follow the link to edit the user profile of that particular user account, change Nickname, choose a different Display name compared to Username, and press the \"Update User\" button.)" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:185 +msgid "No action required." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:186 +msgid "Your site does not have a user account where the display name is identical to the username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:197 +msgid "Password tool" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:200 +msgid "Poor password selection is one of the most common weak points of many sites and is usually the first thing a hacker will try to exploit when attempting to break into your site." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:201 +msgid "Many people fall into the trap of using a simple word or series of numbers as their password. Such a predictable and simple password would take a competent hacker merely minutes to guess your password by using a simple script which cycles through the easy and most common combinations." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:202 +msgid "The longer and more complex your password is the harder it is for hackers to \"crack\" because more complex passwords require much greater computing power and time." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:203 +msgid "This section contains a useful password strength tool which you can use to check whether your password is sufficiently strong enough." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:208 +msgid "Password strength tool" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:210 +msgid "This password tool uses an algorithm which calculates how long it would take for your password to be cracked using the computing power of an off-the-shelf current model desktop PC with high end processor, graphics card and appropriate password cracking software." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:213 +msgid "Start typing a password." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:216 +msgid "It would take a desktop PC approximately" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:217 +msgid "1 sec" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:217 +msgid "to crack your password!" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:222 +msgid "Password Strength" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:245 +msgid "Username " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:245 +msgid " already exists. Please enter another value. " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:262 +msgid "The database update operation of the user account failed!" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:291 +msgid "You entered an invalid username. Please enter another value. " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:295 +msgid "Please enter a value for your username. " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:302 +msgid "Username successfully changed." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:322 +msgid "Account login name" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:331 +msgid "Edit user" +msgstr "" + +#: admin/wp-security-user-login-menu.php:54 +#: admin/wp-security-user-login-menu.php:474 +msgid "Failed login records" +msgstr "" + +#: admin/wp-security-user-login-menu.php:55 +#: classes/grade-system/wp-security-feature-item-manager.php:51 +msgid "Force logout" +msgstr "" + +#: admin/wp-security-user-login-menu.php:56 +#: admin/wp-security-user-login-menu.php:632 +msgid "Account activity logs" +msgstr "" + +#: admin/wp-security-user-login-menu.php:58 +#: admin/wp-security-user-login-menu.php:769 +msgid "Additional settings" +msgstr "" + +#: admin/wp-security-user-login-menu.php:81 +msgid "User login" +msgstr "" + +#: admin/wp-security-user-login-menu.php:118 +msgid "You entered a non-numeric value for the max login attempts field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:124 +msgid "You entered a non numeric value for the login retry time period field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:130 +msgid "You entered a non numeric value for the lockout time length field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:136 +msgid "You entered a non numeric value for the maximum lockout time length field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:141 +msgid "You entered an invalid minimum lockout time length, it must be less than the maximum lockout time length value." +msgstr "" + +#: admin/wp-security-user-login-menu.php:141 +msgid "Both have been set to the default values." +msgstr "" + +#: admin/wp-security-user-login-menu.php:160 +msgid "Please fill in one or more email addresses to notify." +msgstr "" + +#: admin/wp-security-user-login-menu.php:162 +msgid "You have entered one or more invalid email addresses." +msgstr "" + +#: admin/wp-security-user-login-menu.php:165 +msgid "It has been set to your WordPress admin email as default." +msgstr "" + +#: admin/wp-security-user-login-menu.php:250 +msgid "Login lockout configuration" +msgstr "" + +#: admin/wp-security-user-login-menu.php:254 +msgid "One of the ways hackers try to compromise sites is via a " +msgstr "" + +#: admin/wp-security-user-login-menu.php:254 +msgid "Brute force login attack" +msgstr "" + +#: admin/wp-security-user-login-menu.php:254 +msgid "This is where attackers use repeated login attempts until they guess the password." +msgstr "" + +#: admin/wp-security-user-login-menu.php:255 +msgid "Apart from choosing strong passwords, monitoring and blocking IP addresses which are involved in repeated login failures in a short period of time is a very effective way to stop these types of attacks." +msgstr "" + +#: admin/wp-security-user-login-menu.php:256 +msgid "You may also want to checkout our %s feature for another secure way to protect against these types of attacks." +msgstr "" + +#: admin/wp-security-user-login-menu.php:261 +msgid "Login lockout options" +msgstr "" + +#: admin/wp-security-user-login-menu.php:272 +msgid "Enable login lockout feature" +msgstr "" + +#: admin/wp-security-user-login-menu.php:275 +msgid "Check this if you want to enable the login lockout feature and apply the settings below" +msgstr "" + +#: admin/wp-security-user-login-menu.php:279 +msgid "Allow unlock requests" +msgstr "" + +#: admin/wp-security-user-login-menu.php:282 +msgid "Check this if you want to allow users to generate an automated unlock request link which will unlock their account" +msgstr "" + +#: admin/wp-security-user-login-menu.php:286 +msgid "Max login attempts" +msgstr "" + +#: admin/wp-security-user-login-menu.php:288 +msgid "Set the value for the maximum login retries before IP address is locked out" +msgstr "" + +#: admin/wp-security-user-login-menu.php:292 +msgid "Login retry time period (min)" +msgstr "" + +#: admin/wp-security-user-login-menu.php:294 +msgid "If the maximum number of failed login attempts for a particular IP address occur within this time period the plugin will lock out that address" +msgstr "" + +#: admin/wp-security-user-login-menu.php:299 +msgid "Minimum lockout time length" +msgstr "" + +#: admin/wp-security-user-login-menu.php:305 +msgid "Set the minimum time period in minutes of lockout." +msgstr "" + +#: admin/wp-security-user-login-menu.php:306 +msgid "This failed login lockout time will be tripled on each failed login." +msgstr "" + +#: admin/wp-security-user-login-menu.php:313 +msgid "Maximum lockout time length" +msgstr "" + +#: admin/wp-security-user-login-menu.php:318 +msgid "Set the maximum time period in minutes of lockout." +msgstr "" + +#: admin/wp-security-user-login-menu.php:319 +msgid "No IP address will be blocked for more than this time period after making a failed login attempt." +msgstr "" + +#: admin/wp-security-user-login-menu.php:324 +msgid "Display generic error message" +msgstr "" + +#: admin/wp-security-user-login-menu.php:327 +msgid "Check this if you want to show a generic error message when a login attempt fails" +msgstr "" + +#: admin/wp-security-user-login-menu.php:331 +msgid "Instantly lockout invalid usernames" +msgstr "" + +#: admin/wp-security-user-login-menu.php:334 +msgid "Check this if you want to instantly lockout login attempts with usernames which do not exist on your system" +msgstr "" + +#: admin/wp-security-user-login-menu.php:339 +msgid "Instantly lockout specific usernames" +msgstr "" + +#: admin/wp-security-user-login-menu.php:349 +msgid "Insert one username per line. Existing usernames are not blocked even if present in the list." +msgstr "" + +#: admin/wp-security-user-login-menu.php:354 +msgid "Notify by email" +msgstr "" + +#: admin/wp-security-user-login-menu.php:358 +msgid "Check this if you want to receive an email when someone has been locked out due to maximum failed login attempts" +msgstr "" + +#: admin/wp-security-user-login-menu.php:361 +msgid "Fill in one email address per line." +msgstr "" + +#: admin/wp-security-user-login-menu.php:365 +msgid "Each email address must be on a new line." +msgstr "" + +#: admin/wp-security-user-login-menu.php:366 +msgid "If a valid email address has not been filled in, it will not be saved." +msgstr "" + +#: admin/wp-security-user-login-menu.php:367 +msgid "The valid email address format is userid@example.com" +msgstr "" + +#: admin/wp-security-user-login-menu.php:368 +msgid "Example: %s" +msgstr "" + +#: admin/wp-security-user-login-menu.php:375 +msgid "Enable PHP backtrace in email" +msgstr "" + +#: admin/wp-security-user-login-menu.php:379 +msgid "Check this if you want to include the PHP backtrace in notification emails." +msgstr "" + +#: admin/wp-security-user-login-menu.php:379 +msgid "This is internal coding information which makes it easier to investigate where an issued occurred." +msgstr "" + +#: admin/wp-security-user-login-menu.php:389 +msgid "Currently locked out IP address ranges" +msgstr "" + +#: admin/wp-security-user-login-menu.php:394 +msgid "To see a list of all locked IP addresses and ranges go to the %s tab in the dashboard menu." +msgstr "" + +#: admin/wp-security-user-login-menu.php:399 +msgid "Login lockout IP whitelist settings" +msgstr "" + +#: admin/wp-security-user-login-menu.php:405 +msgid "Enable login lockout IP whitelist" +msgstr "" + +#: admin/wp-security-user-login-menu.php:416 +msgid "The addresses specified here will never be blocked by the login lockout feature." +msgstr "" + +#: admin/wp-security-user-login-menu.php:450 +msgid "User login feature - Delete all failed login records operation failed." +msgstr "" + +#: admin/wp-security-user-login-menu.php:452 +msgid "All records from the failed logins table were deleted successfully." +msgstr "" + +#: admin/wp-security-user-login-menu.php:467 +msgid "This tab displays the failed login attempts for your site." +msgstr "" + +#: admin/wp-security-user-login-menu.php:468 +msgid "The information below can be handy if you need to do security investigations because it will show you the IP range, username and ID (if applicable) and the time/date of the failed login attempt." +msgstr "" + +#: admin/wp-security-user-login-menu.php:469 +msgid "Failed login records that are older than %1$d days are purged automatically." +msgstr "" + +#: admin/wp-security-user-login-menu.php:508 +#: admin/wp-security-user-login-menu.php:517 +msgid "Delete all failed login records" +msgstr "" + +#: admin/wp-security-user-login-menu.php:514 +msgid "Click this button if you wish to delete all failed login records in one go." +msgstr "" + +#: admin/wp-security-user-login-menu.php:544 +msgid "You entered a non numeric value for the logout time period field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-user-login-menu.php:569 +msgid "Setting an expiry period for your WP administration session is a simple way to protect against unauthorized access to your site from your computer." +msgstr "" + +#: admin/wp-security-user-login-menu.php:570 +msgid "This feature allows you to specify a time period in minutes after which the admin session will expire and the user will be forced to log back in." +msgstr "" + +#: admin/wp-security-user-login-menu.php:575 +msgid "Force user logout options" +msgstr "" + +#: admin/wp-security-user-login-menu.php:587 +msgid "Enable force WP user logout" +msgstr "" + +#: admin/wp-security-user-login-menu.php:590 +msgid "Check this if you want to force a wp user to be logged out after a configured amount of time" +msgstr "" + +#: admin/wp-security-user-login-menu.php:594 +msgid "Logout the WP user after XX minutes" +msgstr "" + +#: admin/wp-security-user-login-menu.php:596 +msgid "(Minutes) The user will be forced to log back in after this time period has elapased." +msgstr "" + +#: admin/wp-security-user-login-menu.php:625 +msgid "This tab displays the activity for accounts registered with your site that have logged in using the WordPress login form." +msgstr "" + +#: admin/wp-security-user-login-menu.php:626 +msgid "The information below can be handy if you need to do security investigations because it will show you the last 100 recent login events by username, IP address and time/date." +msgstr "" + +#: admin/wp-security-user-login-menu.php:627 +msgid "Account activity logs that are older than %1$d days are purged automatically." +msgstr "" + +#: admin/wp-security-user-login-menu.php:697 +msgid "Refresh logged in user data" +msgstr "" + +#: admin/wp-security-user-login-menu.php:701 +msgid "Refresh data" +msgstr "" + +#: admin/wp-security-user-login-menu.php:706 +msgid "This tab displays all users who are currently logged into your site." +msgstr "" + +#: admin/wp-security-user-login-menu.php:707 +msgid "If you suspect there is a user or users who are logged in which should not be, you can block them by inspecting the IP addresses from the data below and adding them to your blacklist." +msgstr "" + +#: admin/wp-security-user-login-menu.php:708 +msgid "You can also instantly log them out by clicking on the \"Force logout\" link when you hover over the row in the user id column." +msgstr "" + +#: admin/wp-security-user-login-menu.php:713 +msgid "Currently logged in users" +msgstr "" + +#: admin/wp-security-user-login-menu.php:761 +msgid "WordPress 5.6 introduced a new feature called \"Application passwords\"." +msgstr "" + +#: admin/wp-security-user-login-menu.php:762 +msgid "This allows you to create a token from the WordPress dashboard which then can be used in the authorization header." +msgstr "" + +#: admin/wp-security-user-login-menu.php:763 +msgid "This feature allows you to disable application passwords as they can leave your site vulnerable to social engineering and phishing scams." +msgstr "" + +#: admin/wp-security-user-login-menu.php:780 +#: classes/grade-system/wp-security-feature-item-manager.php:53 +msgid "Disable application password" +msgstr "" + +#: admin/wp-security-user-login-menu.php:783 +msgid "Check this if you want to disable the application password." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:27 +msgid "Manual approval" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:28 +#: classes/grade-system/wp-security-feature-item-manager.php:59 +msgid "Registration CAPTCHA" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:29 +msgid "Registration honeypot" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:55 +msgid "User registration" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:115 +msgid "User registration settings" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:119 +msgid "Manually approve new registrations" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:123 +msgid "If your site allows people to create their own accounts via the WordPress registration form, then you can minimize spam or bogus registrations by manually approving each registration." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:124 +msgid "This feature will automatically set a newly registered account to \"pending\" until the administrator activates it. Therefore undesirable registrants will be unable to log in without your express approval." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:125 +msgid "You can view all accounts which have been newly registered via the handy table below and you can also perform bulk activation/deactivation/deletion tasks on each account." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:142 +msgid "Enable manual approval of new registrations" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:145 +msgid "Check this if you want to automatically disable all newly registered accounts so that you can approve them manually." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:154 +msgid "Approve registered users" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:206 +msgid "This feature allows you to add a CAPTCHA form on the WordPress registration page." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:207 +msgid "Users who attempt to register will also need to enter the answer to a simple mathematical question - if they enter the wrong answer, the plugin will not allow them to register." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:208 +msgid "Therefore, adding a CAPTCHA form on the registration page is another effective yet simple spam registration prevention technique." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:212 +msgid "Registration page CAPTCHA settings" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:219 +msgid "The core default behaviour for WordPress Multi Site regarding user registration is that all users are registered via the main site." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:220 +msgid "Therefore, if you would like to add a CAPTCHA form to the registration page for a Multi Site, please go to \"Registration CAPTCHA\" settings on the main site." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:235 +msgid "Enable CAPTCHA on registration page" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:238 +msgid "Check this if you want to insert a CAPTCHA form on the WordPress user registration page (if you allow user registration)." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:276 +msgid "This feature allows you to add a special hidden \"honeypot\" field on the WordPress registration page. This will only be visible to robots and not humans." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:277 +msgid "Since robots usually fill in every input field from a registration form, they will also submit a value for the special hidden honeypot field." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:279 +msgid "Therefore, if the plugin detects that this field has a value when the registration form is submitted, then the robot which is attempting to register on your site will be redirected to its localhost address - http://127.0.0.1." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:285 +msgid "Registration form honeypot settings" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:296 +msgid "Enable honeypot on registration page" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:299 +msgid "Check this if you want to enable the honeypot feature for the registration page" +msgstr "" + +#: classes/aios-ajax.php:89 +msgid "Invalid IP retrieve method." +msgstr "" + +#: classes/aios-ajax.php:131 +#: wp-security-core.php:258 +msgid "The security check failed; try refreshing the page." +msgstr "" + +#: classes/aios-ajax.php:152 +#: wp-security-core.php:268 +msgid "You are not allowed to run this command." +msgstr "" + +#: classes/aios-ajax.php:173 +#: wp-security-core.php:282 +msgid "Options can only be saved by network admin" +msgstr "" + +#: classes/aios-ajax.php:202 +msgid "The command \"%s\" was not found" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:39 +msgid "Remove WP generator meta tag" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:45 +msgid "Change display name" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:57 +msgid "Registration approval" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:61 +msgid "Enable registration honeypot" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:73 +msgid "WordPress files access" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:77 +msgid "IP and user agent blacklisting" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:81 +msgid "Enable basic firewall" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:82 +msgid "Enable pingback vulnerability protection" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:83 +msgid "Block access to debug log file" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:87 +msgid "Forbid proxy comments" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:88 +msgid "Deny bad queries" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:91 +msgid "5G/6G blacklist" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:97 +msgid "Enable IP blocking for 404 detection" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:101 +msgid "Enable rename login page" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:106 +msgid "Lost password CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:107 +msgid "Custom login CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:108 +msgid "Woo login CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:109 +msgid "Woo lost password CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:110 +msgid "Woo register CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:112 +msgid "Login IP whitelisting" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:114 +msgid "Enable login honeypot" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:118 +msgid "Comment CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:119 +msgid "Block spambots" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:121 +msgid "BuddyPress registration CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:123 +msgid "bbPress new topic CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item.php:29 +msgid "Basic" +msgstr "" + +#: classes/grade-system/wp-security-feature-item.php:31 +msgid "Intermediate" +msgstr "" + +#: classes/grade-system/wp-security-feature-item.php:33 +msgid "Advanced" +msgstr "" + +#: classes/wp-security-captcha.php:47 +#: classes/wp-security-general-init-tasks.php:407 +msgid "Please enter an answer in digits:" +msgstr "Kérjük, adja meg a választ számjegyekkel:" + +#: classes/wp-security-captcha.php:127 +msgid "one" +msgstr "egy" + +#: classes/wp-security-captcha.php:128 +msgid "two" +msgstr "kettő" + +#: classes/wp-security-captcha.php:129 +msgid "three" +msgstr "három" + +#: classes/wp-security-captcha.php:130 +msgid "four" +msgstr "négy" + +#: classes/wp-security-captcha.php:131 +msgid "five" +msgstr "öt" + +#: classes/wp-security-captcha.php:132 +msgid "six" +msgstr "hat" + +#: classes/wp-security-captcha.php:133 +msgid "seven" +msgstr "hét" + +#: classes/wp-security-captcha.php:134 +msgid "eight" +msgstr "nyolc" + +#: classes/wp-security-captcha.php:135 +msgid "nine" +msgstr "kilenc" + +#: classes/wp-security-captcha.php:136 +msgid "ten" +msgstr "tíz" + +#: classes/wp-security-captcha.php:137 +msgid "eleven" +msgstr "tizenegy" + +#: classes/wp-security-captcha.php:138 +msgid "twelve" +msgstr "tizenkettő" + +#: classes/wp-security-captcha.php:139 +msgid "thirteen" +msgstr "tizenhárom" + +#: classes/wp-security-captcha.php:140 +msgid "fourteen" +msgstr "tizennégy" + +#: classes/wp-security-captcha.php:141 +msgid "fifteen" +msgstr "tizenöt" + +#: classes/wp-security-captcha.php:142 +msgid "sixteen" +msgstr "tizenhat" + +#: classes/wp-security-captcha.php:143 +msgid "seventeen" +msgstr "tizenhét" + +#: classes/wp-security-captcha.php:144 +msgid "eighteen" +msgstr "tizennyolc" + +#: classes/wp-security-captcha.php:145 +msgid "nineteen" +msgstr "tizenkilenc" + +#: classes/wp-security-captcha.php:146 +msgid "twenty" +msgstr "húsz" + +#: classes/wp-security-cronjob-handler.php:34 +msgid "Every 15 minutes" +msgstr "" + +#: classes/wp-security-debug-logger.php:46 +msgid "Unable to get the reason why" +msgstr "" + +#: classes/wp-security-debug-logger.php:47 +msgid "Unable to clear the logs" +msgstr "" + +#: classes/wp-security-file-scan.php:85 +msgid "All In One WP Security - File change detected!" +msgstr "" + +#: classes/wp-security-file-scan.php:87 +msgid "A file change was detected on your system for site URL" +msgstr "" + +#: classes/wp-security-file-scan.php:87 +msgid ". Scan was generated on" +msgstr "" + +#: classes/wp-security-file-scan.php:88 +msgid "A summary of the scan results is shown below:" +msgstr "" + +#: classes/wp-security-file-scan.php:91 +msgid "Login to your site to view the scan details." +msgstr "" + +#: classes/wp-security-file-scan.php:313 +msgid "The following files were added to your host" +msgstr "" + +#: classes/wp-security-file-scan.php:315 +#: classes/wp-security-file-scan.php:323 +#: classes/wp-security-file-scan.php:332 +msgid "modified on: " +msgstr "" + +#: classes/wp-security-file-scan.php:321 +msgid "The following files were removed from your host" +msgstr "" + +#: classes/wp-security-file-scan.php:330 +msgid "The following files were changed on your host" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:212 +#: classes/wp-security-general-init-tasks.php:481 +msgid "Application passwords have been disabled by All In One WP Security & Firewall plugin." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:428 +#: classes/wp-security-general-init-tasks.php:541 +#: classes/wp-security-general-init-tasks.php:574 +#: classes/wp-security-user-login.php:137 +#: classes/wp-security-user-registration.php:74 +msgid "ERROR: Your answer was incorrect - please try again." +msgstr "HIBA: A válasz helytelen - kérjük, próbálja meg újból." + +#: classes/wp-security-general-init-tasks.php:463 +msgid "Enter something special:" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:476 +msgid "Application passwords" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:485 +msgid "Change setting" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:487 +msgid "Site admin can only change this setting." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:516 +msgid "Error: You entered an incorrect CAPTCHA answer. Please go back and try again." +msgstr "Hiba: Helytelen CAPTCHA választ adott meg. Kérjük menjen vissza és próbálja meg újból." + +#: classes/wp-security-general-init-tasks.php:558 +msgid "Your CAPTCHA answer was incorrect - please try again." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:567 +msgid "ERROR: Your IP address is currently locked please contact the administrator!" +msgstr "" + +#. translators: %s: Admin Dashboard > WP Security > Brute Force > Login CAPTCHA Tab Link +#: classes/wp-security-general-init-tasks.php:642 +msgid "Your Google reCAPTCHA site key is wrong. Please fill the correct reCAPTCHA keys %s to use the Google reCAPTCHA feature." +msgstr "" + +#. translators: %s: Admin Dashboard > WP Security > Brute Force > Login CAPTCHA Tab Link +#: classes/wp-security-general-init-tasks.php:642 +#: classes/wp-security-notices.php:99 +msgid "here" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +msgid "Would you like All In One WP Security & Firewall to re-insert the security rules in your .htaccess file which were cleared when you deactivated the plugin?" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +#: templates/may-also-like.php:40 +#: templates/may-also-like.php:43 +#: templates/may-also-like.php:54 +#: templates/may-also-like.php:57 +#: templates/may-also-like.php:68 +#: templates/may-also-like.php:71 +#: templates/may-also-like.php:91 +#: templates/may-also-like.php:103 +#: templates/may-also-like.php:115 +#: templates/may-also-like.php:127 +#: templates/may-also-like.php:139 +#: templates/may-also-like.php:151 +#: templates/may-also-like.php:168 +#: templates/may-also-like.php:171 +#: templates/may-also-like.php:183 +#: templates/may-also-like.php:195 +#: templates/may-also-like.php:207 +#: templates/may-also-like.php:219 +#: templates/may-also-like.php:231 +#: templates/may-also-like.php:243 +#: templates/may-also-like.php:252 +#: templates/may-also-like.php:255 +#: templates/may-also-like.php:264 +#: templates/may-also-like.php:267 +#: templates/may-also-like.php:279 +#: templates/may-also-like.php:297 +#: templates/may-also-like.php:309 +#: templates/may-also-like.php:327 +#: templates/may-also-like.php:339 +#: templates/may-also-like.php:351 +#: templates/may-also-like.php:368 +#: templates/may-also-like.php:380 +msgid "Yes" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +#: templates/may-also-like.php:88 +#: templates/may-also-like.php:100 +#: templates/may-also-like.php:112 +#: templates/may-also-like.php:124 +#: templates/may-also-like.php:136 +#: templates/may-also-like.php:148 +#: templates/may-also-like.php:180 +#: templates/may-also-like.php:192 +#: templates/may-also-like.php:204 +#: templates/may-also-like.php:216 +#: templates/may-also-like.php:228 +#: templates/may-also-like.php:240 +#: templates/may-also-like.php:276 +#: templates/may-also-like.php:294 +#: templates/may-also-like.php:306 +#: templates/may-also-like.php:324 +#: templates/may-also-like.php:336 +#: templates/may-also-like.php:348 +#: templates/may-also-like.php:365 +#: templates/may-also-like.php:377 +#: templates/notices/custom-notice.php:27 +msgid "No" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:674 +msgid "Your registration is pending approval." +msgstr "" + +#: classes/wp-security-notices.php:25 +msgid "The All in One Security plugin has disabled the login whitelist setting that you have enabled in the past." +msgstr "" + +#: classes/wp-security-notices.php:29 +msgid "Your website is running on an Apache webserver, the login whitelisting might not be functional until the recent update of AIOS (because it relied upon Apache-specific module features)." +msgstr "" + +#: classes/wp-security-notices.php:31 +msgid "Your website is running on a non-Apache webserver, so the login whitelisting was not functional until the recent update of AIOS (because it relied upon Apache-specific features)." +msgstr "" + +#: classes/wp-security-notices.php:33 +msgid "It began working with AIOS version 5.0.8." +msgstr "" + +#: classes/wp-security-notices.php:33 +msgid "We have disabled it so that your login page will not be blocked unexpectedly." +msgstr "" + +#: classes/wp-security-notices.php:42 +msgid "Would you like to re-enable login whitelisting?" +msgstr "" + +#: classes/wp-security-notices.php:48 +msgid "Removed database backup feature from the All In One WP Security & Firewall plugin" +msgstr "" + +#: classes/wp-security-notices.php:50 +msgid "Beginning with version 5.0.0, AIOS has replaced the AIOS backup method with the superior UpdraftPlus method." +msgstr "" + +#: classes/wp-security-notices.php:51 +msgid "It remains free and is fully supported by the UpdraftPlus team." +msgstr "" + +#: classes/wp-security-notices.php:54 +msgid "You are seeing this notice because you have previously set up automated database backups in AIOS." +msgstr "" + +#: classes/wp-security-notices.php:55 +msgid "Would you like to set up scheduled backups with UpdraftPlus?" +msgstr "" + +#: classes/wp-security-notices.php:61 +msgid "Setup UpdraftPlus backup plugin" +msgstr "" + +#: classes/wp-security-notices.php:67 +msgid "Important: set up your IP address detection settings" +msgstr "" + +#: classes/wp-security-notices.php:69 +msgid "The All in One Security plugin couldn't be certain about the correct method to detect the IP address for your site visitors with your currently-configured IP address detection settings." +msgstr "" + +#: classes/wp-security-notices.php:70 +msgid "It is important for your security to set the IP address detection settings properly." +msgstr "" + +#: classes/wp-security-notices.php:73 +msgid "Please go to the settings and set them now." +msgstr "" + +#: classes/wp-security-notices.php:79 +msgid "Setup IP address detection settings" +msgstr "" + +#: classes/wp-security-notices.php:85 +msgid "Important: Disabled login whitelist setting" +msgstr "" + +#: classes/wp-security-notices.php:91 +msgid "Turn it back on" +msgstr "" + +#: classes/wp-security-notices.php:92 +msgid "Edit the settings" +msgstr "" + +#: classes/wp-security-notices.php:95 +msgid "Keep it off" +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Hey - We noticed All In One WP Security & Firewall has kept your site safe for a while. If you like us, please consider leaving a positive review to spread the word. Or if you have any issues or questions please leave us a support message %s." +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Thank you so much!" +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Team All In One WP Security & Firewall" +msgstr "" + +#: classes/wp-security-notices.php:109 +msgid "Enhance your security even more by backing up your site" +msgstr "" + +#: classes/wp-security-notices.php:110 +msgid "UpdraftPlus is the world's most trusted backup plugin from the owners of All In One WP Security & Firewall" +msgstr "" + +#: classes/wp-security-notices.php:121 +msgid "After you've secured your site, we recommend you install our WP-Optimize plugin to streamline it for better website performance." +msgstr "" + +#: classes/wp-security-process-renamed-login-page.php:152 +msgid "Not available." +msgstr "" + +#: classes/wp-security-two-factor-login.php:34 +msgid "Two factor authentication - Admin settings" +msgstr "" + +#: classes/wp-security-two-factor-login.php:97 +msgid "Two Factor Auth" +msgstr "" + +#: classes/wp-security-two-factor-login.php:153 +msgid "PHP OpenSSL or mcrypt module required" +msgstr "" + +#: classes/wp-security-two-factor-login.php:153 +msgid "The All In One WP Security plugin's Two Factor Authentication module requires either the PHP openssl (preferred) or mcrypt module to be installed. Please ask your web hosting company to install one of them." +msgstr "" + +#: classes/wp-security-user-login.php:71 +msgid "You have disabled login lockout by defining the AIOS_DISABLE_LOGIN_LOCKOUT constant value as true, and the login lockout setting has enabled it." +msgstr "" + +#. translators: 1: Locked IP Addresses admin page link +#: classes/wp-security-user-login.php:73 +msgid "Delete your login lockout IP from %s and define the AIOS_DISABLE_LOGIN_LOCKOUT constant value as false." +msgstr "" + +#: classes/wp-security-user-login.php:100 +msgid "ERROR: Access from your IP address has been blocked for security reasons. Please contact the administrator." +msgstr "" + +#: classes/wp-security-user-login.php:108 +msgid "Service temporarily unavailable" +msgstr "" + +#: classes/wp-security-user-login.php:163 +msgid "ACCOUNT PENDING: Your account is currently not active. An administrator needs to activate your account before you can login." +msgstr "FIÓK FÜGGŐBEN: A fiókja jelenleg nem aktív. Egy adminisztrátornak kell aktiválnia, mielőtt belépne." + +#: classes/wp-security-user-login.php:242 +msgid "ERROR: Invalid login credentials." +msgstr "HIBA: Érvénytelen bejelentkezési adatok." + +#: classes/wp-security-user-login.php:392 +msgid "Site Lockout Notification" +msgstr "" + +#: classes/wp-security-user-login.php:393 +msgid "User login lockout events had occurred due to too many failed login attempts or invalid username:" +msgstr "" + +#: classes/wp-security-user-login.php:396 +msgid "Username:" +msgstr "" + +#: classes/wp-security-user-login.php:397 +msgid "IP address:" +msgstr "" + +#: classes/wp-security-user-login.php:399 +msgid "IP range:" +msgstr "" + +#: classes/wp-security-user-login.php:404 +msgid "Log into your site WordPress administration panel to see the duration of the lockout or to unlock the user." +msgstr "" + +#: classes/wp-security-user-login.php:515 +msgid "Unlock request notification" +msgstr "" + +#: classes/wp-security-user-login.php:516 +msgid "You have requested for the account with email address %s to be unlocked. Please click the link below to unlock your account:" +msgstr "" + +#: classes/wp-security-user-login.php:516 +msgid "Unlock link: %s" +msgstr "" + +#: classes/wp-security-user-login.php:516 +msgid "After clicking the above link you will be able to login to the WordPress administration panel." +msgstr "" + +#: classes/wp-security-user-login.php:739 +msgid "Your session has expired because it has been over %d minutes since your last login." +msgstr "" + +#: classes/wp-security-user-login.php:740 +#: classes/wp-security-user-login.php:744 +msgid "Please log back in to continue." +msgstr "" + +#: classes/wp-security-user-login.php:743 +msgid "You were logged out because you just changed the \"admin\" username." +msgstr "" + +#: classes/wp-security-user-login.php:773 +msgid "Request unlock" +msgstr "" + +#: classes/wp-security-user-registration.php:68 +msgid "ERROR: You are not allowed to register because your IP address is currently locked!" +msgstr "" + +#: classes/wp-security-utility-ip-address.php:217 +#: classes/wp-security-utility-ip-address.php:231 +#: classes/wp-security-utility-ip-address.php:245 +#: classes/wp-security-utility-ip-address.php:257 +#: classes/wp-security-utility-ip-address.php:269 +msgid " is not a valid ip address format." +msgstr "" + +#: classes/wp-security-utility-ip-address.php:274 +msgid "You cannot ban your own IP address: " +msgstr "" + +#: classes/wp-security-utility.php:254 +msgid "This feature can only be configured by the \"superadmin\" on the main site." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:32 +msgid "ERROR: Unable to process your request!" +msgstr "" + +#: other-includes/wp-security-unlock-request.php:45 +msgid "Please enter a valid email address" +msgstr "" + +#: other-includes/wp-security-unlock-request.php:57 +msgid "User account not found!" +msgstr "" + +#: other-includes/wp-security-unlock-request.php:71 +msgid "Error: No locked entry was found in the database with your IP address range." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:76 +msgid "An email has been sent to you with the unlock instructions." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:93 +msgid "You are here because you have been locked out due to too many incorrect login attempts." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:94 +msgid "Please enter your email address and you will receive an email with instructions on how to unlock yourself." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:104 +msgid "Email Address" +msgstr "" + +#: other-includes/wp-security-unlock-request.php:108 +msgid "Send unlock request" +msgstr "" + +#: templates/admin/incompatible-plugin.php:6 +msgid "Two Factor Authentication" +msgstr "" + +#: templates/admin/incompatible-plugin.php:10 +msgid "Two Factor Authentication currently disabled" +msgstr "" + +#: templates/admin/incompatible-plugin.php:12 +#: templates/admin/incompatible-plugin.php:16 +msgid "Two factor authentication in All In One WP Security is currently disabled because the incompatible plugin %s is active." +msgstr "" + +#: templates/automated-database-backup.php:4 +msgid "Automated scheduled backups" +msgstr "" + +#: templates/automated-database-backup.php:9 +msgid "Automate backup in the UpdraftPlus plugin" +msgstr "" + +#: templates/automated-database-backup.php:19 +msgid "The AIOS 5.0.0 version release has removed the automated backup feature." +msgstr "" + +#: templates/automated-database-backup.php:20 +msgid "The AIOS automated backup had issues that made it less robust than we could be happy with." +msgstr "" + +#: templates/automated-database-backup.php:21 +msgid "Follow this link to automate backups in the superior UpdraftPlus backup plugin." +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:5 +msgid "Each IP address must be on a new line." +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:6 +msgid "To specify an IPv4 range use a wildcard \"*\" character. Acceptable ways to use wildcards is shown in the examples below:" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:7 +msgid "Example 1: 195.47.89.*" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:8 +msgid "Example 2: 195.47.*.*" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:9 +msgid "Example 3: 195.*.*.*" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:10 +msgid "To specify an IPv6 range use CIDR format as shown in the examples below:" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:11 +msgid "Example 4: 2401:4900:54c3:af15:2:2:5dc0:0/112" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:12 +msgid "Example 5: 2001:db8:1263::/48" +msgstr "" + +#: templates/may-also-like.php:5 +msgid "All-In-One Security (AIOS) Free vs Premium Comparison Chart" +msgstr "" + +#: templates/may-also-like.php:7 +msgid "FAQs" +msgstr "" + +#: templates/may-also-like.php:9 +msgid "Ask a pre-sales question" +msgstr "" + +#: templates/may-also-like.php:17 +msgid "All In One WP Security & Firewall Free" +msgstr "" + +#: templates/may-also-like.php:26 +#: templates/may-also-like.php:386 +msgid "Installed" +msgstr "" + +#: templates/may-also-like.php:29 +#: templates/may-also-like.php:389 +msgid "Upgrade now" +msgstr "" + +#: templates/may-also-like.php:34 +msgid "Login security feature suite" +msgstr "" + +#: templates/may-also-like.php:35 +msgid "Protect against brute-force attacks and keep bots at bay." +msgstr "" + +#: templates/may-also-like.php:35 +msgid "AIOS takes WordPress' default login security features to a whole new level." +msgstr "" + +#: templates/may-also-like.php:37 +msgid "To see all login security features, visit %s" +msgstr "" + +#: templates/may-also-like.php:48 +msgid "Firewall and file protection feature suite" +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Protection from the latest exploits." +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Activate firewall settings ranging from basic, intermediate and advanced." +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Get comprehensive, instant protection with All-in-One Security." +msgstr "" + +#: templates/may-also-like.php:51 +msgid "To see all firewall and file protection features, visit %s" +msgstr "" + +#: templates/may-also-like.php:62 +msgid "Content protection feature suite" +msgstr "" + +#: templates/may-also-like.php:63 +msgid "Eliminate spam and protect your content to dramatically improve your website's interactions with search engines." +msgstr "" + +#: templates/may-also-like.php:65 +msgid "To see all content protection features, visit %s" +msgstr "" + +#: templates/may-also-like.php:76 +msgid "Malware scanning" +msgstr "" + +#: templates/may-also-like.php:77 +msgid "Finding out by accident that your site has been infected with malware is too late." +msgstr "" + +#: templates/may-also-like.php:79 +msgid "Malware can have a dramatic effect on your site's search rankings and you may not even know about it." +msgstr "" + +#: templates/may-also-like.php:79 +msgid "It can slow your website down, access customer data, send unsolicited emails, change your content or prevent users from accessing it." +msgstr "" + +#: templates/may-also-like.php:84 +msgid "Automatic malware scanning" +msgstr "" + +#: templates/may-also-like.php:85 +msgid "Best-in-class scanning for the latest malware, trojans and spyware 24/7." +msgstr "" + +#: templates/may-also-like.php:96 +msgid "Response time monitoring" +msgstr "" + +#: templates/may-also-like.php:97 +msgid "You'll know immediately if your website's response time is negatively affected." +msgstr "" + +#: templates/may-also-like.php:108 +msgid "Up-time monitoring" +msgstr "" + +#: templates/may-also-like.php:109 +msgid "AIOS checks your website's uptime every 5 minutes." +msgstr "" + +#: templates/may-also-like.php:109 +msgid "We'll notify you straight away if your site/server goes down." +msgstr "" + +#: templates/may-also-like.php:120 +msgid "Prevents blacklisting by search engines" +msgstr "" + +#: templates/may-also-like.php:121 +msgid "AIOS monitors your site's blacklist status daily." +msgstr "" + +#: templates/may-also-like.php:121 +msgid "We'll notify you within 24 hours if something's amiss so you can take action, before it's too late." +msgstr "" + +#: templates/may-also-like.php:132 +msgid "Flexible assignment" +msgstr "" + +#: templates/may-also-like.php:133 +msgid "Register and remove websites from the scanning service at any time." +msgstr "" + +#: templates/may-also-like.php:144 +msgid "Malware reports" +msgstr "" + +#: templates/may-also-like.php:145 +msgid "Reports are available via the 'My Account' page and directly via email." +msgstr "" + +#: templates/may-also-like.php:156 +msgid "Flexible two-factor authentication" +msgstr "" + +#: templates/may-also-like.php:157 +msgid "With Two-Factor Authentication (TFA) users enter their username and password and a one-time code sent to a device to login." +msgstr "" + +#: templates/may-also-like.php:159 +msgid "TFA is a feature in both our free and premium packages, but AIOS Premium affords whole new levels of control over how TFA is implemented." +msgstr "" + +#: templates/may-also-like.php:164 +msgid "Authenticator apps" +msgstr "" + +#: templates/may-also-like.php:165 +msgid "Supports TOTP and HOTP protocols." +msgstr "" + +#: templates/may-also-like.php:165 +msgid "TFA Can be used with Google Authenticator, Microsoft Authenticator, Authy and many more." +msgstr "" + +#: templates/may-also-like.php:176 +msgid "Role specific configuration" +msgstr "" + +#: templates/may-also-like.php:177 +msgid "Make it compulsory for certain roles e.g. for admin and editor roles." +msgstr "" + +#: templates/may-also-like.php:188 +msgid "Require TFA after a set time period" +msgstr "" + +#: templates/may-also-like.php:189 +msgid "For example you could require all admins to have TFA once their accounts are a week old." +msgstr "" + +#: templates/may-also-like.php:200 +msgid "Trusted devices - control how often TFA is required" +msgstr "" + +#: templates/may-also-like.php:201 +msgid "Ask for TFA after a chosen number of days for trusted devices instead of on every login." +msgstr "" + +#: templates/may-also-like.php:212 +msgid "Anti-bot protection" +msgstr "" + +#: templates/may-also-like.php:213 +msgid "Option to hide the existence of forms on WooCommerce login pages unless JavaScript is active." +msgstr "" + +#: templates/may-also-like.php:224 +msgid "Customise TFA design layout" +msgstr "" + +#: templates/may-also-like.php:225 +msgid "Customise the design of TFA so it aligns with your existing web design." +msgstr "" + +#: templates/may-also-like.php:236 +msgid "TFA emergency codes" +msgstr "" + +#: templates/may-also-like.php:237 +msgid "Generate a one-time use emergency code to allow access if your device is lost." +msgstr "" + +#: templates/may-also-like.php:248 +msgid "TFA multisite compatibility" +msgstr "" + +#: templates/may-also-like.php:249 +msgid "TFA is Compatible with multisite networks and sub-sites." +msgstr "" + +#: templates/may-also-like.php:260 +msgid "TFA support for common login forms" +msgstr "" + +#: templates/may-also-like.php:261 +msgid "Supports WooCommerce, Affiliates-WP and Theme my Login login forms." +msgstr "" + +#: templates/may-also-like.php:272 +msgid "TFA support for other login forms" +msgstr "" + +#: templates/may-also-like.php:273 +msgid "Supports Elementor Pro, bbPress and all third-party login forms without any further coding needed." +msgstr "" + +#: templates/may-also-like.php:284 +msgid "Smart 404 blocking" +msgstr "" + +#: templates/may-also-like.php:285 +msgid "404 errors can occur when someone legitimately mistypes a URL, but they're also generated by hackers searching for weaknesses in your site." +msgstr "" + +#: templates/may-also-like.php:290 +msgid "Automatically and permanently blocks bots producing 404s" +msgstr "" + +#: templates/may-also-like.php:291 +msgid "AIOS Premium provides more protection than the competition by automatically and permanently blocking IP addresses of bots and hackers based on how many 404 errors they generate." +msgstr "" + +#: templates/may-also-like.php:302 +msgid "404 error charts" +msgstr "" + +#: templates/may-also-like.php:303 +msgid "Handy charts keep you informed of how many 404s have occurred and which IP address or country is producing them." +msgstr "" + +#: templates/may-also-like.php:314 +msgid "Country blocking" +msgstr "" + +#: templates/may-also-like.php:315 +msgid "Most malicious attacks come from a handful of countries and so it's possible to prevent most attacks with our country blocking tool." +msgstr "" + +#: templates/may-also-like.php:320 +msgid "Block traffic based on country of origin" +msgstr "" + +#: templates/may-also-like.php:321 +msgid "AIOS Premium utilises an IP database that promises 99.5% accuracy." +msgstr "" + +#: templates/may-also-like.php:332 +msgid "Block traffic to specific pages based on country of origin" +msgstr "" + +#: templates/may-also-like.php:333 +msgid "Block access to your whole site or on a page-by-page basis." +msgstr "" + +#: templates/may-also-like.php:344 +msgid "Whitelist some users from blocked countries" +msgstr "" + +#: templates/may-also-like.php:345 +msgid "Whitelist IP addresses or IP ranges even if they are part of a blocked country." +msgstr "" + +#: templates/may-also-like.php:356 +msgid "Premium support" +msgstr "" + +#: templates/may-also-like.php:361 +msgid "Unlimited support" +msgstr "" + +#: templates/may-also-like.php:362 +msgid "Personalised, email support from our team of Security experts, as and when you need it." +msgstr "" + +#: templates/may-also-like.php:373 +msgid "Guaranteed response time" +msgstr "" + +#: templates/may-also-like.php:374 +msgid "We offer a guaranteed response time of three days." +msgstr "" + +#: templates/may-also-like.php:374 +msgid "99% of our Premium customers receive a response to their enquiry within 24 hours during the working week." +msgstr "" + +#: templates/may-also-like.php:397 +msgid "Our other plugins" +msgstr "" + +#: templates/may-also-like.php:411 +msgid "UpdraftPlus – the ultimate protection for your site, hard work and business" +msgstr "" + +#: templates/may-also-like.php:412 +msgid "Simplifies backups and restoration." +msgstr "" + +#: templates/may-also-like.php:412 +msgid "It is the world's highest ranking and most popular scheduled backup plugin, with over three million currently-active installs." +msgstr "" + +#: templates/may-also-like.php:413 +#: templates/may-also-like.php:419 +#: templates/may-also-like.php:425 +#: templates/may-also-like.php:431 +msgid "Try for free" +msgstr "" + +#: templates/may-also-like.php:417 +msgid "WP-Optimize – keep your database fast and efficient" +msgstr "" + +#: templates/may-also-like.php:418 +msgid "Makes your site fast and efficient." +msgstr "" + +#: templates/may-also-like.php:418 +msgid "It cleans the database, compresses images and caches pages for ultimate speed." +msgstr "" + +#: templates/may-also-like.php:423 +msgid "UpdraftCentral – save hours managing multiple WP sites from one place" +msgstr "" + +#: templates/may-also-like.php:424 +msgid "Highly efficient way to manage, optimize, update and backup multiple websites from one place." +msgstr "" + +#: templates/may-also-like.php:429 +msgid "Easy Updates Manager" +msgstr "" + +#: templates/may-also-like.php:430 +msgid "Keeps your WordPress site up to date and bug free." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:2 +msgid "IP address detection settings" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:6 +msgid "The IP address detection settings allow you to specify how visitors' IP addresses are made known to PHP (and hence to WordPress and its plugins)." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:7 +msgid "Usually, this is automatic and there is only one choice." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:8 +msgid "However in some setups, such as those using proxies (including load-balancers and security firewalls like Cloudflare), it may be necessary to set this manually." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "Attention" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "It is important to set this correctly - otherwise you may make it possible for a hacker to ban all your visitors (e.g. via banning Cloudflare from connecting to you) instead of being banned himself." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "The default is to use the REMOTE_ADDR PHP server variable. If this variable does not contain the visitor's IP address, then whilst you can make a different selection below, it is better to ask your web hosting company to have it correctly set." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:10 +msgid "This is the most secure setup, because when set correctly it is immune from being spoofed by an attacker." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:16 +msgid "You have no available IP address detection method(s); you must contact your web hosting company." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:22 +#: templates/menus/settings/advanced-settings.php:27 +#: templates/menus/settings/advanced-settings.php:32 +msgid "Your detected IP address according to %s:" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:38 +msgid "If your site is setup on localhost, you won't see your external IP address using your server's IP detection setting; but on a localhost-served site (not available to the outside world), the setting is irrelevant and can be ignored." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:61 +msgid "Choose a $_SERVER variable you would like to detect visitors' IP address using." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:67 +msgid "If your chosen server variable fails the plugin will automatically fall back to retrieving the IP address from $_SERVER[\"REMOTE_ADDR\"]" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:73 +msgid "Your IP address if using this setting:" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:75 +msgid "fetching..." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:81 +#: templates/menus/settings/advanced-settings.php:190 +msgid "getting..." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:89 +msgid "look-up possibly blocked by an ad-blocker or similar tool" +msgstr "" + +#: templates/notices/cookie-based-brute-force-prevention-disabled.php:4 +msgid "Cookie based brute force login prevention currently disabled" +msgstr "" + +#: templates/notices/cookie-based-brute-force-prevention-disabled.php:6 +msgid "Cookie based brute force login prevention is currently disabled via the AIOS_DISABLE_COOKIE_BRUTE_FORCE_PREVENTION constant (which is mostly likely to be defined in your wp-config.php)" +msgstr "" + +#: templates/notices/disable-login-whitelist.php:4 +msgid "Login whitelisting currently disabled" +msgstr "" + +#: templates/notices/disable-login-whitelist.php:6 +msgid "Login whitelisting is currently disabled via the AIOS_DISABLE_LOGIN_WHITELIST constant (which is mostly likely to be defined in your wp-config.php)" +msgstr "" + +#: templates/notices/horizontal-notice.php:8 +#: templates/notices/horizontal-notice.php:40 +msgid "notice image" +msgstr "" + +#: templates/notices/horizontal-notice.php:18 +msgid "Ok, you deserve it" +msgstr "" + +#: templates/notices/horizontal-notice.php:22 +msgid "Maybe later" +msgstr "" + +#: templates/notices/horizontal-notice.php:26 +msgid "Never" +msgstr "" + +#: templates/notices/horizontal-notice.php:66 +msgid "Get UpdraftCentral" +msgstr "" + +#: templates/notices/horizontal-notice.php:68 +msgid "Get UpdraftPlus" +msgstr "" + +#: templates/notices/horizontal-notice.php:70 +msgid "Get WP-Optimize" +msgstr "" + +#: templates/notices/horizontal-notice.php:72 +msgid "Find out more." +msgstr "" + +#: templates/notices/horizontal-notice.php:74 +msgid "Sign up" +msgstr "" + +#: templates/notices/horizontal-notice.php:76 +msgid "Go there" +msgstr "" + +#: templates/notices/horizontal-notice.php:78 +msgid "Read more" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:4 +msgid "Dismiss (for %s months)" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:6 +msgid "Thank you for installing All In One WP Security & Firewall!" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:13 +msgid "Super-charge and secure your WordPress site even more with our other top plugins:" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:17 +msgid "%s makes your site fast and efficient. It cleans the database, compresses images and caches pages for ultimate speed." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:21 +msgid "%s simplifies backups and restoration. It is the world's highest ranking and most popular scheduled backup plugin, with over three million currently-active installs." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:25 +msgid "%s is a highly efficient way to manage, optimize, update and backup multiple websites from one place." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:29 +msgid "%s is a WordPress subscription extension for WooCommerce store owners." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:33 +msgid "More quality plugins" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:33 +msgid "Premium WooCommerce plugins" +msgstr "" + +#: templates/partials/non-apache-feature-notice.php:9 +msgid "This feature works only on the Apache server." +msgstr "" + +#: templates/partials/non-apache-feature-notice.php:10 +msgid "You are using the non-apache server %s, so this feature won't work on your site." +msgstr "" + +#: wp-security-core.php:236 +#: wp-security.php:45 +msgid "This plugin requires PHP version %s." +msgstr "" + +#: wp-security-core.php:237 +msgid "Current site PHP version is %s." +msgstr "" + +#: wp-security-core.php:238 +#: wp-security.php:47 +msgid "You will need to ask your web hosting company to upgrade." +msgstr "" + +#: wp-security-core.php:397 +msgid "Error:" +msgstr "" + +#: wp-security-core.php:397 +msgid "template not found" +msgstr "" + +#: wp-security.php:44 +msgid "All In One WP Security and Firewall plugin has been deactivated." +msgstr "" + +#: wp-security.php:46 +msgid "Your current PHP version is %s." +msgstr "" diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-ko_KR.mo b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-ko_KR.mo new file mode 100755 index 0000000000000000000000000000000000000000..5503e915277cedc11d300698fae564e904d9a31e GIT binary patch literal 69308 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\n" +"Language-Team: Luatic \n" +"Language: ko_KR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=1;\n" +"X-Generator: Poedit 1.8.13\n" +"X-Poedit-Basepath: ..\n" +"X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n" +"X-Poedit-SearchPath-0: .\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Textdomain-Support: yes\n" + +#. Plugin Name of the plugin +msgid "All In One WP Security" +msgstr "" + +#. Plugin URI of the plugin +msgid "https://wordpress.org/plugins/all-in-one-wp-security-and-firewall/" +msgstr "" + +#. Description of the plugin +msgid "All round best WordPress security plugin!" +msgstr "" + +#. Author of the plugin +msgid "All In One WP Security & Firewall Team" +msgstr "" + +#. Author URI of the plugin +msgid "https://teamupdraft.com/" +msgstr "" + +#: admin/general/wp-security-list-table.php:483 +msgid "Are you sure you want to perform this bulk action?" +msgstr "" + +#: admin/wp-security-admin-init.php:259 +msgid "Unexpected response:" +msgstr "" + +#: admin/wp-security-admin-init.php:290 +msgid "Enjoyed %1$s? Please leave us a %2$s rating. We really appreciate your support!" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:414 +#: classes/wp-security-two-factor-login.php:95 +msgid "WP Security" +msgstr "WP 보안" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:415 +#: admin/wp-security-dashboard-menu.php:26 +#: admin/wp-security-dashboard-menu.php:76 +msgid "Dashboard" +msgstr "상황판" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:416 +#: admin/wp-security-settings-menu.php:95 +msgid "Settings" +msgstr "설정" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:417 +msgid "User Accounts" +msgstr "사용자 계정" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:418 +msgid "User Login" +msgstr "사용자 로그인" + +#: admin/wp-security-admin-init.php:419 +msgid "User Registration" +msgstr "회원가입" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:420 +msgid "Database Security" +msgstr "데이터베이스 보안" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:424 +msgid "Filesystem Security" +msgstr "파일 시스템 보안" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:429 +msgid "Blacklist Manager" +msgstr "블랙리스트 관리자" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:434 +#: admin/wp-security-firewall-menu.php:60 +msgid "Firewall" +msgstr "방화벽" + +#: admin/wp-security-admin-init.php:436 +msgid "Brute Force" +msgstr "무차별 대입 공격" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:437 +msgid "Spam Prevention" +msgstr "스팸 예방" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:441 +#: admin/wp-security-filescan-menu.php:53 +msgid "Scanner" +msgstr "스캐너" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:443 +#: admin/wp-security-maintenance-menu.php:51 +msgid "Maintenance" +msgstr "유지관리" + +#: admin/wp-security-admin-init.php:444 +#: admin/wp-security-misc-options-menu.php:57 +msgid "Miscellaneous" +msgstr "기타설정" + +#: admin/wp-security-admin-init.php:445 +#: admin/wp-security-tools-menu.php:64 +msgid "Tools" +msgstr "" + +#: admin/wp-security-admin-init.php:457 +msgid "Premium Upgrade" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-menu.php:67 +msgid "Settings successfully updated." +msgstr "설정이 성공적으로 업데이트 되었습니다." + +#: admin/wp-security-admin-menu.php:77 +msgid "Successfully deleted the selected record(s)." +msgstr "" + +#: admin/wp-security-admin-menu.php:86 +msgid "Failed to delete the selected record(s)." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:25 +msgid "Ban users" +msgstr "사용자 차단" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:51 +msgid "Blacklist manager" +msgstr "블랙리스트 관리자" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:132 +#: admin/wp-security-firewall-menu.php:1233 +#: admin/wp-security-list-404.php:234 +#: admin/wp-security-list-comment-spammer-ip.php:205 +msgid "The plugin was unable to write to the .htaccess file. Please edit file manually." +msgstr "플러그인은 .htaccess 파일에 쓸 수 없습니다. 수동으로 파일을 편집하십시오." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:139 +msgid "Ban IPs or user agents" +msgstr "Ban IPs or User Agents" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:142 +msgid "The All In One WP Security Blacklist feature gives you the option of banning certain host IP addresses or ranges and also user agents." +msgstr "All In One WP 보안 블랙리스트 기능은 특정 호스트 IP 주소 또는 범위 및 사용자 에이전트를 금지하는 옵션을 제공합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:143 +msgid "This feature will deny total site access for users which have IP addresses or user agents matching those which you have configured in the settings below." +msgstr "이 기능은 IP 주소 또는 사용자 에이전트가 아래 설정에서 구성한 것과 일치하는 사용자의 총 사이트 액세스를 거부합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:144 +msgid "The plugin achieves this by making appropriate modifications to your .htaccess file." +msgstr "플러그인은 .htaccess 파일을 적절하게 수정하여 이를 달성합니다." + +#: admin/wp-security-blacklist-menu.php:145 +msgid "By blocking people, you are using the most secure first line of defence, which denies all access to blacklisted visitors as soon as they hit your hosting server." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:154 +#: admin/wp-security-firewall-menu.php:1055 +#: templates/may-also-like.php:20 +msgid "All In One WP Security & Firewall Premium" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:155 +#: admin/wp-security-firewall-menu.php:1056 +msgid "You may also be interested in %s." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "This plugin adds a number of extra features including %s and %s." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "smart 404 blocking" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "country IP blocking" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:170 +msgid "IP hosts and user agent blacklist settings" +msgstr "IP 호스트 및 사용자 에이전트 블랙리스트 설정" + +#: admin/wp-security-blacklist-menu.php:182 +#: admin/wp-security-brute-force-menu.php:193 +#: admin/wp-security-brute-force-menu.php:331 +msgid "must read this message" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:183 +#: admin/wp-security-brute-force-menu.php:194 +msgid "This feature can lock you out of admin if it doesn't work correctly on your site. You %s before activating this feature." +msgstr "이 기능은 사이트에서 제대로 작동하지 않으면 관리자에서 잠글 수 있습니다. 이 기능을 활성화하기 전에 %s를 사용할 수 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:189 +msgid "Enable IP or user agent blacklisting" +msgstr "IP 또는 사용자 에이전트 블랙리스트 사용" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:192 +msgid "Check this if you want to enable the banning (or blacklisting) of selected IP addresses and/or user agents specified in the settings below" +msgstr "아래 설정에 지정된 선택한 IP 주소 및/또는 사용자 에이전트의 금지(또는 블랙리스트)를 사용하도록 설정하려는 경우 이 옵션을 확인합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:196 +msgid "Enter IP addresses:" +msgstr "IP 주소 입력:" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:200 +msgid "Enter one or more IP addresses or IP ranges." +msgstr "하나 이상의 IP 주소 또는 IP 범위를 입력합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:205 +msgid "Enter user agents:" +msgstr "사용자 에이전트 입력:" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:210 +msgid "Enter one or more user agent strings." +msgstr "하나 이상의 사용자 에이전트 문자열을 입력합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:211 +#: admin/wp-security-brute-force-menu.php:374 +#: admin/wp-security-brute-force-menu.php:408 +#: admin/wp-security-brute-force-menu.php:431 +#: admin/wp-security-brute-force-menu.php:452 +#: admin/wp-security-filescan-menu.php:309 +#: admin/wp-security-filescan-menu.php:326 +#: admin/wp-security-firewall-menu.php:175 +#: admin/wp-security-firewall-menu.php:212 +#: admin/wp-security-firewall-menu.php:232 +#: admin/wp-security-firewall-menu.php:258 +#: admin/wp-security-firewall-menu.php:385 +#: admin/wp-security-firewall-menu.php:415 +#: admin/wp-security-firewall-menu.php:446 +#: admin/wp-security-firewall-menu.php:474 +#: admin/wp-security-firewall-menu.php:503 +#: admin/wp-security-firewall-menu.php:681 +#: admin/wp-security-firewall-menu.php:699 +#: admin/wp-security-firewall-menu.php:737 +#: admin/wp-security-firewall-menu.php:868 +#: admin/wp-security-firewall-menu.php:1087 +#: admin/wp-security-firewall-menu.php:1110 +#: admin/wp-security-spam-menu.php:186 +#: admin/wp-security-spam-menu.php:221 +#: admin/wp-security-spam-menu.php:390 +#: admin/wp-security-spam-menu.php:430 +#: admin/wp-security-user-login-menu.php:362 +#: templates/info/ip-address-ip-range-info.php:2 +#: templates/menus/settings/advanced-settings.php:63 +msgid "More info" +msgstr "더보기" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:214 +msgid "Each user agent string must be on a new line." +msgstr "각 사용자 에이전트 문자열은 새 줄에 있어야 합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:215 +msgid "Example 1 - A single user agent string to block:" +msgstr "예 1 - 차단하는 단일 사용자 에이전트 문자열:" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:217 +msgid "Example 2 - A list of more than 1 user agent strings to block" +msgstr "예 2 - 차단할 사용자 에이전트 문자열이 1개 이상 나열됩니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:225 +#: admin/wp-security-brute-force-menu.php:213 +#: admin/wp-security-brute-force-menu.php:686 +#: admin/wp-security-brute-force-menu.php:806 +#: admin/wp-security-brute-force-menu.php:868 +#: admin/wp-security-filescan-menu.php:351 +#: admin/wp-security-filesystem-menu.php:242 +#: admin/wp-security-firewall-menu.php:945 +#: admin/wp-security-firewall-menu.php:1129 +#: admin/wp-security-misc-options-menu.php:167 +#: admin/wp-security-misc-options-menu.php:218 +#: admin/wp-security-misc-options-menu.php:278 +#: admin/wp-security-settings-menu.php:619 +#: admin/wp-security-settings-menu.php:680 +#: admin/wp-security-spam-menu.php:233 +#: admin/wp-security-spam-menu.php:407 +#: admin/wp-security-spam-menu.php:526 +#: admin/wp-security-spam-menu.php:588 +#: admin/wp-security-user-login-menu.php:384 +#: admin/wp-security-user-login-menu.php:422 +#: admin/wp-security-user-login-menu.php:601 +#: admin/wp-security-user-login-menu.php:788 +#: admin/wp-security-user-registration-menu.php:150 +#: admin/wp-security-user-registration-menu.php:242 +#: admin/wp-security-user-registration-menu.php:305 +#: templates/menus/settings/advanced-settings.php:217 +msgid "Save settings" +msgstr "설정 저장" + +#: admin/wp-security-brute-force-menu.php:33 +#: admin/wp-security-brute-force-menu.php:759 +#: admin/wp-security-dashboard-menu.php:651 +msgid "Rename login page" +msgstr "로그인 페이지 주소 변경" + +#: admin/wp-security-brute-force-menu.php:34 +#: admin/wp-security-brute-force-menu.php:154 +msgid "Cookie based brute force prevention" +msgstr "쿠키 기반 무차별 무력 예방" + +#: admin/wp-security-brute-force-menu.php:35 +#: classes/grade-system/wp-security-feature-item-manager.php:105 +msgid "Login CAPTCHA" +msgstr "로그인 캡챠" + +#: admin/wp-security-brute-force-menu.php:36 +#: admin/wp-security-brute-force-menu.php:746 +msgid "Login whitelist" +msgstr "로그인 허용 목록" + +#: admin/wp-security-brute-force-menu.php:37 +msgid "Honeypot" +msgstr "허니팟(Honeypot)" + +#: admin/wp-security-brute-force-menu.php:67 +msgid "Brute force" +msgstr "무차별 대입 공격" + +#: admin/wp-security-brute-force-menu.php:105 +msgid "Please enter a value for your login page slug." +msgstr "로그인 페이지 슬러그에 대한 값을 입력하십시오." + +#: admin/wp-security-brute-force-menu.php:109 +msgid "You cannot use the value \"wp-admin\" for your login page slug." +msgstr "로그인 페이지 슬러그에 대해 \"wp-admin\" 값을 사용할 수 없습니다." + +#: admin/wp-security-brute-force-menu.php:111 +msgid "You must use alpha numeric characters for your login page slug." +msgstr "로그인 페이지 슬러그에 알파 숫자 문자를 사용해야 합니다." + +#: admin/wp-security-brute-force-menu.php:116 +#: admin/wp-security-filescan-menu.php:174 +#: admin/wp-security-firewall-menu.php:151 +#: admin/wp-security-firewall-menu.php:1011 +#: admin/wp-security-spam-menu.php:101 +#: admin/wp-security-spam-menu.php:270 +#: admin/wp-security-spam-menu.php:302 +#: admin/wp-security-user-login-menu.php:184 +#: admin/wp-security-user-login-menu.php:553 +#: templates/partials/non-apache-feature-notice.php:9 +msgid "Attention:" +msgstr "注意:" + +#: admin/wp-security-brute-force-menu.php:133 +msgid "Could not delete the Cookie-based directives from the .htaccess file. Please check the file permissions." +msgstr ".htaccess 파일에서 쿠키 기반 지침을 삭제할 수 없습니다. 파일 권한을 확인하십시오." + +#: admin/wp-security-brute-force-menu.php:155 +msgid "Login page white list" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:156 +msgid "An effective Brute Force prevention technique is to change the default WordPress login page URL." +msgstr "효과적인 무차별 포스 방지 기술은 기본 워드 프레스 로그인 페이지 URL을 변경하는 것입니다." + +#: admin/wp-security-brute-force-menu.php:157 +msgid "Normally if you wanted to login to WordPress you would type your site's home URL followed by wp-login.php." +msgstr "일반적으로 WordPress에 로그인하려는 경우 사이트의 홈 URL을 입력한 다음 wp-login.php를 입력합니다." + +#: admin/wp-security-brute-force-menu.php:158 +msgid "This feature allows you to change the login URL by setting your own slug and renaming the last portion of the login URL which contains the wp-login.php to any string that you like." +msgstr "이 기능을 사용하면 자신의 슬러그를 설정하고 wp-login.php를 포함하는 로그인 URL의 마지막 부분의 이름을 원하는 문자열로 변경하여 로그인 URL을 변경할 수 있습니다." + +#: admin/wp-security-brute-force-menu.php:159 +msgid "By doing this, malicious bots and hackers will not be able to access your login page because they will not know the correct login page URL." +msgstr "이렇게 하면 악의적인 봇과 해커가 로그인 페이지에 액세스할 수 없습니다." + +#: admin/wp-security-brute-force-menu.php:161 +msgid "You may also be interested in the following alternative brute force prevention features:" +msgstr "또한 다음과 같은 대체 무차별 무력 방지 기능에 관심이 있을 수 있습니다." + +#: admin/wp-security-brute-force-menu.php:172 +msgid "Your WordPress login page URL has been renamed." +msgstr "워드 프레스 로그인 페이지 URL의 이름이 변경되었습니다." + +#: admin/wp-security-brute-force-menu.php:173 +msgid "Your current login URL is:" +msgstr "현재 로그인 URL은 다음과 같은 것입니다." + +#: admin/wp-security-brute-force-menu.php:181 +msgid "Rename login page settings" +msgstr "로그인 페이지 주소 변경 설정" + +#: admin/wp-security-brute-force-menu.php:195 +msgid "NOTE: If you are hosting your site on WPEngine or a provider which performs server caching, you will need to ask the host support people to NOT cache your renamed login page." +msgstr "참고: WPEngine 또는 서버 캐싱을 수행하는 공급자에서 사이트를 호스팅하는 경우 호스트 지원 사람들에게 이름이 변경된 로그인 페이지를 캐시하지 않도록 요청해야 합니다." + +#: admin/wp-security-brute-force-menu.php:200 +msgid "Enable rename login page feature" +msgstr "이름 바꾸기 페이지 기능 사용" + +#: admin/wp-security-brute-force-menu.php:203 +msgid "Check this if you want to enable the rename login page feature" +msgstr "이름 바꾸기 페이지 기능을 사용하도록 설정하려면 이 방법을 확인하십시오." + +#: admin/wp-security-brute-force-menu.php:207 +msgid "Login page URL" +msgstr "로그인 페이지 URL" + +#: admin/wp-security-brute-force-menu.php:209 +msgid "Enter a string which will represent your secure login page slug. You are encouraged to choose something which is hard to guess and only you will remember." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:243 +msgid "Settings have not been saved - your secret word must consist only of alphanumeric characters, ie, letters and/or numbers only." +msgstr "설정은 저장되지 않았습니다 - 당신의 비밀 단어는 영숫자 문자, 즉, 문자 및 / 또는 숫자로만 구성해야합니다!" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:257 +msgid "You have successfully enabled the cookie based brute force prevention feature" +msgstr "쿠키 기반 무차별 무력 방지 기능을 성공적으로 활성화했습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:258 +msgid "From now on you will need to log into your WP Admin using the following URL:" +msgstr "지금부터 다음 URL을 사용하여 WP 관리자에 로그인해야 합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:260 +msgid "It is important that you save this URL value somewhere in case you forget it, OR," +msgstr "이 URL 값을 잊어버린 경우 어딘가에 저장하는 것이 중요합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:261 +msgid "simply remember to add a \"?%s=1\" to your current site URL address." +msgstr "단순히 현재 사이트 URL 주소에 \"?%s=1\"을 추가해야 합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:265 +msgid "You have successfully saved cookie based brute force prevention feature settings." +msgstr "쿠키 기반 무차별 무력 방지 기능 설정을 성공적으로 저장했습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:295 +msgid "Brute force prevention firewall settings" +msgstr "무차별 강제 방지 방화벽 설정" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:300 +msgid "A Brute Force Attack is when a hacker tries many combinations of usernames and passwords until they succeed in guessing the right combination." +msgstr "무차별 포스 공격은 해커가 올바른 조합을 추측하는 데 성공할 때까지 사용자 이름과 암호의 많은 조합을 시도할 때입니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:301 +msgid "Due to the fact that at any one time there may be many concurrent login attempts occurring on your site via malicious automated robots, this also has a negative impact on your server's memory and performance." +msgstr "악의적인 자동화 된 로봇을 통해 사이트에서 발생하는 동시 로그인 시도가 있을 수 있으므로 서버의 메모리와 성능에도 부정적인 영향을 미칩니다." + +#: admin/wp-security-brute-force-menu.php:302 +msgid "The features in this tab will stop the majority of brute force login attacks thus providing even better protection for your WP login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:307 +#: admin/wp-security-firewall-menu.php:654 +msgid "backup" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:308 +msgid "video tutorial" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:309 +msgid "To learn more about how to use this feature, please watch the following %s." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:310 +#: admin/wp-security-brute-force-menu.php:758 +msgid "Cookie-Based Brute Force Login Prevention" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:320 +#: admin/wp-security-user-login-menu.php:253 +msgid "Cookie based brute force login prevention" +msgstr "쿠키 기반 무차별 포스 로그인 방지" + +#: admin/wp-security-brute-force-menu.php:331 +msgid "This feature can lock you out of admin if it doesn't work correctly on your site. You " +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:342 +msgid "The cookie test was successful. You can now enable this feature." +msgstr "쿠키 테스트는 성공적이었습니다. 이제 이 기능을 활성화할 수 있습니다." + +#: admin/wp-security-brute-force-menu.php:350 +msgid "The cookie test failed on this server. Consequently, this feature cannot be used on this site." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:357 +msgid "Before using this feature, you must perform a cookie test first." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:359 +msgid "This ensures that your browser cookie is working correctly and that you won't lock yourself out." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:364 +msgid "Perform cookie test" +msgstr "쿠키 테스트 수행" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:370 +#: classes/grade-system/wp-security-feature-item-manager.php:103 +msgid "Enable brute force attack prevention" +msgstr "무차별 무력 공격 방지 활성화" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:373 +msgid "Check this if you want to protect your login page from Brute Force Attack." +msgstr "브루트 포스 공격으로부터 로그인 페이지를 보호하려면 이 방법을 확인하십시오." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:378 +msgid "This feature will deny access to your WordPress login page for all people except those who have a special cookie in their browser." +msgstr "이 기능은 브라우저에 특별한 쿠키가있는 사람들을 제외한 모든 사용자의 워드 프레스 로그인 페이지에 대한 액세스를 거부합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:380 +msgid "To use this feature do the following:" +msgstr "이 기능을 사용하려면 다음을 수행합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:382 +msgid "1) Enable the checkbox." +msgstr "1) 확인란을 활성화합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:384 +msgid "2) Enter a secret word consisting of alphanumeric characters which will be difficult to guess. This secret word will be useful whenever you need to know the special URL which you will use to access the login page (see point below)." +msgstr "2) 추측하기 어려운 거넘 문자로 구성된 비밀 단어를 입력합니다. 이 비밀 단어는 로그인 페이지에 액세스하는 데 사용할 특수 URL을 알아야 할 때마다 유용합니다(아래 점 참조)." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:386 +msgid "3) You will then be provided with a special login URL. You will need to use this URL to login to your WordPress site instead of the usual login URL. NOTE: The system will deposit a special cookie in your browser which will allow you access to the WordPress administration login page." +msgstr "3) 당신은 다음 특별한 로그인 URL이 제공됩니다. 이 URL을 사용하여 일반적인 로그인 URL 대신 WordPress 사이트에 로그인해야 합니다. 참고 : 시스템은 당신이 워드 프레스 관리 로그인 페이지에 액세스 할 수 있도록 브라우저에 특별한 쿠키를 입금합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:388 +msgid "Any person trying to access your login page who does not have the special cookie in their browser will be automatically blocked." +msgstr "브라우저에 특별한 쿠키가 없는 로그인 페이지에 액세스하려는 모든 사람이 자동으로 차단됩니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:395 +msgid "Secret word" +msgstr "암호 문자" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:397 +msgid "Choose a secret word consisting of alphanumeric characters which you can use to access your special URL. Your are highly encouraged to choose a word which will be difficult to guess." +msgstr "특수 URL에 액세스하는 데 사용할 수 있는 유수 문자로 구성된 비밀 단어를 선택합니다. 추측하기 어려운 단어를 선택하는 것이 좋습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:401 +msgid "Re-direct URL" +msgstr "Re-direct URL" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:405 +msgid "Specify a URL to redirect a hacker to when they try to access your WordPress login page." +msgstr "해커가 WordPress 로그인 페이지에 액세스하려고 할 때로 리디렉션할 URL을 지정합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:412 +msgid "The URL specified here can be any site's URL and does not have to be your own. For example you can be as creative as you like and send hackers to the CIA or NSA home page." +msgstr "여기에 지정된 URL은 사이트의 URL일 수 있으며 사용자 고유의 URL일 필요는 없습니다. 예를 들어 원하는 만큼 창의적이며 해커를 CIA 또는 NSA 홈 페이지로 보낼 수 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:414 +msgid "This field will default to: http://127.0.0.1 if you do not enter a value." +msgstr "값을 입력하지 않으면 이 필드는 기본값으로 http://127.0.0.1." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:416 +msgid "Useful Tip:" +msgstr "유용한 팁:" + +#: admin/wp-security-brute-force-menu.php:418 +msgid "It's a good idea to not redirect attempted brute force login attempts to your site because it increases the load on your server." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:420 +msgid "Redirecting a hacker or malicious bot back to \"http://127.0.0.1\" is ideal because it deflects them back to their own local host and puts the load on their server instead of yours." +msgstr "해커 나 악성 봇을 다시 \"http://127.0.0.1\"로 리디렉션하는 것은 자신의 로컬 호스트로 다시 편향하고 대신 서버의 부하를 넣기 때문에 이상적입니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:427 +msgid "My site has posts or pages which are password protected" +msgstr "내 사이트에는 암호로 보호된 게시물 또는 페이지가 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:430 +msgid "Check this if you are using the native WordPress password protection feature for some or all of your blog posts or pages." +msgstr "블로그 게시물 또는 페이지의 일부 또는 전부에 대해 기본 WordPress 암호 보호 기능을 사용하는 경우 이 기능을 확인하십시오." + +#: admin/wp-security-brute-force-menu.php:435 +msgid "In the cases where you are protecting some of your posts or pages using the in-built WordPress password protection feature, a few extra lines of directives and exceptions need to be added so that people trying to access pages are not automatically blocked." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:437 +msgid "By enabling this checkbox, the plugin will add the necessary rules and exceptions so that people trying to access these pages are not automatically blocked." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:439 +msgid "Helpful Tip:" +msgstr "유용한 팁:" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:441 +msgid "If you do not use the WordPress password protection feature for your posts or pages then it is highly recommended that you leave this checkbox disabled." +msgstr "게시물이나 페이지에 대해 WordPress 암호 보호 기능을 사용하지 않는 경우 이 확인란을 사용하지 않도록 두는 것이 좋습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:448 +msgid "My site has a theme or plugins which use AJAX" +msgstr "내 사이트는 AJAX를 사용하는 테마 또는 플러그인이 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:451 +msgid "Check this if your site uses AJAX functionality." +msgstr "사이트에서 AJAX 기능을 사용하는지 확인합니다." + +#: admin/wp-security-brute-force-menu.php:456 +msgid "In the cases where your WordPress installation has a theme or plugin that uses AJAX, a few extra lines of directives and exceptions need to be added to prevent AJAX requests from being automatically blocked by the brute force prevention feature." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:458 +msgid "By enabling this checkbox, the plugin will add the necessary rules and exceptions so that AJAX operations will work as expected." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:467 +msgid "Save feature settings" +msgstr "기능 설정 저장" + +#: admin/wp-security-brute-force-menu.php:525 +msgid "This feature allows you to add a CAPTCHA form on various WordPress login pages and forms." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:526 +msgid "Adding a CAPTCHA form on a login page or form is another effective yet simple \"Brute Force\" prevention technique." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:527 +msgid "You have the option of using either %s or a plain maths CAPTCHA form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:528 +msgid "If you enable Google reCAPTCHA the reCAPTCHA widget will be displayed for all forms the CAPTCHA settings below." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:529 +msgid "If Google reCAPTCHA is disabled the simple maths CAPTCHA form will apply and users will need to enter the answer to a simple mathematical question." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:535 +msgid "Google reCAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:540 +msgid "By enabling these settings the Google reCAPTCHA v2 widget will be applied by default for all forms with CAPTCHA enabled." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:549 +msgid "reCAPTCHA will not work because you have disabled login lockout by activating the AIOS_DISABLE_LOGIN_LOCKOUT constant value in a configuration file." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:550 +msgid "To enable it, define AIOS_DISABLE_LOGIN_LOCKOUT constant value as false, or remove it." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:558 +msgid "Use Google reCAPTCHA as default" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:561 +msgid "Check this if you want to default to Google reCAPTCHA for all settings below. (If this is left unchecked, all CAPTCHA forms will revert to the plain maths CAPTCHA)" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:565 +msgid "Site key" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:571 +msgid "Secret key" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:580 +msgid "Login form CAPTCHA settings" +msgstr "로그인 양식 캡차 설정" + +#: admin/wp-security-brute-force-menu.php:589 +msgid "Enable CAPTCHA on login page" +msgstr "로그인 페이지에서 Captcha 사용" + +#: admin/wp-security-brute-force-menu.php:592 +msgid "Check this if you want to insert a CAPTCHA form on the login page." +msgstr "로그인 페이지에 캡차 양식을 삽입하려는 경우 이 방법을 확인하십시오." + +#: admin/wp-security-brute-force-menu.php:598 +msgid "Lost password form CAPTCHA settings" +msgstr "비밀번호 찾기 양식에 보안 문자 설정" + +#: admin/wp-security-brute-force-menu.php:608 +msgid "Enable CAPTCHA on lost password page" +msgstr "암호 분실 페이지에서 보안 문자 활성화" + +#: admin/wp-security-brute-force-menu.php:611 +msgid "Check this if you want to insert a CAPTCHA form on the lost password page." +msgstr "비밀번호 찾기 페이지에 보안 문자 양식을 삽입하려는 경우 이 방법을 확인하십시오." + +#: admin/wp-security-brute-force-menu.php:617 +msgid "Custom login form CAPTCHA settings" +msgstr "사용자 정의 로그인 양식 캡차 설정" + +#: admin/wp-security-brute-force-menu.php:626 +msgid "Enable CAPTCHA on custom login form" +msgstr "맞춤형 로그인 양식에 보안 문자 사용" + +#: admin/wp-security-brute-force-menu.php:629 +msgid "Check this if you want to insert CAPTCHA on a custom login form generated by the following WP function: wp_login_form()" +msgstr "다음 WP 함수에서 생성된 사용자 지정 로그인 양식에 보안 문자를 삽입하려는 경우 wp_login_form()" + +#: admin/wp-security-brute-force-menu.php:639 +msgid "WooCommerce forms CAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:648 +msgid "Enable CAPTCHA on WooCommerce login form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:651 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce login form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:661 +msgid "Enable CAPTCHA on WooCommerce lost password form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:664 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce lost password form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:674 +msgid "Enable CAPTCHA on WooCommerce registration form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:677 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce registration form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:749 +msgid "The All In One WP Security Whitelist feature gives you the option of only allowing certain IP addresses or ranges to have access to your WordPress login page." +msgstr "모든 WP 보안 화이트리스트 기능은 특정 IP 주소 또는 범위만 WordPress 로그인 페이지에 액세스할 수 있도록 허용하는 옵션을 제공합니다." + +#: admin/wp-security-brute-force-menu.php:750 +msgid "This feature will deny login access for all IP addresses which are not in your whitelist as configured in the settings below." +msgstr "이 기능은 아래 설정에서 구성된 대로 화이트리스트에 없는 모든 IP 주소에 대한 로그인 액세스를 거부합니다." + +#: admin/wp-security-brute-force-menu.php:751 +msgid "The plugin achieves this by writing the appropriate directives to your .htaccess file." +msgstr "플러그인은 .htaccess 파일에 적절한 지침을 작성하여 이를 달성합니다." + +#: admin/wp-security-brute-force-menu.php:752 +msgid "By allowing/blocking IP addresses, you are using the most secure first line of defence because login access will only be granted to whitelisted IP addresses and other addresses will be blocked as soon as they try to access your login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:760 +msgid "Attention: If in addition to enabling the white list feature, you also have one of the %s or %s features enabled, you will still need to use your secret word or special slug in the URL when trying to access your WordPress login page." +msgstr "주의: 화이트 리스트 기능을 사용하도록 설정하는 것 외에도 %s 또는 %s 기능 중 하나가 활성화된 경우 WordPress 로그인 페이지에 액세스하려고 할 때 URL에서 비밀 단어 또는 특수 슬러그를 사용해야 합니다." + +#: admin/wp-security-brute-force-menu.php:761 +msgid "These features are NOT functionally related. Having both of them enabled on your site means you are creating 2 layers of security." +msgstr "이러한 기능은 기능적으로 관련이 없습니다. 두 가지 를 모두 사이트에서 사용하도록 설정하면 2개의 보안 계층을 만드는 것을 의미합니다." + +#: admin/wp-security-brute-force-menu.php:772 +msgid "Login IP whitelist settings" +msgstr "로그인 IP 허용 목록 설정" + +#: admin/wp-security-brute-force-menu.php:783 +msgid "Enable IP whitelisting" +msgstr "IP 화이트리스팅 활성화" + +#: admin/wp-security-brute-force-menu.php:786 +#: admin/wp-security-user-login-menu.php:408 +msgid "Check this if you want to enable the whitelisting of selected IP addresses specified in the settings below" +msgstr "아래 설정에 지정된 선택한 IP 주소의 화이트리스팅을 사용하도록 설정하려면 이 옵션을 확인하십시오." + +#: admin/wp-security-brute-force-menu.php:790 +msgid "Your current IP address" +msgstr "현재 IP 주소" + +#: admin/wp-security-brute-force-menu.php:793 +msgid "You can copy and paste this address in the text box below if you want to include it in your login whitelist." +msgstr "로그인 화이트리스트에 포함하려는 경우 아래 텍스트 상자에 이 주소를 복사하여 붙여넣기할 수 있습니다." + +#: admin/wp-security-brute-force-menu.php:797 +#: admin/wp-security-user-login-menu.php:412 +msgid "Enter whitelisted IP addresses:" +msgstr "화이트리스트 IP 주소 입력:" + +#: admin/wp-security-brute-force-menu.php:801 +#: admin/wp-security-user-login-menu.php:416 +msgid "Enter one or more IP addresses or IP ranges you wish to include in your whitelist." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:801 +msgid "Only the addresses specified here will have access to the WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:839 +msgid "This feature allows you to add a special hidden \"honeypot\" field on the WordPress login page. This will only be visible to robots and not humans." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:840 +msgid "Since robots usually fill in every input field from a login form, they will also submit a value for the special hidden honeypot field." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:841 +#: admin/wp-security-user-registration-menu.php:278 +msgid "The way honeypots work is that a hidden field is placed somewhere inside a form which only robots will submit. If that field contains a value when the form is submitted then a robot has most likely submitted the form and it is consequently dealt with." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:842 +msgid "Therefore, if the plugin detects that this field has a value when the login form is submitted, then the robot which is attempting to login to your site will be redirected to its localhost address - http://127.0.0.1." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:848 +msgid "Login form honeypot settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:859 +msgid "Enable honeypot on login page" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:862 +msgid "Check this if you want to enable the honeypot feature for the login page" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:27 +#: admin/wp-security-dashboard-menu.php:374 +#: classes/wp-security-user-login.php:74 +msgid "Locked IP addresses" +msgstr "잠긴 IP 주소" + +#: admin/wp-security-dashboard-menu.php:28 +msgid "Permanent block list" +msgstr "영구 블록 목록" + +#: admin/wp-security-dashboard-menu.php:29 +msgid "Logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:33 +msgid "Premium upgrade" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:131 +#: admin/wp-security-dashboard-menu.php:518 +#: admin/wp-security-user-login-menu.php:53 +#: classes/grade-system/wp-security-feature-item-manager.php:49 +msgid "Login lockout" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:132 +msgid "This tab displays the list of all IP addresses which are currently temporarily locked out due to the login lockout feature:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:138 +msgid "Currently locked out IP addresses and ranges" +msgstr "현재 잠겨 있는 IP 주소 및 범위" + +#: admin/wp-security-dashboard-menu.php:183 +msgid "This tab displays the list of all permanently blocked IP addresses." +msgstr "이 탭에는 영구적으로 차단된 모든 IP 주소 목록이 표시됩니다." + +#: admin/wp-security-dashboard-menu.php:184 +#: admin/wp-security-spam-menu.php:339 +msgid "NOTE: This feature does NOT use the .htaccess file to permanently block the IP addresses so it should be compatible with all web servers running WordPress." +msgstr "참고: 이 기능은 .htaccess 파일을 사용하여 IP 주소를 영구적으로 차단하지 않으므로 WordPress를 실행하는 모든 웹 서버와 호환되어야 합니다." + +#: admin/wp-security-dashboard-menu.php:189 +msgid "Permanently blocked IP addresses" +msgstr "영구적으로 차단된 IP 주소" + +#: admin/wp-security-dashboard-menu.php:200 +#: admin/wp-security-firewall-menu.php:1151 +#: admin/wp-security-user-login-menu.php:485 +#: admin/wp-security-user-login-menu.php:643 +#: admin/wp-security-user-registration-menu.php:164 +msgid "Search" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:238 +#: admin/wp-security-dashboard-menu.php:249 +#: admin/wp-security-dashboard-menu.php:260 +msgid "All In One WP Security & Firewall" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:250 +msgid "Debug logs have been cleared." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:261 +msgid "Unable to clear the logs; an invalid nonce was provided" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:274 +msgid "Debug log options" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:281 +msgid "Clear logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:289 +msgid "Debug logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:362 +msgid "Security strength meter" +msgstr "보안 강도 계수" + +#: admin/wp-security-dashboard-menu.php:363 +msgid "Security points breakdown" +msgstr "보안 지점 고장" + +#: admin/wp-security-dashboard-menu.php:364 +msgid "Spread the word" +msgstr "입소문 내기" + +#: admin/wp-security-dashboard-menu.php:365 +msgid "Get to know the developers" +msgstr "개발자에 대해 알아가기" + +#: admin/wp-security-dashboard-menu.php:366 +msgid "Critical feature status" +msgstr "중요 기능 상태" + +#: admin/wp-security-dashboard-menu.php:367 +msgid "Last 5 logins" +msgstr "마지막 5 로그인" + +#: admin/wp-security-dashboard-menu.php:368 +msgid "Maintenance mode status" +msgstr "유지 관리 모드 상태" + +#: admin/wp-security-dashboard-menu.php:373 +#: admin/wp-security-dashboard-menu.php:664 +#: admin/wp-security-user-login-menu.php:57 +msgid "Logged in users" +msgstr "로그인한 사용자" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:417 +msgid "Total Achievable Points: " +msgstr "총 달성 가능한 포인트:" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:419 +msgid "Current Score of Your Site: " +msgstr "사이트의 현재 점수:" + +#: admin/wp-security-dashboard-menu.php:472 +msgid "We are working hard to make your WordPress site more secure. Please support us, here is how:" +msgstr "우리는 당신의 워드 프레스 사이트를 더 안전하게 만들기 위해 열심히 노력하고 있습니다. 우리를 지원하십시오, 여기에 방법입니다 :" + +#: admin/wp-security-dashboard-menu.php:473 +msgid "Follow us on" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:477 +msgid "Post to Twitter" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:481 +msgid "Give us a good rating" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:488 +msgid "Wanna know more about the developers behind this plugin?" +msgstr "이 플러그인 뒤에 개발자에 대 한 자세한 내용은?" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:499 +msgid "Below is the current status of the critical features that you should activate on your site to achieve a minimum level of recommended security" +msgstr "다음은 최소한의 권장 보안을 달성하기 위해 사이트에서 활성화해야 하는 중요한 기능의 현재 상태입니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:503 +msgid "Admin username" +msgstr "관리자 아이디" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:533 +msgid "File permission" +msgstr "파일 권한" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:548 +msgid "Basic firewall" +msgstr "기본 방화벽" + +#: admin/wp-security-dashboard-menu.php:577 +msgid "No data found." +msgstr "데이터가 없습니다" + +#: admin/wp-security-dashboard-menu.php:581 +msgid "Last 5 logins summary:" +msgstr "마지막 5 개의 로그인 요약:" + +#: admin/wp-security-dashboard-menu.php:585 +msgid "User" +msgstr "사용자" + +#: admin/wp-security-dashboard-menu.php:586 +#: admin/wp-security-list-404.php:95 +#: admin/wp-security-list-login-fails.php:56 +#: admin/wp-security-list-permanent-blocked-ip.php:68 +msgid "Date" +msgstr "날짜" + +#: admin/wp-security-dashboard-menu.php:587 +msgid "IP" +msgstr "IP" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:608 +msgid "Maintenance mode is currently enabled. Remember to turn it off when you are done" +msgstr "현재 유지 관리 모드가 활성화되어 있습니다. 완료되면 꺼야 합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:610 +msgid "Maintenance mode is currently off." +msgstr "유지 관리 모드가 현재 해제되었습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:614 +msgid "Maintenance mode" +msgstr "유지관리 모드" + +#: admin/wp-security-dashboard-menu.php:632 +msgid "Cookie based brute force" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:636 +#: admin/wp-security-dashboard-menu.php:654 +msgid "The %s feature is currently active." +msgstr "%s 피쳐는 현재 활성 상태입니다." + +#: admin/wp-security-dashboard-menu.php:637 +#: admin/wp-security-dashboard-menu.php:655 +msgid "Your new WordPress login URL is now:" +msgstr "당신의 새 워드프레스 로그인 URL:" + +#: admin/wp-security-dashboard-menu.php:666 +msgid "Number of users currently logged into your site (including you) is:" +msgstr "현재 사이트에 로그인한 사용자 수(회원 포함):" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:667 +msgid "There are no other users currently logged in." +msgstr "현재 로그인한 다른 사용자는 없습니다." + +#: admin/wp-security-dashboard-menu.php:680 +msgid "Number of users currently logged in site-wide (including you) is:" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:681 +msgid "There are no other site-wide users currently logged in." +msgstr "현재 로그인한 사이트 전체의 다른 사용자는 없습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:694 +#: admin/wp-security-dashboard-menu.php:711 +msgid "Go to the %s menu to see more details" +msgstr "자세한 내용을 보려면 %s 메뉴로 이동" + +#: admin/wp-security-dashboard-menu.php:707 +msgid "There are no IP addresses currently locked out." +msgstr "현재 잠겨 있는 IP 주소가 없습니다." + +#: admin/wp-security-dashboard-menu.php:710 +msgid "Number of temporarily locked out IP addresses: " +msgstr "일시적으로 잠긴 IP 주소 수:" + +#: admin/wp-security-database-menu.php:52 +msgid "UpdraftPlus is installed but currently not active." +msgstr "" + +#: admin/wp-security-database-menu.php:52 +msgid "Follow this link to activate UpdraftPlus, to take a backup." +msgstr "" + +#: admin/wp-security-database-menu.php:57 +msgid "Follow this link to install UpdraftPlus, to take a database backup." +msgstr "" + +#: admin/wp-security-database-menu.php:87 +#: admin/wp-security-database-menu.php:92 +msgid "Database backup" +msgstr "DB 백업" + +#: admin/wp-security-database-menu.php:91 +#: classes/grade-system/wp-security-feature-item-manager.php:65 +msgid "Database prefix" +msgstr "DB 접두사" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:119 +msgid "Database security" +msgstr "데이터베이스 보안" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:147 +msgid "Nonce check failed for DB prefix change operation!" +msgstr "NONCE 는 DB 접두사 변경 작업에 대한 실패 확인!" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:155 +msgid "The plugin has detected that it cannot write to the wp-config.php file. This feature can only be used if the plugin can successfully write to the wp-config.php file." +msgstr "플러그인은 wp-config.php 파일에 쓸 수 없다는 것을 감지했습니다. 이 기능은 플러그인이 wp-config.php 파일에 성공적으로 쓸 수 있는 경우에만 사용할 수 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:168 +msgid "Please enter a value for the DB prefix." +msgstr "DB 접두사값을 입력하십시오." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:177 +msgid "ERROR: The table prefix can only contain numbers, letters, and underscores." +msgstr "오류: 테이블 접두사에는 숫자, 문자 및 밑줄만 포함될 수 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:186 +#: admin/wp-security-database-menu.php:245 +msgid "Change database prefix" +msgstr "데이터베이스 접두사 변경" + +#: admin/wp-security-database-menu.php:189 +msgid "Your WordPress database is the most important asset of your website because it contains a lot of your site's precious information." +msgstr "" + +#: admin/wp-security-database-menu.php:190 +msgid "The database is also a target for hackers via methods such as SQL injections and malicious and automated code which targets certain tables." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:191 +msgid "One way to add a layer of protection for your DB is to change the default WordPress table prefix from \"wp_\" to something else which will be difficult for hackers to guess." +msgstr "DB에 대한 보호 계층을 추가하는 한 가지 방법은 기본 워드 프레스 테이블 접두사를 \"wp_\"에서 해커가 추측하기 어려운 다른 것으로 변경하는 것입니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:192 +msgid "This feature allows you to easily change the prefix to a value of your choice or to a random value set by this plugin." +msgstr "이 기능을 사용하면 접두사를 원하는 값또는 이 플러그인으로 설정한 임의값으로 쉽게 변경할 수 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:198 +msgid "Database prefix options" +msgstr "DB 접두사 옵션" + +#: admin/wp-security-database-menu.php:210 +msgid "database backup" +msgstr "DB 백업" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:211 +msgid "It is recommended that you perform a %s before using this feature" +msgstr "이 기능을 사용하기 전에 %s를 수행하는 것이 좋습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:221 +msgid "Current database table prefix" +msgstr "현재 DB 테이블 접두사" + +#: admin/wp-security-database-menu.php:227 +msgid "Your site is currently using the default WordPress database prefix value of \"wp_\"." +msgstr "" + +#: admin/wp-security-database-menu.php:227 +msgid "To increase your site's security you should consider changing the database prefix value to another value." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:234 +msgid "Generate new database table prefix" +msgstr "새 DB 테이블 접두사 생성" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:238 +msgid "Check this if you want the plugin to generate a random 6 character string for the table prefix" +msgstr "플러그인이 테이블 접두사에 대한 임의의 6 자 문자열을 생성하려는 경우이 확인" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:239 +msgid "OR" +msgstr "또는" + +#: admin/wp-security-database-menu.php:241 +msgid "Choose your own database prefix by specifying a string which contains letters and/or numbers and/or underscores. Example: xyz_" +msgstr "" + +#: admin/wp-security-database-menu.php:265 +msgid "Take a database backup using UpdraftPlus" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:270 +msgid "Manual backup" +msgstr "수동 백업" + +#: admin/wp-security-database-menu.php:274 +msgid "UpdraftPlus Backup/Restore" +msgstr "" + +#: admin/wp-security-database-menu.php:274 +msgid "Your backups are on the UpdraftPlus Backup/Restore admin page." +msgstr "" + +#: admin/wp-security-database-menu.php:276 +msgid "Create database backup now" +msgstr "" + +#: admin/wp-security-database-menu.php:308 +msgid "Error - Could not get tables or no tables found!" +msgstr "오류 - 테이블을 얻을 수 없거나 테이블을 찾을 수 없습니다!" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:312 +msgid "Starting DB prefix change operations....." +msgstr "시작 DB 접두사 변경 작업....." + +#: admin/wp-security-database-menu.php:314 +msgid "Your WordPress system has a total of %s tables and your new DB prefix will be: %s" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:320 +#: classes/wp-security-utility.php:306 +msgid "Failed to make a backup of the wp-config.php file. This operation will not go ahead." +msgstr "wp-config.php 파일의 백업을 하지 못했습니다. 이 작업은 진행되지 않습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:324 +msgid "A backup copy of your wp-config.php file was created successfully!" +msgstr "wp-config.php 파일의 백업 복사본이 성공적으로 만들어졌습니다!" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:351 +msgid "%s table name update failed" +msgstr "%s 테이블 이름 업데이트 실패" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:363 +msgid "Please change the prefix manually for the above tables to: %s" +msgstr "위의 테이블에 대해 수동으로 접두사를 변경하십시오: %s" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:366 +msgid "%s tables had their prefix updated successfully!" +msgstr "%s 테이블은 접두사를 성공적으로 업데이트했습니다!" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:387 +msgid "wp-config.php file was updated successfully!" +msgstr "wp-config.php 파일이 성공적으로 업데이트되었습니다!" + +#: admin/wp-security-database-menu.php:390 +msgid "The \"wp-config.php\" file was not able to be modified." +msgstr "" + +#: admin/wp-security-database-menu.php:390 +msgid "Please modify this file manually using your favourite editor and search for variable \"$table_prefix\" and assign the following value to that variable: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:401 +#: admin/wp-security-database-menu.php:420 +msgid "Update of table %s failed: unable to change %s to %s" +msgstr "테이블 %s 업데이트 실패: %s를 %s로 변경할 수 없음" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:405 +msgid "The options table records which had references to the old DB prefix were updated successfully!" +msgstr "이전 DB 접두사에 대한 참조가 있는 옵션 테이블 레코드가 성공적으로 업데이트되었습니다!" + +#: admin/wp-security-database-menu.php:424 +msgid "The %s table records which had references to the old DB prefix were updated successfully!" +msgstr "이전 DB 접두사에 대한 참조가 있는 %s 테이블 레코드가 성공적으로 업데이트되었습니다!" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:452 +msgid "Error updating user_meta table where new meta_key = %s, old meta_key = %s and user_id = %s." +msgstr "새 meta_key = %s, 이전 meta_key = %s 및 user_id = %s가 있는 user_meta 테이블을 업데이트하는 오류입니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:457 +msgid "The usermeta table records which had references to the old DB prefix were updated successfully!" +msgstr "이전 DB 접두사에 대한 참조가 있는 사용자메타 테이블 레코드가 성공적으로 업데이트되었습니다!" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:459 +msgid "The database prefix change tasks have been completed." +msgstr "DB 접두사 변경 작업이 완료되었습니다." + +#: admin/wp-security-database-menu.php:503 +msgid "Checking for MySQL tables of type \"view\"....." +msgstr "유형 \"보기\"의 MySQL 테이블을 확인합니다.." + +#: admin/wp-security-database-menu.php:520 +msgid "Update of the following MySQL view definition failed: %s" +msgstr "다음 MySQL 보기 정의 업데이트 실패: %s" + +#: admin/wp-security-database-menu.php:527 +msgid "%s view definitions were updated successfully!" +msgstr "%s 보기 정의가 성공적으로 업데이트되었습니다!" + +#: admin/wp-security-filescan-menu.php:26 +#: classes/grade-system/wp-security-feature-item-manager.php:127 +msgid "File change detection" +msgstr "파일 변경 감지" + +#: admin/wp-security-filescan-menu.php:27 +msgid "Malware scan" +msgstr "악성 코드 검사" + +#: admin/wp-security-filescan-menu.php:88 +msgid "There have been no file changes since the last scan." +msgstr "마지막 검사 이후 파일 변경 사항이 없습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:98 +msgid "Nonce check failed for manual file change detection scan operation!" +msgstr "Nonce 확인 수동 파일 변경 감지 검사 작업에 대 한 실패!" + +#: admin/wp-security-filescan-menu.php:104 +msgid "There was an error during the file change detection scan. Please check the AIOS logs." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:110 +msgid "The plugin has detected that this is your first file change detection scan. The file details from this scan will be used to detect file changes for future scans." +msgstr "플러그인이 첫 번째 파일 변경 감지 검사임을 감지했습니다. 이 검사의 파일 세부 정보는 향후 검사에 대한 파일 변경 내용을 감지하는 데 사용됩니다!" + +#: admin/wp-security-filescan-menu.php:112 +msgid "Scan complete - There were no file changes detected!" +msgstr "검사 완료 - 파일 변경 사항이 검색되지 않았습니다!" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:133 +msgid "You entered a non numeric value for the \"backup time interval\" field. It has been set to the default value." +msgstr "\"백업 시간 간격\" 필드에 대한 비 숫자 값을 입력했습니다. 기본 값으로 설정되었습니다." + +#: admin/wp-security-filescan-menu.php:167 +msgid "The following address was removed because it is not a valid email address: " +msgstr "유효한 이메일 주소가 아니므로 다음 주소가 삭제되었습니다." + +#: admin/wp-security-filescan-menu.php:206 +msgid "NEW SCAN COMPLETED: The plugin has detected that you have made changes to the \"File Types To Ignore\" or \"Files To Ignore\" fields." +msgstr "" + +#: admin/wp-security-filescan-menu.php:206 +msgid "In order to ensure that future scan results are accurate, the old scan data has been refreshed." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:215 +msgid "All In One WP Security & Firewall has detected that there was a change in your host's files." +msgstr "모든 하나의 WP 보안 및 방화벽은 호스트의 파일에 변경이 있음을 감지했습니다." + +#: admin/wp-security-filescan-menu.php:217 +msgid "View scan details and clear this message" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:226 +msgid "If given an opportunity hackers can insert their code or files into your system which they can then use to carry out malicious acts on your site." +msgstr "기회가 주어진 경우 해커는 자신의 코드 또는 파일을 시스템에 삽입할 수 있으며, 이 파일을 시스템에 삽입하여 사이트에서 악의적인 행위를 수행하는 데 사용할 수 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:227 +msgid "Being informed of any changes in your files can be a good way to quickly prevent a hacker from causing damage to your website." +msgstr "파일의 변경 사항을 알리는 것은 해커가 웹 사이트에 손상을 입히는 것을 신속하게 방지하는 좋은 방법이 될 수 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:228 +msgid "In general, WordPress core and plugin files and file types such as \".php\" or \".js\" should not change often and when they do, it is important that you are made aware when a change occurs and which file was affected." +msgstr "일반적으로 워드 프레스 코어 및 플러그인 파일 및 \".php\" 또는 \".js\"와 같은 파일 유형은 자주 변경되지 않아야하며, 그렇게 할 때 변경이 발생하고 어떤 파일이 영향을 받은 지 알 수 있어야 합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:229 +msgid "The \"File Change Detection Feature\" will notify you of any file change which occurs on your system, including the addition and deletion of files by performing a regular automated or manual scan of your system's files." +msgstr "\"파일 변경 감지 기능\"은 시스템 파일의 정기적인 자동 또는 수동 스캔을 수행하여 파일의 추가 및 삭제를 포함하여 시스템에서 발생하는 파일 변경 사항을 알려줍니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:230 +msgid "This feature also allows you to exclude certain files or folders from the scan in cases where you know that they change often as part of their normal operation. (For example log files and certain caching plugin files may change often and hence you may choose to exclude such files from the file change detection scan)" +msgstr "또한 이 기능을 사용하면 정규 작업의 일부로 자주 변경되는 경우 특정 파일 이나 폴더를 검색에서 제외할 수 있습니다. (예를 들어 로그 파일 및 특정 캐싱 플러그인 파일은 자주 변경될 수 있으므로 파일 변경 검색에서 이러한 파일을 제외하도록 선택할 수 있습니다.)" + +#: admin/wp-security-filescan-menu.php:241 +msgid "It appears that your server is using an old PHP version which is missing the %s. The file scanner feature needs this class in order to work. If you would like to use this feature please upgrade your server PHP version to 5.3 or greater." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:249 +msgid "Manual file change detection scan" +msgstr "수동 파일 변경 감지 스캔" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:255 +msgid "To perform a manual file change detection scan click on the button below." +msgstr "수동 파일 변경 검색 스캔을 수행하려면 아래 버튼을 클릭하십시오." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:258 +msgid "Perform scan now" +msgstr "지금 검사 수행" + +#: admin/wp-security-filescan-menu.php:262 +msgid "View last saved file change results" +msgstr "마지막으로 저장된 파일 변경 결과 보기" + +#: admin/wp-security-filescan-menu.php:268 +msgid "Click the button below to view the saved file change results from the last scan." +msgstr "아래 버튼을 클릭하여 마지막 검사에서 저장된 파일 변경 결과를 봅니다." + +#: admin/wp-security-filescan-menu.php:271 +msgid "View last file change" +msgstr "마지막 파일 변경 보기" + +#: admin/wp-security-filescan-menu.php:275 +msgid "File change detection settings" +msgstr "파일 변경 검색 설정" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:287 +msgid "Enable automated file change detection scan" +msgstr "자동 파일 변경 감지 검색 활성화" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:290 +msgid "Check this if you want the system to automatically/periodically scan your files to check for file changes based on the settings below" +msgstr "시스템이 파일을 자동으로/주기적으로 스캔하여 아래 설정에 따라 파일 변경 사항을 확인하려면 이 방법을 확인합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:294 +msgid "Scan time interval" +msgstr "스캔 시간 간격" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:297 +msgid "Hours" +msgstr "시간" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:298 +msgid "Days" +msgstr "일" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:299 +msgid "Weeks" +msgstr "주" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:301 +msgid "Set the value for how often you would like a scan to occur" +msgstr "검사를 수행하려는 빈도에 대한 값을 설정합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:305 +msgid "File types to ignore" +msgstr "무시할 파일 유형" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:308 +msgid "Enter each file type or extension on a new line which you wish to exclude from the file change detection scan." +msgstr "파일 변경 검색검색에서 제외하려는 새 줄에 각 파일 유형 또는 확장을 입력합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:312 +msgid "You can exclude file types from the scan which would not normally pose any security threat if they were changed. These can include things such as image files." +msgstr "일반적으로 보안 위협이 변경되지 않는 검색에서 파일 형식을 제외할 수 있습니다. 여기에는 이미지 파일과 같은 것들이 포함될 수 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:313 +msgid "Example: If you want the scanner to ignore files of type jpg, png, and bmp, then you would enter the following:" +msgstr "예: 스캐너가 jpg, png 및 bmp 유형 의 파일을 무시하려면 다음을 입력합니다." + +#: admin/wp-security-filescan-menu.php:314 +msgid "jpg" +msgstr "" + +#: admin/wp-security-filescan-menu.php:315 +msgid "png" +msgstr "" + +#: admin/wp-security-filescan-menu.php:316 +msgid "bmp" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:322 +msgid "Files/Directories to ignore" +msgstr "무시할 파일/디렉터리" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:325 +msgid "Enter each file or directory on a new line which you wish to exclude from the file change detection scan." +msgstr "파일 변경 검색 검색에서 제외하려는 새 줄에 각 파일 또는 디렉터리를 입력합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:329 +msgid "You can exclude specific files/directories from the scan which would not normally pose any security threat if they were changed. These can include things such as log files." +msgstr "특정 파일/디렉터리가 변경된 경우 일반적으로 보안 위협을 제기하지 않는 검색에서 제외할 수 있습니다. 여기에는 로그 파일과 같은 것들이 포함될 수 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:330 +msgid "Example: If you want the scanner to ignore certain files in different directories or whole directories, then you would enter the following:" +msgstr "예: 스캐너가 다른 디렉터리 또는 전체 디렉터리의 특정 파일을 무시하려면 다음을 입력합니다." + +#: admin/wp-security-filescan-menu.php:331 +msgid "cache/config/master.php" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:332 +msgid "somedirectory" +msgstr "일부 디렉터리" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:339 +msgid "Send email when change detected" +msgstr "변경이 감지되면 이메일 보내기" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:343 +msgid "Check this if you want the system to email you if a file change was detected" +msgstr "파일 변경이 감지된 경우 시스템에서 이메일을 보내려면 이 방법을 확인합니다." + +#: admin/wp-security-filescan-menu.php:347 +msgid "Enter one or more email addresses on a new line." +msgstr "새 줄에 하나 이상의 이메일 주소를 입력합니다." + +#: admin/wp-security-filescan-menu.php:364 +msgid "What is malware?" +msgstr "악성 코드란 무엇입니까?" + +#: admin/wp-security-filescan-menu.php:365 +msgid "The word malware stands for Malicious Software. It can consist of things like trojan horses, adware, worms, spyware and any other undesirable code which a hacker will try to inject into your website." +msgstr "악성 코드라는 단어는 악성 소프트웨어를 의미합니다. 그것은 트로이 목마 같은 것 들 구성될 수 있습니다., 애드웨어, 웜, 스파이웨어 및 해커 웹사이트에 주입 하려고 합니다 다른 바람직하지 않은 코드." + +#: admin/wp-security-filescan-menu.php:366 +msgid "Often when malware code has been inserted into your site you will normally not notice anything out of the ordinary based on appearances, but it can have a dramatic effect on your site's search ranking." +msgstr "종종 악성 코드는 사이트에 삽입 된 경우 당신은 일반적으로 외모에 따라 일반 아무것도 통지하지 않습니다, 하지만 사이트의 검색 순위에 극적인 영향을 미칠 수 있습니다." + +#: admin/wp-security-filescan-menu.php:367 +msgid "This is because the bots and spiders from search engines such as Google have the capability to detect malware when they are indexing the pages on your site, and consequently they can blacklist your website which will in turn affect your search rankings." +msgstr "Google과 같은 검색 엔진의 봇과 거미는 사이트의 페이지를 인덱싱할 때 맬웨어를 탐지할 수 있으며, 따라서 웹 사이트를 블랙리스트에 표시하여 검색 순위에 영향을 줄 수 있기 때문입니다." + +#: admin/wp-security-filescan-menu.php:369 +msgid "CLICK HERE" +msgstr "" + +#: admin/wp-security-filescan-menu.php:371 +msgid "Scanning for malware" +msgstr "악성 코드 검사중" + +#: admin/wp-security-filescan-menu.php:372 +msgid "Due to the constantly changing and complex nature of Malware, scanning for such things using a standalone plugin will not work reliably. This is something best done via an external scan of your site regularly." +msgstr "악성 코드는 끊임없이 변화하고 복잡한 특성으로 인해 독립 형 플러그인을 사용하여 이러한 것들을 검사하는 것은 안정적으로 작동하지 않습니다. 이것은 정기적으로 사이트의 외부 검사를 통해 수행 하는 것이 가장 좋습니다." + +#: admin/wp-security-filescan-menu.php:373 +msgid "This is why we have created an easy-to-use scanning service which is hosted off our own server which will scan your site for malware once every day and notify you if it finds anything." +msgstr "이 때문에 우리는 매일 한 번 악성 코드에 대한 사이트를 스캔하고 아무것도 발견하면 알려 우리의 자신의 서버에서 호스팅되는 사용하기 쉬운 스캔 서비스를 만들었습니다." + +#: admin/wp-security-filescan-menu.php:374 +msgid "When you sign up for this service you will get the following:" +msgstr "이 서비스에 가입하면 다음을 얻을 수 있습니다." + +#: admin/wp-security-filescan-menu.php:376 +msgid "Automatic daily scan of 1 website" +msgstr "1 웹 사이트의 자동 일일 검사" + +#: admin/wp-security-filescan-menu.php:377 +msgid "Automatic malware and blacklist monitoring" +msgstr "" + +#: admin/wp-security-filescan-menu.php:378 +msgid "Automatic email alerting" +msgstr "자동 이메일 경고" + +#: admin/wp-security-filescan-menu.php:379 +msgid "Site uptime monitoring" +msgstr "사이트 가동 시간 모니터링" + +#: admin/wp-security-filescan-menu.php:380 +msgid "Site response time monitoring" +msgstr "현장 대응 시간 모니터링" + +#: admin/wp-security-filescan-menu.php:381 +msgid "We provide advice for malware cleanup" +msgstr "우리는 악성 코드 정리에 대한 조언을 제공합니다" + +#: admin/wp-security-filescan-menu.php:382 +msgid "Blacklist removal" +msgstr "블랙리스트 제거" + +#: admin/wp-security-filescan-menu.php:383 +msgid "No contract (cancel anytime)" +msgstr "" + +#: admin/wp-security-filescan-menu.php:385 +msgid "To learn more please %s." +msgstr "자세한 내용은 %s를 참조하십시오." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:406 +msgid "Latest file change scan results" +msgstr "최신 파일 변경 검사 결과" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:416 +msgid "The following files were added to your host." +msgstr "호스트에 다음 파일이 추가되었습니다." + +#: admin/wp-security-filescan-menu.php:419 +#: admin/wp-security-filescan-menu.php:440 +#: admin/wp-security-filescan-menu.php:464 +msgid "File" +msgstr "" + +#: admin/wp-security-filescan-menu.php:420 +#: admin/wp-security-filescan-menu.php:441 +#: admin/wp-security-filescan-menu.php:465 +msgid "File size" +msgstr "" + +#: admin/wp-security-filescan-menu.php:421 +#: admin/wp-security-filescan-menu.php:442 +#: admin/wp-security-filescan-menu.php:466 +msgid "File modified" +msgstr "" + +#: admin/wp-security-filescan-menu.php:437 +msgid "The following files were removed from your host." +msgstr "" + +#: admin/wp-security-filescan-menu.php:461 +msgid "The following files were changed on your host." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:26 +#: classes/grade-system/wp-security-feature-item-manager.php:69 +msgid "File permissions" +msgstr "파일 사용 권한" + +#: admin/wp-security-filesystem-menu.php:27 +msgid "PHP file editing" +msgstr "PHP 파일 편집" + +#: admin/wp-security-filesystem-menu.php:28 +msgid "WP file access" +msgstr "WP 파일 액세스" + +#: admin/wp-security-filesystem-menu.php:29 +msgid "Host system logs" +msgstr "호스트 시스템 로그" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filesystem-menu.php:55 +msgid "Filesystem security" +msgstr "파일 시스템 보안" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filesystem-menu.php:80 +msgid "Nonce check failed for manual DB backup operation!" +msgstr "Nonce 확인 수동 DB 백업 작업에 대 한 실패!" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filesystem-menu.php:90 +msgid "The permissions for %s were successfully changed to %s" +msgstr "%s에 대한 사용 권한은 %s로 성공적으로 변경되었습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filesystem-menu.php:94 +msgid "Unable to change permissions for %s!" +msgstr "%s에 대한 권한을 변경할 수 없습니다!" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filesystem-menu.php:100 +msgid "File permissions scan" +msgstr "파일 권한 검사" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filesystem-menu.php:103 +msgid "Your WordPress file and folder permission settings govern the accessibility and read/write privileges of the files and folders which make up your WP installation." +msgstr "워드 프레스 파일 및 폴더 권한 설정은 액세스 가능성을 제어하고 WP 설치를 구성하는 파일 및 폴더의 권한을 읽고 작성합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filesystem-menu.php:104 +msgid "Your WP installation already comes with reasonably secure file permission settings for the filesystem." +msgstr "WP 설치에는 파일 시스템에 대한 합리적으로 안전한 파일 권한 설정이 이미 함께 제공됩니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filesystem-menu.php:105 +msgid "However, sometimes people or other plugins modify the various permission settings of certain core WP folders or files such that they end up making their site less secure because they chose the wrong permission values." +msgstr "그러나 때로는 사람 또는 다른 플러그인이 잘못된 권한 값을 선택했기 때문에 사이트를 덜 안전하게 만들 수 있도록 특정 핵심 WP 폴더 또는 파일의 다양한 권한 설정을 수정합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filesystem-menu.php:106 +msgid "This feature will scan the critical WP core folders and files and will highlight any permission settings which are insecure." +msgstr "이 기능은 중요한 WP 핵심 폴더와 파일을 스캔하고 안전하지 않은 모든 권한 설정을 강조 표시합니다." + +#: admin/wp-security-filesystem-menu.php:114 +msgid "This plugin has detected that your site is running on a Windows server." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:115 +msgid "This feature is not applicable for Windows server installations." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:121 +msgid "WP directory and file permissions scan results" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filesystem-menu.php:133 +#: admin/wp-security-filesystem-menu.php:152 +msgid "Name" +msgstr "이름" + +#: admin/wp-security-filesystem-menu.php:134 +#: admin/wp-security-filesystem-menu.php:153 +msgid "File/Folder" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:135 +#: admin/wp-security-filesystem-menu.php:154 +msgid "Current permissions" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:136 +#: admin/wp-security-filesystem-menu.php:155 +msgid "Recommended permissions" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:137 +#: admin/wp-security-filesystem-menu.php:156 +msgid "Recommended action" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:195 +msgid "Your PHP file editing settings were saved successfully." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:199 +msgid "Operation failed! Unable to modify or make a backup of wp-config.php file!" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:212 +#: classes/grade-system/wp-security-feature-item-manager.php:71 +msgid "File editing" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:215 +msgid "The WordPress Dashboard by default allows administrators to edit PHP files, such as plugin and theme files." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:216 +msgid "This is often the first tool an attacker will use if able to login, since it allows code execution." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:217 +msgid "This feature will disable the ability for people to edit PHP files via the dashboard." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:223 +msgid "Disable PHP file editing" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:235 +msgid "Disable ability to edit PHP files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:238 +msgid "Check this if you want to remove the ability for people to edit PHP files via the WP dashboard" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:282 +msgid "You have successfully saved the Prevent Access to Default WP Files configuration." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filesystem-menu.php:286 +#: admin/wp-security-firewall-menu.php:126 +#: admin/wp-security-firewall-menu.php:346 +#: admin/wp-security-firewall-menu.php:613 +#: admin/wp-security-firewall-menu.php:912 +#: admin/wp-security-settings-menu.php:772 +#: admin/wp-security-spam-menu.php:124 +msgid "Could not write to the .htaccess file. Please check the file permissions." +msgstr ".htaccess 파일에 쓸 수 없습니다. 파일 권한을 확인하십시오." + +#: admin/wp-security-filesystem-menu.php:291 +msgid "WordPress files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:294 +msgid "This feature allows you to prevent access to files such as %s, %s and %s which are delivered with all WP installations." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:295 +msgid "By preventing access to these files you are hiding some key pieces of information (such as WordPress version info) from potential hackers." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:300 +msgid "Prevent access to default WP files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:311 +msgid "Prevent access to WP default install files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:314 +msgid "Check this if you want to prevent access to readme.html, license.txt and wp-config-sample.php." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:318 +msgid "Save setting" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:342 +msgid "System logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:345 +msgid "Sometimes your hosting platform will produce error or warning logs in a file called \"error_log\"." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:346 +msgid "Depending on the nature and cause of the error or warning, your hosting server can create multiple instances of this file in numerous directory locations of your WordPress installation." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:347 +msgid "By occasionally viewing the contents of these logs files you can keep informed of any underlying problems on your system which you might need to address." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:353 +msgid "View system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:355 +msgid "Please click the button below to view the latest system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:358 +msgid "Enter System Log File Name" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:360 +msgid "Enter your system log file name. (Defaults to error_log)" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:363 +msgid "View latest system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:365 +msgid "Loading..." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:382 +msgid "No system logs were found." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:435 +msgid "Set recommended permissions" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filesystem-menu.php:441 +msgid "No action required" +msgstr "필요한 조치가 없습니다." + +#: admin/wp-security-filesystem-menu.php:481 +msgid "Showing latest entries of error_log file: %s" +msgstr "" + +#: admin/wp-security-firewall-menu.php:28 +msgid "Basic firewall rules" +msgstr "기본 방화벽 규칙" + +#: admin/wp-security-firewall-menu.php:29 +msgid "Additional firewall rules" +msgstr "추가 방화벽 규칙" + +#: admin/wp-security-firewall-menu.php:30 +msgid "6G Blacklist firewall rules" +msgstr "6G 블랙리스트 방화벽 규칙" + +#: admin/wp-security-firewall-menu.php:31 +msgid "Internet bots" +msgstr "인터넷 봇" + +#: admin/wp-security-firewall-menu.php:32 +msgid "Prevent hotlinks" +msgstr "핫링크 방지" + +#: admin/wp-security-firewall-menu.php:33 +msgid "404 detection" +msgstr "404 감지" + +#: admin/wp-security-firewall-menu.php:34 +msgid "Custom rules" +msgstr "사용자 지정 규칙" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:122 +#: admin/wp-security-firewall-menu.php:908 +#: admin/wp-security-spam-menu.php:120 +#: admin/wp-security-spam-menu.php:494 +#: admin/wp-security-spam-menu.php:556 +#: admin/wp-security-user-registration-menu.php:95 +msgid "Settings were successfully saved" +msgstr "설정이 저장되었습니다" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:131 +#: admin/wp-security-firewall-menu.php:651 +msgid "Firewall settings" +msgstr "방화벽 설정" + +#: admin/wp-security-firewall-menu.php:138 +msgid "This should not have any impact on your site's general functionality but if you wish you can take a %s of your .htaccess file before proceeding." +msgstr "" + +#: admin/wp-security-firewall-menu.php:139 +msgid "The features in this tab allow you to activate some basic firewall security protection rules for your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:140 +msgid "The firewall functionality is achieved via the insertion of special code into your currently active .htaccess file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:151 +msgid "You have enabled the \"Completely Block Access To XMLRPC\" checkbox which means all XMLRPC functionality will be blocked." +msgstr "" + +#: admin/wp-security-firewall-menu.php:152 +msgid "By leaving this feature enabled you will prevent Jetpack or Wordpress iOS or other apps which need XMLRPC from working correctly on your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:153 +msgid "If you still need XMLRPC then uncheck the \"Completely Block Access To XMLRPC\" checkbox and enable only the \"Disable Pingback Functionality From XMLRPC\" checkbox." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:163 +msgid "Basic firewall settings" +msgstr "기본 방화벽 설정" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:171 +msgid "Enable basic firewall protection" +msgstr "기본 방화벽 보호 활성화" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:174 +msgid "Check this if you want to apply basic firewall protection to your site." +msgstr "사이트에 기본 방화벽 보호를 적용하려는 경우 이 방법을 확인합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:178 +msgid "This setting will implement the following basic firewall protection mechanisms on your site:" +msgstr "이 설정은 사이트에서 다음과 같은 기본 방화벽 보호 메커니즘을 구현합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:179 +msgid "1) Protect your htaccess file by denying access to it." +msgstr "1) 액세스 권한을 거부하여 htaccess 파일을 보호합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:180 +msgid "2) Disable the server signature." +msgstr "2) 서버 서명을 사용하지 않도록 설정합니다." + +#: admin/wp-security-firewall-menu.php:181 +msgid "3) Limit file upload size (%sMB)." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:182 +msgid "4) Protect your wp-config.php file by denying access to it." +msgstr "4) 그것에 대한 액세스를 거부하여 wp-config.php 파일을 보호합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:183 +msgid "The above firewall features will be applied via your .htaccess file and should not affect your site's overall functionality." +msgstr "위의 방화벽 기능은 .htaccess 파일을 통해 적용되며 사이트의 전반적인 기능에영향을 미치지 않아야 합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:184 +msgid "You are still advised to take a backup of your active .htaccess file just in case." +msgstr "활성 .htaccess 파일의 백업을 하는 것이 좋습니다." + +#: admin/wp-security-firewall-menu.php:190 +msgid "Max file upload size (MB)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:192 +msgid "The value for the maximum file upload size used in the .htaccess file. (Defaults to %sMB if left blank)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:200 +msgid "WordPress XMLRPC and pingback vulnerability protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:208 +msgid "Completely block access to XMLRPC" +msgstr "XMLRPC에 대한 액세스를 완전히 차단합니다." + +#: admin/wp-security-firewall-menu.php:211 +msgid "Check this if you are not using the WP XML-RPC functionality and you want to completely block external access to XMLRPC." +msgstr "WP XML-RPC 기능을 사용하지 않고 XMLRPC에 대한 외부 액세스를 완전히 차단하려는 경우 이 기능을 확인합니다." + +#: admin/wp-security-firewall-menu.php:215 +msgid "This setting will add a directive in your .htaccess to disable access to the WordPress xmlrpc.php file which is responsible for the XML-RPC functionality in WordPress." +msgstr "이 설정은 워드 프레스의 XML-RPC 기능에 대한 책임이있는 워드 프레스 xmlrpc.php 파일에 대한 액세스를 비활성화하려면 .htaccess에 지시문을 추가합니다." + +#: admin/wp-security-firewall-menu.php:216 +msgid "Hackers can exploit various vulnerabilities in the WordPress XML-RPC API in a number of ways such as:" +msgstr "해커는 다음과 같은 여러 가지 방법으로 워드 프레스 XML-RPC API의 다양한 취약점을 악용 할 수 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:217 +msgid "1) Denial of Service (DoS) attacks" +msgstr "1) 서비스 거부(DoS) 공격" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:218 +msgid "2) Hacking internal routers." +msgstr "2) 해킹 내부 라우터." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:219 +msgid "3) Scanning ports in internal networks to get info from various hosts." +msgstr "3) 다양한 호스트로부터 정보를 얻기 위해 내부 네트워크에서 포트를 스캔합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:220 +msgid "Apart from the security protection benefit, this feature may also help reduce load on your server, particularly if your site currently has a lot of unwanted traffic hitting the XML-RPC API on your installation." +msgstr "보안 보호 이점 외에도 이 기능은 특히 사이트에 현재 설치시 XML-RPC API에 영향을 미치는 원치 않는 트래픽이 많은 경우 서버의 부하를 줄이는 데 도움이 될 수 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:221 +msgid "NOTE: You should only enable this feature if you are not currently using the XML-RPC functionality on your WordPress installation." +msgstr "참고: 현재 WordPress 설치에서 XML-RPC 기능을 사용하지 않는 경우에만 이 기능을 사용하도록 설정해야 합니다." + +#: admin/wp-security-firewall-menu.php:222 +msgid "Leave this feature disabled and use the feature below if you want pingback protection but you still need XMLRPC." +msgstr "이 기능을 사용하지 않도록 두고 pingback 보호를 원하지만 여전히 XMLRPC가 필요한 경우 아래 기능을 사용합니다." + +#: admin/wp-security-firewall-menu.php:228 +msgid "Disable pingback functionality from XMLRPC" +msgstr "XMLRPC에서 Pingback 기능 비활성화" + +#: admin/wp-security-firewall-menu.php:231 +msgid "If you use Jetpack or WP iOS or other apps which need WP XML-RPC functionality then check this. This will enable protection against WordPress pingback vulnerabilities." +msgstr "Jetpack 또는 WP iOS 또는 WP XML-RPC 기능이 필요한 기타 앱을 사용하는 경우 이 기능을 확인합니다. 이렇게 하면 워드프레스 핑백 취약점을 보호할 수 있습니다." + +#: admin/wp-security-firewall-menu.php:235 +msgid "NOTE: If you use Jetpack or the Wordpress iOS or other apps then you should enable this feature but leave the \"Completely Block Access To XMLRPC\" checkbox unchecked." +msgstr "참고: Jetpack 또는 워드프레스 iOS 또는 기타 앱을 사용하는 경우 이 기능을 사용하도록 설정하지만 \"XMLRPC에 대한 완전히 차단\" 확인란을 선택하지 않은 상태로 두어야 합니다." + +#: admin/wp-security-firewall-menu.php:236 +msgid "The feature will still allow XMLRPC functionality on your site but will disable the pingback methods." +msgstr "이 기능은 여전히 사이트에서 XMLRPC 기능을 허용하지만 pingback 메서드를 비활성화합니다." + +#: admin/wp-security-firewall-menu.php:237 +msgid "This feature will also remove the \"X-Pingback\" header if it is present." +msgstr "이 기능은 \"X-Pingback\" 헤더가 있는 경우에도 제거합니다." + +#: admin/wp-security-firewall-menu.php:246 +msgid "Block access to debug log file" +msgstr "" + +#: admin/wp-security-firewall-menu.php:254 +msgid "Block access to debug.log file" +msgstr "디버그.로그 파일에 대한 액세스 차단" + +#: admin/wp-security-firewall-menu.php:257 +msgid "Check this if you want to block access to the debug.log file that WordPress creates when debug logging is enabled." +msgstr "디버그 로깅을 사용할 때 워드프레스가 만드는 debug.log 파일에 대한 액세스를 차단하려면 이 옵션을 확인합니다." + +#: admin/wp-security-firewall-menu.php:261 +msgid "WordPress has an option to turn on the debug logging to a file located in wp-content/debug.log. This file may contain sensitive information." +msgstr "워드 프레스는 wp-content/debug.log에 있는 파일에 디버그 로깅을 켤 수 있는 옵션이 있습니다. 이 파일에는 중요한 정보가 포함될 수 있습니다." + +#: admin/wp-security-firewall-menu.php:262 +msgid "Using this option will block external access to this file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:262 +msgid "You can still access this file by logging into your site via FTP." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:270 +msgid "Save basic firewall settings" +msgstr "기본 방화벽 설정 저장" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:342 +msgid "You have successfully saved the Additional Firewall Protection configuration" +msgstr "추가 방화벽 보호 구성을 성공적으로 저장했습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:356 +msgid "Additional firewall protection" +msgstr "추가 방화벽 보호" + +#: admin/wp-security-firewall-menu.php:360 +msgid "Due to the nature of the code being inserted to the .htaccess file, this feature may break some functionality for certain plugins and you are therefore advised to take a %s of .htaccess before applying this configuration." +msgstr "" + +#: admin/wp-security-firewall-menu.php:362 +msgid "This feature allows you to activate more advanced firewall settings to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:363 +msgid "The advanced firewall rules are applied via the insertion of special code to your currently active .htaccess file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:372 +msgid "Listing of directory contents" +msgstr "" + +#: admin/wp-security-firewall-menu.php:381 +#: classes/grade-system/wp-security-feature-item-manager.php:85 +msgid "Disable index views" +msgstr "" + +#: admin/wp-security-firewall-menu.php:384 +msgid "Check this if you want to disable directory and file listing." +msgstr "" + +#: admin/wp-security-firewall-menu.php:389 +msgid "By default, an Apache server will allow the listing of the contents of a directory if it doesn't contain an index.php file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:391 +msgid "This feature will prevent the listing of contents for all directories." +msgstr "" + +#: admin/wp-security-firewall-menu.php:393 +msgid "NOTE: In order for this feature to work \"AllowOverride\" of the Indexes directive must be enabled in your httpd.conf file. Ask your hosting provider to check this if you don't have access to httpd.conf" +msgstr "" + +#: admin/wp-security-firewall-menu.php:402 +msgid "Trace and track" +msgstr "" + +#: admin/wp-security-firewall-menu.php:411 +#: classes/grade-system/wp-security-feature-item-manager.php:86 +msgid "Disable trace and track" +msgstr "" + +#: admin/wp-security-firewall-menu.php:414 +msgid "Check this if you want to disable trace and track." +msgstr "" + +#: admin/wp-security-firewall-menu.php:419 +msgid "HTTP Trace attack (XST) can be used to return header requests and grab cookies and other information." +msgstr "" + +#: admin/wp-security-firewall-menu.php:421 +msgid "This hacking technique is usually used together with cross site scripting attacks (XSS)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:423 +msgid "Disabling trace and track on your site will help prevent HTTP Trace attacks." +msgstr "" + +#: admin/wp-security-firewall-menu.php:432 +msgid "Proxy comment posting" +msgstr "" + +#: admin/wp-security-firewall-menu.php:442 +msgid "Forbid proxy comment posting" +msgstr "" + +#: admin/wp-security-firewall-menu.php:445 +msgid "Check this if you want to forbid proxy comment posting." +msgstr "" + +#: admin/wp-security-firewall-menu.php:450 +msgid "This setting will deny any requests that use a proxy server when posting comments." +msgstr "" + +#: admin/wp-security-firewall-menu.php:451 +msgid "By forbidding proxy comments you are in effect eliminating some spam and other proxy requests." +msgstr "" + +#: admin/wp-security-firewall-menu.php:460 +msgid "Bad query strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:470 +msgid "Deny bad query strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:473 +msgid "This will help protect you against malicious queries via XSS." +msgstr "" + +#: admin/wp-security-firewall-menu.php:478 +msgid "This feature will write rules in your .htaccess file to prevent malicious string attacks on your site using XSS." +msgstr "" + +#: admin/wp-security-firewall-menu.php:479 +msgid "NOTE: Some of these strings might be used for plugins or themes and hence this might break some functionality." +msgstr "" + +#: admin/wp-security-firewall-menu.php:480 +#: admin/wp-security-firewall-menu.php:510 +msgid "You are therefore strongly advised to take a backup of your active .htaccess file before applying this feature." +msgstr "" + +#: admin/wp-security-firewall-menu.php:489 +#: classes/grade-system/wp-security-feature-item-manager.php:89 +msgid "Advanced character string filter" +msgstr "" + +#: admin/wp-security-firewall-menu.php:499 +msgid "Enable advanced character string filter" +msgstr "" + +#: admin/wp-security-firewall-menu.php:502 +msgid "This will block bad character matches from XSS." +msgstr "" + +#: admin/wp-security-firewall-menu.php:507 +msgid "This is an advanced character string filter to prevent malicious string attacks on your site coming from Cross Site Scripting (XSS)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:508 +msgid "This setting matches for common malicious string patterns and exploits and will produce a 403 error for the hacker attempting the query." +msgstr "" + +#: admin/wp-security-firewall-menu.php:509 +msgid "NOTE: Some strings for this setting might break some functionality." +msgstr "" + +#: admin/wp-security-firewall-menu.php:518 +msgid "Save additional firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:609 +msgid "You have successfully saved the 5G/6G Firewall Protection configuration" +msgstr "" + +#: admin/wp-security-firewall-menu.php:633 +msgid "All in One WP Security and Firewall" +msgstr "" + +#: admin/wp-security-firewall-menu.php:634 +msgid "We were unable to access the firewall's configuration file:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:636 +msgid "As a result, the firewall will be unavailable." +msgstr "" + +#: admin/wp-security-firewall-menu.php:637 +msgid "Please check your PHP error log for further information." +msgstr "" + +#: admin/wp-security-firewall-menu.php:638 +msgid "If you're unable to locate your PHP log file, please contact your web hosting company to ask them where it can be found on their setup." +msgstr "" + +#: admin/wp-security-firewall-menu.php:655 +msgid "This feature allows you to activate the %s (or legacy %s) firewall security protection rules designed and produced by %s." +msgstr "" + +#: admin/wp-security-firewall-menu.php:656 +msgid "The 6G Blacklist is updated and improved version of 5G Blacklist. If you have 5G Blacklist active, you might consider activating 6G Blacklist instead." +msgstr "" + +#: admin/wp-security-firewall-menu.php:657 +msgid "The 6G Blacklist is a simple, flexible blacklist that helps reduce the number of malicious URL requests that hit your website." +msgstr "" + +#: admin/wp-security-firewall-menu.php:658 +msgid "The added advantage of applying the 6G firewall to your site is that it has been tested and confirmed by the people at PerishablePress.com to be an optimal and least disruptive set of .htaccess security rules for general WP sites running on an Apache server or similar." +msgstr "" + +#: admin/wp-security-firewall-menu.php:659 +msgid "Therefore the 6G firewall rules should not have any impact on your site's general functionality but if you wish you can take a %s of your .htaccess file before proceeding." +msgstr "" + +#: admin/wp-security-firewall-menu.php:665 +msgid "6G blacklist/firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:677 +msgid "Enable 6G firewall protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:680 +msgid "Check this if you want to apply the 6G Blacklist firewall protection from perishablepress.com to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:684 +msgid "This setting will implement the 6G security firewall protection mechanisms on your site which include the following things:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:685 +#: admin/wp-security-firewall-menu.php:703 +msgid "1) Block forbidden characters commonly used in exploitative attacks." +msgstr "" + +#: admin/wp-security-firewall-menu.php:686 +#: admin/wp-security-firewall-menu.php:704 +msgid "2) Block malicious encoded URL characters such as the \".css(\" string." +msgstr "" + +#: admin/wp-security-firewall-menu.php:687 +#: admin/wp-security-firewall-menu.php:705 +msgid "3) Guard against the common patterns and specific exploits in the root portion of targeted URLs." +msgstr "" + +#: admin/wp-security-firewall-menu.php:688 +#: admin/wp-security-firewall-menu.php:706 +msgid "4) Stop attackers from manipulating query strings by disallowing illicit characters." +msgstr "" + +#: admin/wp-security-firewall-menu.php:689 +#: admin/wp-security-firewall-menu.php:707 +msgid "....and much more." +msgstr "" + +#: admin/wp-security-firewall-menu.php:695 +msgid "Enable legacy 5G firewall protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:698 +msgid "Check this if you want to apply the 5G Blacklist firewall protection from perishablepress.com to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:702 +msgid "This setting will implement the 5G security firewall protection mechanisms on your site which include the following things:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:713 +msgid "Save 5G/6G firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:721 +msgid "6G block request methods" +msgstr "" + +#: admin/wp-security-firewall-menu.php:725 +msgid "HTTP Request methods are used by browsers and clients to communicate with servers to get responses." +msgstr "" + +#: admin/wp-security-firewall-menu.php:726 +msgid "GET and POST are the most commonly used methods to request and submit data for specified resources of the server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:732 +msgid "Block %s method" +msgstr "" + +#: admin/wp-security-firewall-menu.php:735 +msgid "Check this to block the %s request method" +msgstr "" + +#: admin/wp-security-firewall-menu.php:740 +msgid "Some WooCommerce extensions use the PUT request method in addition to GET and POST." +msgstr "" + +#: admin/wp-security-firewall-menu.php:740 +msgid "This means WooCommerce users shouldn't block the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:741 +msgid "A few REST requests use the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:741 +msgid "If your site is communicated by the WP REST API, you should not block the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:749 +msgid "Save request methods settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:757 +msgid "6G other settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:761 +msgid "Block query strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:764 +msgid "Check this to block all query strings recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:768 +msgid "Block request strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:771 +msgid "Check this to block all request strings recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:775 +msgid "Block referrers" +msgstr "" + +#: admin/wp-security-firewall-menu.php:778 +msgid "Check this to block all referrers recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:782 +msgid "Block user-agents" +msgstr "" + +#: admin/wp-security-firewall-menu.php:785 +msgid "Check this to block all user-agents recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:789 +msgid "Save other settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:823 +msgid "The Internet bot settings were successfully saved" +msgstr "" + +#: admin/wp-security-firewall-menu.php:827 +msgid "Internet bot settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:833 +msgid "What is an Internet Bot" +msgstr "" + +#: admin/wp-security-firewall-menu.php:834 +msgid "%s?" +msgstr "" + +#: admin/wp-security-firewall-menu.php:836 +msgid "A bot is a piece of software which runs on the Internet and performs automatic tasks. For example when Google indexes your pages it uses automatic bots to achieve this task." +msgstr "" + +#: admin/wp-security-firewall-menu.php:837 +msgid "A lot of bots are legitimate and non-malicious but not all bots are good and often you will find some which try to impersonate legitimate bots such as \"Googlebot\" but in reality they have nohing to do with Google at all." +msgstr "" + +#: admin/wp-security-firewall-menu.php:838 +msgid "Although most of the bots out there are relatively harmless sometimes website owners want to have more control over which bots they allow into their site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:839 +msgid "This feature allows you to block bots which are impersonating as a Googlebot but actually aren't. (In other words they are fake Google bots)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:840 +msgid "Googlebots have a unique identity which cannot easily be forged and this feature will identify any fake Google bots and block them from reading your site's pages." +msgstr "" + +#: admin/wp-security-firewall-menu.php:846 +msgid "Attention: Sometimes non-malicious Internet organizations might have bots which impersonate as a \"Googlebot\"." +msgstr "" + +#: admin/wp-security-firewall-menu.php:847 +msgid "Just be aware that if you activate this feature the plugin will block all bots which use the \"Googlebot\" string in their User Agent information but are NOT officially from Google (irrespective whether they are malicious or not)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:848 +msgid "All other bots from other organizations such as \"Yahoo\", \"Bing\" etc will not be affected by this feature." +msgstr "" + +#: admin/wp-security-firewall-menu.php:854 +#: admin/wp-security-firewall-menu.php:864 +#: classes/grade-system/wp-security-feature-item-manager.php:93 +msgid "Block fake Googlebots" +msgstr "" + +#: admin/wp-security-firewall-menu.php:867 +msgid "Check this if you want to block all fake Googlebots." +msgstr "" + +#: admin/wp-security-firewall-menu.php:871 +msgid "This feature will check if the User Agent information of a bot contains the string \"Googlebot\"." +msgstr "" + +#: admin/wp-security-firewall-menu.php:872 +msgid "It will then perform a few tests to verify if the bot is legitimately from Google and if so it will allow the bot to proceed." +msgstr "" + +#: admin/wp-security-firewall-menu.php:873 +msgid "If the bot fails the checks then the plugin will mark it as being a fake Googlebot and it will block it" +msgstr "" + +#: admin/wp-security-firewall-menu.php:880 +msgid "Save internet bot settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:916 +#: admin/wp-security-firewall-menu.php:938 +#: classes/grade-system/wp-security-feature-item-manager.php:95 +msgid "Prevent image hotlinking" +msgstr "" + +#: admin/wp-security-firewall-menu.php:919 +msgid "A Hotlink is where someone displays an image on their site which is actually located on your site by using a direct link to the source of the image on your server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:920 +msgid "Due to the fact that the image being displayed on the other person's site is coming from your server, this can cause leaking of bandwidth and resources for you because your server has to present this image for the people viewing it on someone elses's site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:921 +msgid "This feature will prevent people from directly hotlinking images from your site's pages by writing some directives in your .htaccess file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:926 +msgid "Prevent hotlinking" +msgstr "" + +#: admin/wp-security-firewall-menu.php:941 +msgid "Check this if you want to prevent hotlinking to images on your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:961 +msgid "Nonce check failed for delete all 404 event logs operation!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:972 +msgid "404 Detection Feature - Delete all 404 event logs operation failed!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:976 +msgid "All 404 event logs were deleted from the DB successfully!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1000 +msgid "You entered a non numeric value for the lockout time length field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1006 +msgid "You entered an incorrect format for the \"Redirect URL\" field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1039 +msgid "404 detection configuration" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1042 +msgid "A 404 or Not Found error occurs when somebody tries to access a non-existent page on your website." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1043 +msgid "Typically, most 404 errors happen quite innocently when people have mis-typed a URL or used an old link to page which doesn't exist anymore." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1044 +msgid "However, in some cases you may find many repeated 404 errors which occur in a relatively short space of time and from the same IP address which are all attempting to access a variety of non-existent page URLs." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1045 +msgid "Such behaviour can mean that a hacker might be trying to find a particular page or URL for sinister reasons." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1046 +msgid "This feature allows you to monitor all 404 events which occur on your site, and it also gives you the option of blocking IP addresses for a configured length of time." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1047 +msgid "If you want to temporarily block or blacklist an IP address, simply click the \"Temp Block\" or \"Blacklist IP\" link for the applicable IP entry in the \"404 Event Logs\" table below." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1071 +msgid "404 detection options" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1083 +msgid "Enable 404 IP detection and lockout" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1086 +msgid "Check this if you want to enable the lockout of selected IP addresses." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1091 +msgid "When you enable this checkbox, all 404 events on your site will be logged in the table below. You can monitor these events and select some IP addresses listed in the table below and block them for a specified amount of time. All IP addresses you select to be blocked from the \"404 Event Logs\" table section will be unable to access your site during the time specified." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1099 +msgid "Enable 404 event logging" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1102 +msgid "Check this if you want to enable the logging of 404 events" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1107 +msgid "Time length of 404 lockout (minutes)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1109 +msgid "Set the length of time for which a blocked IP address will be prevented from visiting your site" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1114 +msgid "You can lock any IP address which is recorded in the \"404 Event Logs\" table section below." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1116 +msgid "To temporarily lock an IP address, hover over the ID column and click the \"Temp Block\" link for the applicable IP entry." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1123 +msgid "404 lockout redirect URL" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1125 +msgid "A blocked visitor will be automatically redirected to this URL." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1135 +msgid "This list displays the 404 event logs when somebody tries to access a non-existent page on your website." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1136 +msgid "404 event logs that are older than %1$d days are purged automatically." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1141 +msgid "404 event logs" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1163 +#: admin/wp-security-firewall-menu.php:1172 +#: admin/wp-security-user-login-menu.php:495 +#: admin/wp-security-user-login-menu.php:504 +#: admin/wp-security-user-login-menu.php:653 +#: admin/wp-security-user-login-menu.php:662 +msgid "Export to CSV" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1169 +#: admin/wp-security-user-login-menu.php:501 +#: admin/wp-security-user-login-menu.php:659 +msgid "Click this button if you wish to download this log in CSV format." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1176 +#: admin/wp-security-firewall-menu.php:1185 +msgid "Delete all 404 event logs" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1182 +msgid "Click this button if you wish to purge all 404 event logs from the DB." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1241 +msgid "Custom .htaccess rules settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1248 +msgid "This feature can be used to apply your own custom .htaccess rules and directives." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1249 +msgid "It is useful for when you want to tweak our existing firewall rules or when you want to add your own." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1250 +msgid "NOTE: This feature can only be used if your site is hosted in an apache or similar web server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1256 +msgid "Warning: Only use this feature if you know what you are doing." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1257 +msgid "Incorrect .htaccess rules or directives can break or prevent access to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1258 +msgid "It is your responsibility to ensure that you are entering the correct code!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1259 +msgid "If you break your site you will need to access your server via FTP or something similar and then edit your .htaccess file and delete the changes you made." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1265 +msgid "Custom .htaccess rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1269 +msgid "Enable custom .htaccess rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1272 +msgid "Check this if you want to enable custom rules entered in the text box below" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1276 +msgid "Place custom rules at the top" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1279 +msgid "Check this if you want to place your custom rules at the beginning of all the rules applied by this plugin" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1283 +msgid "Enter custom .htaccess rules:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1287 +msgid "Enter your custom .htaccess rules/directives." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1292 +msgid "Save custom rules" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:338 +#: admin/wp-security-firewall-setup-notice.php:407 +#: admin/wp-security-firewall-setup-notice.php:479 +#: admin/wp-security-firewall-setup-notice.php:595 +#: wp-security.php:43 +msgid "All In One WP Security and Firewall" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:340 +msgid "We were unable to create the file necessary to give you the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:341 +msgid "Your firewall will have reduced protection which means some of your firewall's functionality will be unavailable." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:342 +msgid "If you would like to manually set up the necessary file, please follow these steps:" +msgstr "" + +#. translators: %s Bootstrap file name. +#. translators: %s Firewall file name. +#: admin/wp-security-firewall-setup-notice.php:346 +#: admin/wp-security-firewall-setup-notice.php:453 +msgid "1. Create a file with the name %s in the same directory as your WordPress install is in, i.e.:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:350 +msgid "2. Paste in the following code:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:352 +#: admin/wp-security-firewall-setup-notice.php:462 +msgid "3. Save the file and press the 'Try again' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:372 +msgid "1. Open the following file:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:378 +msgid "2. Look for the auto_prepend_file directive." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:382 +msgid "2. Look for the following:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:388 +msgid "3. Change it to the following:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:392 +msgid "4. Save the file and press the 'Try again' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:392 +#: admin/wp-security-firewall-setup-notice.php:441 +msgid "You may have to wait up to 5 minutes before the settings take effect." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:410 +msgid "Your firewall has been installed with the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:411 +msgid "You may have to wait 5 minutes for the changes to take effect." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:434 +msgid "1. Open your php.ini file." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:437 +msgid "2. Set the auto_prepend_file directive like below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:441 +msgid "3. Restart the webserver and refresh the page" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:458 +msgid "2. Paste in the following directives:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:482 +msgid "We were unable to set up your firewall with the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:483 +msgid "Your firewall will have reduced functionality." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:487 +msgid "To give your site the highest level of protection, please follow these steps:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:500 +msgid "Note: if you're unable to perform any of the aforementioned steps, please ask your web hosting provider for further assistance." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:517 +msgid "Try again" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:539 +msgid "We have detected that your AIOS firewall is not fully installed, and therefore does not have the highest level of protection. " +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:540 +msgid "Your firewall will have reduced functionality until it has been upgraded. " +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:542 +msgid "Upgrade your protection now" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:598 +msgid "Our PHP-based firewall has been created to give you even greater protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:602 +msgid "If you already have our .htaccess-based firewall enabled, you will still need to set up the PHP-based firewall to benefit from its protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:605 +msgid "To set up the PHP-based firewall, press the 'Set up now' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:608 +msgid "Set up now" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:614 +#: templates/notices/custom-notice.php:10 +#: templates/notices/custom-notice.php:12 +#: templates/notices/horizontal-notice.php:50 +#: templates/notices/horizontal-notice.php:52 +#: templates/notices/htaccess-to-php-feature-notice.php:10 +#: templates/notices/htaccess-to-php-feature-notice.php:12 +msgid "Dismiss" +msgstr "" + +#: admin/wp-security-list-404.php:91 +msgid "Event type" +msgstr "" + +#: admin/wp-security-list-404.php:92 +#: admin/wp-security-list-logged-in-users.php:46 +#: admin/wp-security-list-registered-users.php:74 +msgid "IP address" +msgstr "" + +#: admin/wp-security-list-404.php:93 +msgid "Attempted URL" +msgstr "" + +#: admin/wp-security-list-404.php:94 +msgid "Referer" +msgstr "" + +#: admin/wp-security-list-404.php:96 +msgid "Lock status" +msgstr "" + +#: admin/wp-security-list-404.php:118 +msgid "Temp block IP" +msgstr "" + +#: admin/wp-security-list-404.php:119 +msgid "Blacklist IP" +msgstr "" + +#: admin/wp-security-list-404.php:120 +#: admin/wp-security-list-acct-activity.php:82 +#: admin/wp-security-list-locked-ip.php:37 +#: admin/wp-security-list-locked-ip.php:84 +#: admin/wp-security-list-login-fails.php:73 +#: admin/wp-security-list-registered-users.php:93 +msgid "Delete" +msgstr "" + +#: admin/wp-security-list-404.php:128 +#: admin/wp-security-list-404.php:136 +#: admin/wp-security-list-404.php:143 +#: admin/wp-security-list-acct-activity.php:92 +#: admin/wp-security-list-comment-spammer-ip.php:95 +#: admin/wp-security-list-locked-ip.php:97 +#: admin/wp-security-list-locked-ip.php:105 +#: admin/wp-security-list-login-fails.php:85 +#: admin/wp-security-list-permanent-blocked-ip.php:96 +#: admin/wp-security-list-registered-users.php:107 +#: admin/wp-security-list-registered-users.php:115 +#: admin/wp-security-list-registered-users.php:123 +msgid "Please select some records using the checkboxes" +msgstr "" + +#: admin/wp-security-list-404.php:278 +msgid "Nonce check failed for delete selected 404 event logs operation!" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:35 +msgid "Are you sure you want to delete this item?" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:46 +msgid "Login session still active" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:60 +#: admin/wp-security-list-locked-ip.php:60 +#: admin/wp-security-list-logged-in-users.php:44 +#: admin/wp-security-list-login-fails.php:54 +#: admin/wp-security-list-registered-users.php:69 +msgid "User ID" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:61 +#: admin/wp-security-list-locked-ip.php:61 +#: admin/wp-security-list-login-fails.php:55 +msgid "Username" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:62 +msgid "Login date" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:63 +msgid "Logout date" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:136 +msgid "Nonce check failed for delete selected account activity logs operation!" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:59 +msgid "Spammer IP" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:60 +msgid "Number of spam comments from this IP" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:61 +msgid "Status" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:81 +msgid "Block" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:130 +#: admin/wp-security-list-comment-spammer-ip.php:179 +msgid "Nonce check failed for delete selected blocked IP operation!" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:137 +msgid "The selected IP addresses are now permanently blocked!" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:193 +msgid "The selected IP addresses were saved in the blacklist configuration settings." +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:201 +msgid "The .htaccess file was successfully modified to include the selected IP addresses." +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:212 +msgid "NOTE: The .htaccess file was not modified because you have disabled the \"Enable IP or User Agent Blacklisting\" check box." +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:213 +msgid "To block these IP addresses you will need to enable the above flag in the %s menu" +msgstr "" + +#: admin/wp-security-list-debug.php:47 +msgid "Level" +msgstr "" + +#: admin/wp-security-list-debug.php:48 +msgid "Message" +msgstr "" + +#: admin/wp-security-list-debug.php:49 +msgid "Type" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:36 +#: admin/wp-security-list-locked-ip.php:83 +msgid "Unlock" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:59 +msgid "Locked IP/range" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:62 +#: admin/wp-security-list-permanent-blocked-ip.php:67 +msgid "Reason" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:63 +msgid "Date locked" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:64 +msgid "Release date" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:134 +msgid "The selected IP entries were unlocked successfully." +msgstr "선택한 IP 항목이 성공적으로 잠금 해제되었습니다." + +#: admin/wp-security-list-locked-ip.php:140 +msgid "Nonce check failed for unlock IP operation!" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:147 +msgid "The selected IP entry was unlocked successfully." +msgstr "" + +#: admin/wp-security-list-logged-in-users.php:45 +#: admin/wp-security-list-registered-users.php:70 +msgid "Login name" +msgstr "" + +#: admin/wp-security-list-logged-in-users.php:87 +msgid "Nonce check failed for force user logout operation!" +msgstr "" + +#: admin/wp-security-list-logged-in-users.php:96 +msgid "The selected user was logged out successfully!" +msgstr "" + +#: admin/wp-security-list-login-fails.php:53 +msgid "Login IP range" +msgstr "" + +#: admin/wp-security-list-login-fails.php:130 +msgid "Nonce check failed for delete failed login record operation!" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:66 +msgid "Blocked IP" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:87 +msgid "Unblock" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:122 +#: admin/wp-security-list-permanent-blocked-ip.php:139 +msgid "Successfully unblocked and deleted the selected record(s)." +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:126 +#: admin/wp-security-list-permanent-blocked-ip.php:143 +msgid "Failed to unblock and delete the selected record(s)." +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:133 +msgid "Nonce check failed for unblock IP operation!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:71 +msgid "Email" +msgstr "" + +#: admin/wp-security-list-registered-users.php:72 +msgid "Register date" +msgstr "" + +#: admin/wp-security-list-registered-users.php:73 +msgid "Account status" +msgstr "" + +#: admin/wp-security-list-registered-users.php:92 +msgid "Approve" +msgstr "" + +#: admin/wp-security-list-registered-users.php:94 +msgid "Block IP" +msgstr "" + +#: admin/wp-security-list-registered-users.php:159 +msgid "The selected accounts were approved successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:163 +msgid "The following accounts failed to update successfully: " +msgstr "" + +#: admin/wp-security-list-registered-users.php:171 +msgid "The selected account was approved successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:190 +msgid "Your account is now active" +msgstr "" + +#: admin/wp-security-list-registered-users.php:191 +msgid "Your account with username: " +msgstr "" + +#: admin/wp-security-list-registered-users.php:191 +msgid " is now active" +msgstr "" + +#: admin/wp-security-list-registered-users.php:222 +msgid "The selected accounts were deleted successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:230 +msgid "Nonce check failed for delete registered user account operation!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:238 +msgid "The selected account was deleted successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:264 +msgid "The selected IP addresses were successfully added to the permanent block list!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:265 +#: admin/wp-security-list-registered-users.php:282 +msgid "View Blocked IPs" +msgstr "" + +#: admin/wp-security-list-registered-users.php:274 +msgid "Nonce check failed for block IP operation of registered user!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:281 +msgid "The selected IP was successfully added to the permanent block list!" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:25 +msgid "Visitor lockout" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:85 +msgid "Site lockout feature settings saved!" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:92 +msgid "General visitor lockout" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:98 +msgid "This feature allows you to put your site into \"maintenance mode\" by locking down the front-end to all visitors except logged in users with super admin privileges." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:99 +msgid "Locking your site down to general visitors can be useful if you are investigating some issues on your site or perhaps you might be doing some maintenance and wish to keep out all traffic for security reasons." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:104 +msgid "Enable front-end lockout" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:107 +msgid "Check this if you want all visitors except those who are logged in as administrator to be locked out of the front-end of your site." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:111 +msgid "Enter a message:" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:123 +msgid "Enter a message you wish to display to visitors when your site is in maintenance mode." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:130 +msgid "Save site lockout settings" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:28 +msgid "Copy protection" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:29 +msgid "Frames" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:30 +msgid "Users enumeration" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:31 +msgid "WP REST API" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:89 +msgid "Copy Protection feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:94 +msgid "Disable the ability to copy text" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:100 +msgid "This feature allows you to disable the ability to select and copy text from your front end." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:101 +msgid "When admin user is logged in, the feature is automatically disabled for his session." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:106 +msgid "Enable copy protection" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:109 +msgid "Check this if you want to disable the \"Right click\", \"Text selection\" and \"Copy\" option on the front end of your site." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:116 +msgid "Save copy protection settings" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:140 +msgid "Frame Display Prevention feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:145 +msgid "Prevent your site from being displayed in a frame" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:151 +msgid "This feature allows you to prevent other sites from displaying any of your content via a frame or iframe." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:152 +msgid "When enabled, this feature will set the \"X-Frame-Options\" parameter to \"sameorigin\" in the HTTP header." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:157 +msgid "Enable iFrame protection" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:160 +msgid "Check this if you want to stop other sites from displaying your content in a frame or iframe." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:191 +msgid "Users Enumeration Prevention feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:196 +msgid "Prevent users enumeration" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:202 +msgid "This feature allows you to prevent external users/bots from fetching the user info with urls like \"/?author=1\"." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:203 +msgid "When enabled, this feature will print a \"forbidden\" error rather than the user information." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:208 +msgid "Disable users enumeration" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:211 +msgid "Check this if you want to stop users enumeration." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:242 +msgid "WP REST API Security feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:253 +msgid "This feature allows you to block WordPress REST API access for unauthorized requests." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:254 +msgid "When enabled this feature will only allow REST requests to be processed if the user is logged in." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:260 +msgid "Beware that if you are using other plugins which have registered REST endpoints (eg, Contact Form 7), then this feature will also block REST requests used by these plugins if the user is not logged in. It is recommended that you leave this feature disabled if you want uninterrupted functionality for such plugins." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:268 +msgid "Disallow unauthorized REST requests" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:271 +msgid "Check this if you want to stop REST API access for non-logged in requests." +msgstr "" + +#: admin/wp-security-settings-menu.php:25 +msgid "General settings" +msgstr "일반 설정" + +#: admin/wp-security-settings-menu.php:29 +#: admin/wp-security-settings-menu.php:33 +msgid "file" +msgstr "" + +#: admin/wp-security-settings-menu.php:37 +msgid "Delete plugin settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:41 +msgid "WP version info" +msgstr "WP 버전 정보" + +#: admin/wp-security-settings-menu.php:45 +msgid "Import/Export" +msgstr "가져오기/내보내기" + +#: admin/wp-security-settings-menu.php:52 +msgid "Advanced settings" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:128 +msgid "All the security features have been disabled successfully!" +msgstr "모든 보안 기능이 성공적으로 비활성화되었습니다!" + +#: admin/wp-security-settings-menu.php:132 +#: admin/wp-security-settings-menu.php:159 +msgid "Could not write to the .htaccess file. Please restore your .htaccess file manually using the restore functionality in the \".htaccess File\"." +msgstr "" + +#: admin/wp-security-settings-menu.php:137 +msgid "Could not write to the wp-config.php. Please restore your wp-config.php file manually using the restore functionality in the \"wp-config.php File\"." +msgstr "" + +#: admin/wp-security-settings-menu.php:155 +msgid "All firewall rules have been disabled successfully!" +msgstr "" + +#: admin/wp-security-settings-menu.php:177 +msgid "Deletion of aio_wp_security_configs option and .htaccess directives failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:179 +msgid "Reset of aio_wp_security_configs option failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:181 +msgid "Deletion of .htaccess directives failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:183 +msgid "All settings have been successfully reset." +msgstr "" + +#: admin/wp-security-settings-menu.php:203 +msgid "For information, updates and documentation, please visit the" +msgstr "For information, updates and documentation, please visit the" + +#: admin/wp-security-settings-menu.php:203 +msgid "Page" +msgstr "페이지" + +#: admin/wp-security-settings-menu.php:204 +msgid "Follow us" +msgstr "팔로우" + +#: admin/wp-security-settings-menu.php:204 +msgid "on Twitter, Google+ or via Email to stay up to date about the new security features of this plugin." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:208 +msgid "WP Security plugin" +msgstr "WP 보안 플러그인" + +#: admin/wp-security-settings-menu.php:212 +msgid "Thank you for using the AIOS security plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:216 +msgid "There are a lot of security features in this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:221 +msgid "To start, go through each security option and enable the \"basic\" options." +msgstr "" + +#: admin/wp-security-settings-menu.php:225 +msgid "The more features you enable, the more security points you will achieve." +msgstr "" + +#: admin/wp-security-settings-menu.php:228 +msgid "Before doing anything we advise taking a backup of your .htaccess file, database and wp-config.php." +msgstr "" + +#: admin/wp-security-settings-menu.php:231 +msgid "Backup your database" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:232 +#: admin/wp-security-settings-menu.php:433 +msgid "Backup .htaccess file" +msgstr "백업 .htaccess 파일" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:233 +#: admin/wp-security-settings-menu.php:534 +msgid "Backup wp-config.php file" +msgstr "백업 wp-config.php 파일" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:240 +msgid "Disable security features" +msgstr "보안 기능 비활성화" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:246 +msgid "If you think that some plugin functionality on your site is broken due to a security feature you enabled in this plugin, then use the following option to turn off all the security features of this plugin." +msgstr "이 플러그인에서 활성화 된 보안 기능으로 인해 사이트의 일부 플러그인 기능이 손상된 것으로 생각되면 다음 옵션을 사용하여이 플러그인의 모든 보안 기능을 끕니다." + +# @ default +#: admin/wp-security-settings-menu.php:250 +msgid "Disable all security features" +msgstr "모든 보안 기능 비활성화" + +# @ all-in-one-wp-security-and-firewall +# @ default +#: admin/wp-security-settings-menu.php:257 +#: admin/wp-security-settings-menu.php:267 +msgid "Disable all firewall rules" +msgstr "모든 방화벽 규칙 비활성화" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:263 +msgid "This feature will disable all firewall rules which are currently active in this plugin and it will also delete these rules from your .htacess file. Use it if you think one of the firewall rules is causing an issue on your site." +msgstr "이 기능은 현재이 플러그인에서 활성화된 모든 방화벽 규칙을 비활성화하고 .htacess 파일에서 이러한 규칙을 삭제합니다. 방화벽 규칙 중 하나가 사이트에서 문제를 일으킨다고 생각되면 사용하십시오." + +#: admin/wp-security-settings-menu.php:274 +#: admin/wp-security-settings-menu.php:287 +msgid "Reset settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:279 +msgid "This button click will delete all of your settings related to the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:280 +msgid "This button click will reset/empty all the database tables of the security plugin also." +msgstr "" + +#: admin/wp-security-settings-menu.php:281 +msgid "Use this plugin if you were locked out by the All In One WP Security & Firewall Plugin and/or you are having issues logging in when that plugin is activated." +msgstr "" + +#: admin/wp-security-settings-menu.php:282 +msgid "In addition to the settings it will also delete any directives which were added to the .htaccess file by the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:283 +msgid "%1$sNOTE: %2$sAfter deleting the settings you will need to re-configure the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:295 +msgid "Debug settings" +msgstr "디버그 설정" + +#: admin/wp-security-settings-menu.php:301 +msgid "This setting allows you to enable/disable debug for this plugin." +msgstr "이 설정을 사용하면 이 플러그인에 대한 디버그를 활성화/비활성화할 수 있습니다." + +#: admin/wp-security-settings-menu.php:307 +msgid "Enable debug" +msgstr "디버그 사용" + +#: admin/wp-security-settings-menu.php:310 +msgid "Check this if you want to enable debug. You should keep this option disabled after you have finished debugging the issue." +msgstr "디버그를 사용하도록 설정하려면 이 방법을 확인합니다. 문제 디버깅을 완료한 후에도 이 옵션을 사용하지 않도록 설정해야 합니다." + +#: admin/wp-security-settings-menu.php:314 +msgid "Save debug settings" +msgstr "디버그 설정 저장" + +#: admin/wp-security-settings-menu.php:350 +msgid "Your .htaccess file was successfully backed up! Using an FTP program go to the \"/wp-content/aiowps_backups\" directory to save a copy of the file to your computer." +msgstr ".htaccess 파일이 성공적으로 백업되었습니다! FTP 프로그램을 사용하여 \"/wp-content/aiowps_backups\" 디렉터리로 이동하여 파일의 복사본을 컴퓨터에 저장합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:356 +msgid "htaccess file rename failed during backup. Please check your root directory for the backup file using FTP." +msgstr "htaccess 파일 이름 바꾸기 백업 중에 실패했습니다. FTP를 사용하여 백업 파일에 대한 루트 디렉토리를 확인하십시오." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:362 +msgid "htaccess backup failed." +msgstr "htaccess 백업에 실패했습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:377 +msgid "Please choose a .htaccess to restore from." +msgstr "복원하려면 .htaccess를 선택하십시오." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:392 +msgid "htaccess file restore failed. Please attempt to restore the .htaccess manually using FTP." +msgstr "htaccess 파일 복원에 실패했습니다. FTP를 사용하여 수동으로 .htaccess를 복원하십시오." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:396 +msgid "Your .htaccess file has successfully been restored!" +msgstr ".htaccess 파일이 성공적으로 복원되었습니다!" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:402 +msgid "htaccess Restore operation failed! Please check the contents of the file you are trying to restore from." +msgstr "htaccess 복원 작업이 실패했습니다! 복원하려는 파일의 내용을 확인하십시오." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:408 +msgid ".htaccess file operations" +msgstr ".htaccess 파일 작업" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:411 +msgid "Your \".htaccess\" file is a key component of your website's security and it can be modified to implement various levels of protection mechanisms." +msgstr "\".htaccess\" 파일은 웹 사이트 보안의 핵심 구성 요소이며 다양한 수준의 보호 메커니즘을 구현하도록 수정할 수 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:412 +msgid "This feature allows you to backup and save your currently active .htaccess file should you need to re-use the the backed up file in the future." +msgstr "이 기능을 사용하면 나중에 백업된 파일을 다시 사용해야 하는 경우 현재 활성 .htaccess 파일을 백업하고 저장할 수 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:413 +msgid "You can also restore your site's .htaccess settings using a backed up .htaccess file." +msgstr "백업된 .htaccess 파일을 사용하여 사이트의 .htaccess 설정을 복원할 수도 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:428 +msgid "Save the current .htaccess file" +msgstr "현재 .htaccess 파일 저장" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:432 +msgid "Click the button below to backup and save the currently active .htaccess file." +msgstr "아래 버튼을 클릭하여 현재 활성 .htaccess 파일을 백업하고 저장합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:437 +msgid "Restore from a backed up .htaccess file" +msgstr "백업된 .htaccess 파일에서 복원" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:443 +msgid ".htaccess file to restore from" +msgstr "복원할 .htaccess 파일" + +#: admin/wp-security-settings-menu.php:445 +msgid "Select Your htaccess File" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:449 +msgid "After selecting your file, click the button below to restore your site using the backed up htaccess file (htaccess_backup.txt)." +msgstr "파일을 선택한 후 아래 버튼을 클릭하여 백업된 htaccess 파일(htaccess_backup.txt)을 사용하여 사이트를 복원합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:455 +msgid "Restore .htaccess file" +msgstr ".htaccess 파일 복원" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:477 +msgid "Please choose a wp-config.php file to restore from." +msgstr "복원하려면 wp-config.php 파일을 선택하십시오." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:493 +msgid "wp-config.php file restore failed. Please attempt to restore this file manually using FTP." +msgstr "wp-config.php 파일 복원에 실패했습니다. FTP를 사용하여 수동으로 이 파일을 복원해 보십시오." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:497 +msgid "Your wp-config.php file has successfully been restored!" +msgstr "wp-config.php 파일이 성공적으로 복원되었습니다!" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:503 +msgid "wp-config.php Restore operation failed! Please check the contents of the file you are trying to restore from." +msgstr "wp-config.php 복원 작업이 실패했습니다! 복원하려는 파일의 내용을 확인하십시오." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:509 +msgid "wp-config.php file operations" +msgstr "wp-config.php 파일 작업" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:512 +msgid "Your \"wp-config.php\" file is one of the most important in your WordPress installation. It is a primary configuration file and contains crucial things such as details of your database and other critical components." +msgstr "\"wp-config.php\" 파일은 워드 프레스 설치에서 가장 중요한 파일 중 하나입니다. 기본 구성 파일이며 데이터베이스 및 기타 중요한 구성 요소의 세부 정보와 같은 중요한 항목을 포함합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:513 +msgid "This feature allows you to backup and save your currently active wp-config.php file should you need to re-use the the backed up file in the future." +msgstr "이 기능을 사용하면 나중에 백업된 파일을 다시 사용해야 하는 경우 현재 활성 중인 wp-config.php 파일을 백업하고 저장할 수 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:514 +msgid "You can also restore your site's wp-config.php settings using a backed up wp-config.php file." +msgstr "백업된 wp-config.php 파일을 사용하여 사이트의 wp-config.php 설정을 복원할 수도 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:529 +msgid "Save the current wp-config.php file" +msgstr "현재 wp-config.php 파일 저장" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:533 +msgid "Click the button below to backup and download the contents of the currently active wp-config.php file." +msgstr "아래 버튼을 클릭하여 현재 활성 중인 wp-config.php 파일의 내용을 백업하고 다운로드합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:539 +msgid "Restore from a backed up wp-config file" +msgstr "백업된 wp-config 파일에서 복원" + +#: admin/wp-security-settings-menu.php:545 +msgid "wp-config file to restore from" +msgstr "" + +#: admin/wp-security-settings-menu.php:547 +msgid "Select Your wp-config File" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:551 +msgid "After selecting your file click the button below to restore your site using the backed up wp-config file (wp-config.php.backup.txt)." +msgstr "파일을 선택한 후 아래 버튼을 클릭하여 백업된 wp-config 파일(wp-config.php.backup.txt)을 사용하여 사이트를 복원합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:557 +msgid "Restore wp-config file" +msgstr "wp-config 파일 복원" + +#: admin/wp-security-settings-menu.php:591 +msgid "Manage delete plugin settings saved." +msgstr "" + +#: admin/wp-security-settings-menu.php:596 +msgid "Manage delete plugin tasks" +msgstr "" + +#: admin/wp-security-settings-menu.php:603 +msgid "Delete database tables" +msgstr "" + +#: admin/wp-security-settings-menu.php:606 +msgid "Check this if you want to remove database tables when the plugin is uninstalled." +msgstr "" + +#: admin/wp-security-settings-menu.php:610 +msgid "Delete settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:613 +msgid "Check this if you want to remove all plugin settings when uninstalling the plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:613 +msgid "It will also remove all custom htaccess rules that were added by this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:647 +msgid "WP generator meta tag and version info" +msgstr "" + +#: admin/wp-security-settings-menu.php:650 +msgid "WordPress generator automatically adds some meta information inside the \"head\" tags of every page on your site's front end. Below is an example of this:" +msgstr "" + +#: admin/wp-security-settings-menu.php:652 +msgid "The above meta information shows which version of WordPress your site is currently running and thus can help hackers or crawlers scan your site to see if you have an older version of WordPress or one with a known exploit." +msgstr "" + +#: admin/wp-security-settings-menu.php:653 +msgid "There are also other ways wordpress reveals version info such as during style and script loading. An example of this is:" +msgstr "" + +#: admin/wp-security-settings-menu.php:655 +msgid "This feature will allow you to remove the WP generator meta info and other version info from your site's pages." +msgstr "" + +#: admin/wp-security-settings-menu.php:661 +msgid "WP generator meta info" +msgstr "" + +#: admin/wp-security-settings-menu.php:673 +msgid "Remove WP generator meta info" +msgstr "" + +#: admin/wp-security-settings-menu.php:676 +msgid "Check this if you want to remove the version and meta info produced by WP from all pages" +msgstr "" + +#: admin/wp-security-settings-menu.php:704 +msgid "Please choose a file to import your settings from." +msgstr "" + +#: admin/wp-security-settings-menu.php:736 +msgid "Import AIOS settings from " +msgstr "" + +#: admin/wp-security-settings-menu.php:742 +#: admin/wp-security-settings-menu.php:786 +msgid "The deletion of the import file failed. Please delete this file manually via the media menu for security purposes." +msgstr "" + +#: admin/wp-security-settings-menu.php:744 +#: admin/wp-security-settings-menu.php:788 +msgid "The file you uploaded was also deleted for security purposes because it contains security settings details." +msgstr "" + +#: admin/wp-security-settings-menu.php:759 +msgid "Your AIOS settings were successfully imported via file input." +msgstr "" + +#: admin/wp-security-settings-menu.php:760 +msgid "The deletion of the import file failed. Please delete this file manually via the media menu for security purposes because it contains security settings details." +msgstr "" + +#: admin/wp-security-settings-menu.php:762 +msgid "Your AIOS settings were successfully imported. The file you uploaded was also deleted for security purposes because it contains security settings details." +msgstr "" + +#: admin/wp-security-settings-menu.php:765 +msgid "Your AIOS settings were successfully imported via text entry." +msgstr "" + +#: admin/wp-security-settings-menu.php:780 +msgid "The contents of your settings file appear invalid. Please check the contents of the file you are trying to import settings from." +msgstr "" + +#: admin/wp-security-settings-menu.php:797 +msgid "Export or import your AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:800 +msgid "This section allows you to export or import your All In One WP Security & Firewall settings." +msgstr "이 섹션에서는 모든 WP 보안 및 방화벽 설정을 내보내거나 가져올 수 있습니다." + +#: admin/wp-security-settings-menu.php:801 +msgid "This can be handy if you wanted to save time by applying the settings from one site to another site." +msgstr "이 기능은 한 사이트에서 다른 사이트로 설정을 적용하여 시간을 절약하려는 경우에 유용할 수 있습니다." + +#: admin/wp-security-settings-menu.php:802 +msgid "NOTE: Before importing, it is your responsibility to know what settings you are trying to import. Importing settings blindly can cause you to be locked out of your site." +msgstr "참고: 가져오기 전에 가져오려는 설정을 파악하는 것은 사용자의 책임입니다. 설정을 맹목적으로 가져오면 사이트에서 잠길 수 있습니다." + +#: admin/wp-security-settings-menu.php:803 +msgid "For Example: If a settings item relies on the domain URL then it may not work correctly when imported into a site with a different domain." +msgstr "예를 들어 설정 항목이 도메인 URL에 의존하는 경우 다른 도메인이 있는 사이트로 가져올 때 제대로 작동하지 않을 수 있습니다." + +#: admin/wp-security-settings-menu.php:809 +#: admin/wp-security-settings-menu.php:818 +msgid "Export AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:815 +msgid "To export your All In One WP Security & Firewall settings click the button below." +msgstr "모든 WP 보안 및 방화벽 설정을 내보내려면 아래 버튼을 클릭하십시오." + +#: admin/wp-security-settings-menu.php:822 +#: admin/wp-security-settings-menu.php:851 +msgid "Import AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:828 +msgid "Use this section to import your All In One WP Security & Firewall settings from a file. Alternatively, copy/paste the contents of your import file into the textarea below." +msgstr "" + +#: admin/wp-security-settings-menu.php:830 +msgid "Import file" +msgstr "파일 가져오기" + +#: admin/wp-security-settings-menu.php:833 +msgid "Select Your Import Settings File" +msgstr "" + +#: admin/wp-security-settings-menu.php:837 +msgid "After selecting your file, click the button below to apply the settings to your site." +msgstr "" + +#: admin/wp-security-settings-menu.php:844 +msgid "Copy/Paste import data" +msgstr "가져오기 데이터 복사/붙여넣기" + +#: admin/wp-security-settings-menu.php:893 +msgid "Default - if correct, then this is the best option" +msgstr "" + +#: admin/wp-security-settings-menu.php:894 +msgid "Only use if you're using Cloudflare." +msgstr "" + +#: admin/wp-security-settings-menu.php:902 +msgid "(current value: %s)" +msgstr "" + +#: admin/wp-security-settings-menu.php:905 +msgid "no value (i.e. empty) on your server" +msgstr "" + +#: admin/wp-security-spam-menu.php:28 +msgid "Comment spam" +msgstr "" + +#: admin/wp-security-spam-menu.php:29 +msgid "Comment spam IP monitoring" +msgstr "" + +#: admin/wp-security-spam-menu.php:30 +msgid "BuddyPress" +msgstr "" + +#: admin/wp-security-spam-menu.php:31 +msgid "bbPress" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-spam-menu.php:57 +msgid "Spam prevention" +msgstr "스팸 예방" + +#: admin/wp-security-spam-menu.php:99 +msgid "You entered a non numeric value for the \"move spam comments to trash after number of days\" field." +msgstr "" + +#: admin/wp-security-spam-menu.php:99 +#: admin/wp-security-spam-menu.php:297 +#: admin/wp-security-user-login-menu.php:118 +#: admin/wp-security-user-login-menu.php:124 +#: admin/wp-security-user-login-menu.php:130 +#: admin/wp-security-user-login-menu.php:136 +msgid "It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:129 +msgid "Comment spam settings" +msgstr "" + +#: admin/wp-security-spam-menu.php:134 +msgid "Add CAPTCHA to comments form" +msgstr "" + +#: admin/wp-security-spam-menu.php:138 +msgid "This feature will add a CAPTCHA field in the WordPress comments form." +msgstr "" + +#: admin/wp-security-spam-menu.php:139 +msgid "Adding a CAPTCHA field in the comment form is a simple way of greatly reducing spam comments from bots without using .htaccess rules." +msgstr "" + +#: admin/wp-security-spam-menu.php:148 +msgid "Enable CAPTCHA on comment forms" +msgstr "" + +#: admin/wp-security-spam-menu.php:151 +msgid "Check this if you want to insert a CAPTCHA field on the comment forms." +msgstr "" + +#: admin/wp-security-spam-menu.php:158 +msgid "Block spambot comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:162 +msgid "A large portion of WordPress blog comment spam is mainly produced by automated bots and not necessarily by humans." +msgstr "" + +#: admin/wp-security-spam-menu.php:163 +msgid "This feature will greatly minimize the useless and unnecessary traffic and load on your server resulting from spam comments by blocking all comment requests which do not originate from your domain." +msgstr "" + +#: admin/wp-security-spam-menu.php:164 +msgid "In other words, if the comment was not submitted by a human who physically submitted the comment on your site, the request will be blocked." +msgstr "" + +#: admin/wp-security-spam-menu.php:182 +msgid "Block spambots from posting comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:185 +msgid "Check this if you want to apply a firewall rule which will block comments originating from spambots." +msgstr "" + +#: admin/wp-security-spam-menu.php:189 +msgid "This feature will implement a firewall rule to block all comment attempts which do not originate from your domain." +msgstr "" + +#: admin/wp-security-spam-menu.php:190 +msgid "A legitimate comment is one which is submitted by a human who physically fills out the comment form and clicks the submit button. For such events, the HTTP_REFERRER is always set to your own domain." +msgstr "" + +#: admin/wp-security-spam-menu.php:191 +msgid "A comment submitted by a spambot is done by directly calling the comments.php file, which usually means that the HTTP_REFERRER value is not your domain and often times empty." +msgstr "" + +#: admin/wp-security-spam-menu.php:192 +msgid "This feature will check and block comment requests which are not referred by your domain thus greatly reducing your overall blog spam and PHP requests done by the server to process these comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:202 +msgid "Comment processing" +msgstr "" + +#: admin/wp-security-spam-menu.php:207 +msgid "Trash spam comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:216 +msgid "Move spam comments to trash after %s days." +msgstr "" + +#: admin/wp-security-spam-menu.php:224 +msgid "Enable this feature in order to move the spam comments to trash after given number of days." +msgstr "" + +#: admin/wp-security-spam-menu.php:262 +msgid "You entered a non numeric value for the minimum number of spam comments field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:265 +msgid "You must enter an integer greater than zero for minimum number of spam comments field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:292 +msgid "Nonce check failed for list spam comment IPs." +msgstr "" + +#: admin/wp-security-spam-menu.php:297 +msgid "You entered a non numeric value for the minimum spam comments per IP field." +msgstr "" + +#: admin/wp-security-spam-menu.php:308 +msgid "Displaying results for IP addresses which have posted a minimum of %s spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:323 +msgid "Auto block spammer IPs" +msgstr "" + +#: admin/wp-security-spam-menu.php:328 +msgid "This feature has detected that %s is not active. It is highly recommended that you activate the Akismet plugin to make the most of this feature." +msgstr "" + +#: admin/wp-security-spam-menu.php:337 +msgid "This feature allows you to automatically and permanently block IP addresses which have exceeded a certain number of comments labelled as spam." +msgstr "" + +#: admin/wp-security-spam-menu.php:338 +msgid "Comments are usually labelled as spam either by the Akismet plugin or manually by the WP administrator when they mark a comment as \"spam\" from the WordPress Comments menu." +msgstr "" + +#: admin/wp-security-spam-menu.php:352 +msgid "You currently have no IP addresses permanently blocked due to spam." +msgstr "" + +#: admin/wp-security-spam-menu.php:365 +msgid "Spammer IPs added to permanent block list today: " +msgstr "" + +#: admin/wp-security-spam-menu.php:366 +msgid "All time total: " +msgstr "" + +#: admin/wp-security-spam-menu.php:367 +msgid "View blocked IPs" +msgstr "" + +#: admin/wp-security-spam-menu.php:380 +msgid "Enable auto block of spam comment IPs" +msgstr "" + +#: admin/wp-security-spam-menu.php:383 +msgid "Check this box if you want this plugin to automatically block IP addresses which submit spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:387 +msgid "Minimum number of spam comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:389 +msgid "Specify the minimum number of spam comments for an IP address before it is permanently blocked." +msgstr "" + +#: admin/wp-security-spam-menu.php:393 +msgid "Example 1: Setting this value to \"1\" will block ALL IP addresses which were used to submit at least one spam comment." +msgstr "" + +#: admin/wp-security-spam-menu.php:394 +msgid "Example 2: Setting this value to \"5\" will block only those IP addresses which were used to submit 5 spam comments or more on your site." +msgstr "" + +#: admin/wp-security-spam-menu.php:412 +msgid "List spammer IP addresses" +msgstr "" + +#: admin/wp-security-spam-menu.php:416 +msgid "This section displays a list of the IP addresses of the people or bots who have left spam comments on your site." +msgstr "" + +#: admin/wp-security-spam-menu.php:417 +msgid "This information can be handy for identifying the most persistent IP addresses or ranges used by spammers." +msgstr "" + +#: admin/wp-security-spam-menu.php:418 +msgid "By inspecting the IP address data coming from spammers you will be in a better position to determine which addresses or address ranges you should block by adding them to the permanent block list." +msgstr "" + +#: admin/wp-security-spam-menu.php:419 +msgid "To add one or more of the IP addresses displayed in the table below to your blacklist, simply click the \"Block\" link for the individual row or select more than one address using the checkboxes and then choose the \"block\" option from the Bulk Actions dropdown list and click the \"Apply\" button." +msgstr "" + +#: admin/wp-security-spam-menu.php:427 +msgid "Minimum number of spam comments per IP" +msgstr "" + +#: admin/wp-security-spam-menu.php:429 +msgid "This field allows you to list only those IP addresses which have been used to post X or more spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:433 +msgid "Example 1: Setting this value to \"0\" or \"1\" will list ALL IP addresses which were used to submit spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:434 +msgid "Example 2: Setting this value to \"5\" will list only those IP addresses which were used to submit 5 spam comments or more on your site." +msgstr "" + +#: admin/wp-security-spam-menu.php:441 +msgid "Find IP addresses" +msgstr "" + +#: admin/wp-security-spam-menu.php:445 +msgid "Spammer IP address results" +msgstr "" + +#: admin/wp-security-spam-menu.php:451 +#: classes/wp-security-utility.php:253 +msgid "The plugin has detected that you are using a Multi-Site WordPress installation." +msgstr "" + +#: admin/wp-security-spam-menu.php:452 +msgid "Only the \"superadmin\" can block IP addresses from the main site." +msgstr "" + +#: admin/wp-security-spam-menu.php:453 +msgid "Take note of the IP addresses you want blocked and ask the superadmin to add these to the blacklist using the \"Blacklist Manager\" on the main site." +msgstr "" + +#: admin/wp-security-spam-menu.php:498 +msgid "BuddyPress spam settings" +msgstr "" + +#: admin/wp-security-spam-menu.php:503 +msgid "Add CAPTCHA to BuddyPress registration form" +msgstr "" + +#: admin/wp-security-spam-menu.php:507 +msgid "This feature will add a simple math CAPTCHA field in the BuddyPress registration form." +msgstr "" + +#: admin/wp-security-spam-menu.php:508 +msgid "Adding a CAPTCHA field in the registration form is a simple way of greatly reducing spam signups from bots without using .htaccess rules." +msgstr "" + +#: admin/wp-security-spam-menu.php:518 +msgid "Enable CAPTCHA on BuddyPress registration form" +msgstr "" + +#: admin/wp-security-spam-menu.php:521 +msgid "Check this if you want to insert a CAPTCHA field on the BuddyPress registration forms." +msgstr "" + +#: admin/wp-security-spam-menu.php:530 +msgid "BuddyPress is not active! In order to use this feature you will need to have BuddyPress installed and activated." +msgstr "" + +#: admin/wp-security-spam-menu.php:560 +msgid "bbPress spam settings" +msgstr "" + +#: admin/wp-security-spam-menu.php:565 +msgid "Add CAPTCHA to bbPress new topic form" +msgstr "" + +#: admin/wp-security-spam-menu.php:569 +msgid "This feature will add a simple math CAPTCHA field in the bbPress new topic form." +msgstr "" + +#: admin/wp-security-spam-menu.php:570 +msgid "Adding a CAPTCHA field in this form is a simple way of greatly reducing spam submitted from bots." +msgstr "" + +#: admin/wp-security-spam-menu.php:580 +msgid "Enable CAPTCHA on bbPress new topic form" +msgstr "" + +#: admin/wp-security-spam-menu.php:583 +msgid "Check this if you want to insert a CAPTCHA field on the bbPress new topic forms." +msgstr "" + +#: admin/wp-security-spam-menu.php:592 +msgid "bbPress is not active. In order to use this feature you will need to have bbPress installed and activated." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-tools-menu.php:34 +msgid "WHOIS lookup" +msgstr "후이스 조회" + +#: admin/wp-security-tools-menu.php:95 +#: admin/wp-security-tools-menu.php:136 +msgid "Querying %s: %s" +msgstr "" + +#: admin/wp-security-tools-menu.php:103 +#: admin/wp-security-tools-menu.php:112 +#: admin/wp-security-tools-menu.php:151 +msgid "Redirected to %s" +msgstr "" + +#: admin/wp-security-tools-menu.php:173 +msgid "The WHOIS lookup feature gives you a way to look up who owns an IP address or domain name." +msgstr "" + +#: admin/wp-security-tools-menu.php:173 +msgid "You can use this to investigate users engaging in malicious activity on your site." +msgstr "" + +#: admin/wp-security-tools-menu.php:176 +msgid "WHOIS lookup on IP or domain" +msgstr "" + +#: admin/wp-security-tools-menu.php:183 +msgid "IP address or domain name:" +msgstr "" + +#: admin/wp-security-tools-menu.php:190 +msgid "Look up IP or domain" +msgstr "" + +#: admin/wp-security-tools-menu.php:219 +msgid "Please enter a valid IP address or domain name to look up." +msgstr "" + +#: admin/wp-security-tools-menu.php:220 +#: admin/wp-security-tools-menu.php:226 +msgid "Nothing to show." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:32 +msgid "WP username" +msgstr "WP 사용자 이름" + +#: admin/wp-security-user-accounts-menu.php:33 +msgid "Display name" +msgstr "표시 이름" + +#: admin/wp-security-user-accounts-menu.php:34 +msgid "Password" +msgstr "비밀번호" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:60 +msgid "User accounts" +msgstr "사용자 계정" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:82 +msgid "Admin user security" +msgstr "관리자 사용자 보안" + +#: admin/wp-security-user-accounts-menu.php:85 +msgid "By default, WordPress sets the administrator username to \"admin\" at installation time." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:86 +msgid "A lot of hackers try to take advantage of this information by attempting \"Brute force login attacks\" where they repeatedly try to guess the password by using \"admin\" for username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:87 +msgid "From a security perspective, changing the default \"admin\" user name is one of the first and smartest things you should do on your site." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:88 +msgid "This feature will allow you to change your default \"admin\" user name to a more secure name of your choosing." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:95 +msgid "List of administrator accounts" +msgstr "관리자 계정 목록" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:104 +#: classes/grade-system/wp-security-feature-item-manager.php:43 +msgid "Change admin username" +msgstr "관리자 사용자 이름 변경" + +#: admin/wp-security-user-accounts-menu.php:112 +msgid "Your site currently has an account which uses the default \"admin\" username. It is highly recommended that you change this name to something else. Use the following field to change the admin username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:118 +msgid "New admin username" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:120 +msgid "Choose a new username for admin." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:124 +msgid "Change username" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:126 +msgid "NOTE: If you are currently logged in as \"admin\" you will be automatically logged out after changing your username and will be required to log back in." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:133 +msgid "No action required! " +msgstr "필요한 조치가 없습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:135 +msgid "Your site does not have any account which uses the default \"admin\" username. " +msgstr "사이트에기본 \"관리자\" 사용자 이름을 사용하는 계정이 없습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:136 +msgid "This is good security practice." +msgstr "이것은 좋은 보안 관행입니다." + +#: admin/wp-security-user-accounts-menu.php:148 +msgid "Display name security" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:151 +msgid "When you submit a post or answer a comment, WordPress will usually display your \"nickname\"." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:152 +msgid "By default the nickname is set to the login (or user) name of your account." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:153 +msgid "From a security perspective, leaving your nickname the same as your user name is bad practice because it gives a hacker at least half of your account's login credentials." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:154 +msgid "Therefore to further tighten your site's security you are advised to change your nickname and Display name to be different from your Username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:160 +msgid "Modify accounts with identical login name and display name" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:169 +msgid "Your site currently has the following accounts which have an identical login name and display name." +msgstr "사이트에는 현재 로그인 이름과 표시 이름이 동일한 다음 계정이 있습니다." + +#: admin/wp-security-user-accounts-menu.php:170 +msgid "Follow the link to edit the user profile of that particular user account, change Nickname, choose a different Display name compared to Username, and press the \"Update User\" button.)" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:185 +msgid "No action required." +msgstr "필요한 조치가 없습니다." + +#: admin/wp-security-user-accounts-menu.php:186 +msgid "Your site does not have a user account where the display name is identical to the username." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:197 +msgid "Password tool" +msgstr "암호 도구" + +#: admin/wp-security-user-accounts-menu.php:200 +msgid "Poor password selection is one of the most common weak points of many sites and is usually the first thing a hacker will try to exploit when attempting to break into your site." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:201 +msgid "Many people fall into the trap of using a simple word or series of numbers as their password. Such a predictable and simple password would take a competent hacker merely minutes to guess your password by using a simple script which cycles through the easy and most common combinations." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:202 +msgid "The longer and more complex your password is the harder it is for hackers to \"crack\" because more complex passwords require much greater computing power and time." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:203 +msgid "This section contains a useful password strength tool which you can use to check whether your password is sufficiently strong enough." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:208 +msgid "Password strength tool" +msgstr "암호 강도 도구" + +#: admin/wp-security-user-accounts-menu.php:210 +msgid "This password tool uses an algorithm which calculates how long it would take for your password to be cracked using the computing power of an off-the-shelf current model desktop PC with high end processor, graphics card and appropriate password cracking software." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:213 +msgid "Start typing a password." +msgstr "암호 입력을 시작합니다." + +#: admin/wp-security-user-accounts-menu.php:216 +msgid "It would take a desktop PC approximately" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:217 +msgid "1 sec" +msgstr "1 초" + +#: admin/wp-security-user-accounts-menu.php:217 +msgid "to crack your password!" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:222 +msgid "Password Strength" +msgstr "비밀번호 보안수준" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:245 +msgid "Username " +msgstr "이용자명" + +#: admin/wp-security-user-accounts-menu.php:245 +msgid " already exists. Please enter another value. " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:262 +msgid "The database update operation of the user account failed!" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:291 +msgid "You entered an invalid username. Please enter another value. " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:295 +msgid "Please enter a value for your username. " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:302 +msgid "Username successfully changed." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:322 +msgid "Account login name" +msgstr "계정 로그인 이름" + +#: admin/wp-security-user-accounts-menu.php:331 +msgid "Edit user" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:54 +#: admin/wp-security-user-login-menu.php:474 +msgid "Failed login records" +msgstr "실패한 로그인 레코드" + +#: admin/wp-security-user-login-menu.php:55 +#: classes/grade-system/wp-security-feature-item-manager.php:51 +msgid "Force logout" +msgstr "강제 로그아웃" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:56 +#: admin/wp-security-user-login-menu.php:632 +msgid "Account activity logs" +msgstr "계정 활동 로그" + +#: admin/wp-security-user-login-menu.php:58 +#: admin/wp-security-user-login-menu.php:769 +msgid "Additional settings" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:81 +msgid "User login" +msgstr "사용자 로그인" + +#: admin/wp-security-user-login-menu.php:118 +msgid "You entered a non-numeric value for the max login attempts field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:124 +msgid "You entered a non numeric value for the login retry time period field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:130 +msgid "You entered a non numeric value for the lockout time length field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:136 +msgid "You entered a non numeric value for the maximum lockout time length field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:141 +msgid "You entered an invalid minimum lockout time length, it must be less than the maximum lockout time length value." +msgstr "" + +#: admin/wp-security-user-login-menu.php:141 +msgid "Both have been set to the default values." +msgstr "" + +#: admin/wp-security-user-login-menu.php:160 +msgid "Please fill in one or more email addresses to notify." +msgstr "" + +#: admin/wp-security-user-login-menu.php:162 +msgid "You have entered one or more invalid email addresses." +msgstr "" + +#: admin/wp-security-user-login-menu.php:165 +msgid "It has been set to your WordPress admin email as default." +msgstr "" + +#: admin/wp-security-user-login-menu.php:250 +msgid "Login lockout configuration" +msgstr "" + +#: admin/wp-security-user-login-menu.php:254 +msgid "One of the ways hackers try to compromise sites is via a " +msgstr "" + +#: admin/wp-security-user-login-menu.php:254 +msgid "Brute force login attack" +msgstr "" + +#: admin/wp-security-user-login-menu.php:254 +msgid "This is where attackers use repeated login attempts until they guess the password." +msgstr "" + +#: admin/wp-security-user-login-menu.php:255 +msgid "Apart from choosing strong passwords, monitoring and blocking IP addresses which are involved in repeated login failures in a short period of time is a very effective way to stop these types of attacks." +msgstr "" + +#: admin/wp-security-user-login-menu.php:256 +msgid "You may also want to checkout our %s feature for another secure way to protect against these types of attacks." +msgstr "" + +#: admin/wp-security-user-login-menu.php:261 +msgid "Login lockout options" +msgstr "" + +#: admin/wp-security-user-login-menu.php:272 +msgid "Enable login lockout feature" +msgstr "" + +#: admin/wp-security-user-login-menu.php:275 +msgid "Check this if you want to enable the login lockout feature and apply the settings below" +msgstr "" + +#: admin/wp-security-user-login-menu.php:279 +msgid "Allow unlock requests" +msgstr "잠금 해제 요청 허용" + +#: admin/wp-security-user-login-menu.php:282 +msgid "Check this if you want to allow users to generate an automated unlock request link which will unlock their account" +msgstr "사용자가 계정잠금을 해제하는 자동 잠금 해제 요청 링크를 생성하도록 허용하려면 이 방법을 확인합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:286 +msgid "Max login attempts" +msgstr "최대 로그인 시도" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:288 +msgid "Set the value for the maximum login retries before IP address is locked out" +msgstr "IP 주소가 잠기기 전에 최대 로그인 리트리에 대한 값을 설정합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:292 +msgid "Login retry time period (min)" +msgstr "로그인 재시도 기간(최소)" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:294 +msgid "If the maximum number of failed login attempts for a particular IP address occur within this time period the plugin will lock out that address" +msgstr "특정 IP 주소에 대한 로그인 시도가 최대 실패한 경우 이 기간 내에 플러그인이 해당 주소를 잠그게 됩니다." + +#: admin/wp-security-user-login-menu.php:299 +msgid "Minimum lockout time length" +msgstr "" + +#: admin/wp-security-user-login-menu.php:305 +msgid "Set the minimum time period in minutes of lockout." +msgstr "" + +#: admin/wp-security-user-login-menu.php:306 +msgid "This failed login lockout time will be tripled on each failed login." +msgstr "" + +#: admin/wp-security-user-login-menu.php:313 +msgid "Maximum lockout time length" +msgstr "" + +#: admin/wp-security-user-login-menu.php:318 +msgid "Set the maximum time period in minutes of lockout." +msgstr "" + +#: admin/wp-security-user-login-menu.php:319 +msgid "No IP address will be blocked for more than this time period after making a failed login attempt." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:324 +msgid "Display generic error message" +msgstr "일반 오류 메시지 표시" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:327 +msgid "Check this if you want to show a generic error message when a login attempt fails" +msgstr "로그인 시도가 실패할 때 일반 오류 메시지를 표시하려는 경우 이 방법을 확인합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:331 +msgid "Instantly lockout invalid usernames" +msgstr "즉시 잘못된 사용자 이름을 잠그기" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:334 +msgid "Check this if you want to instantly lockout login attempts with usernames which do not exist on your system" +msgstr "시스템에 존재하지 않는 사용자 이름으로 로그인 시도를 즉시 잠그려면 이 방법을 확인하십시오." + +#: admin/wp-security-user-login-menu.php:339 +msgid "Instantly lockout specific usernames" +msgstr "특정 사용자 이름을 즉시 잠그기" + +#: admin/wp-security-user-login-menu.php:349 +msgid "Insert one username per line. Existing usernames are not blocked even if present in the list." +msgstr "줄당 하나의 사용자 이름을 삽입합니다. 목록에 있는 경우에도 기존 사용자 이름은 차단되지 않습니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:354 +msgid "Notify by email" +msgstr "이메일로 알림" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:358 +msgid "Check this if you want to receive an email when someone has been locked out due to maximum failed login attempts" +msgstr "로그인 시도가 최대 실패로 인해 다른 사람이 잠긴 경우 이메일을 수신하려는 경우 이 방법을 확인하십시오." + +#: admin/wp-security-user-login-menu.php:361 +msgid "Fill in one email address per line." +msgstr "" + +#: admin/wp-security-user-login-menu.php:365 +msgid "Each email address must be on a new line." +msgstr "" + +#: admin/wp-security-user-login-menu.php:366 +msgid "If a valid email address has not been filled in, it will not be saved." +msgstr "" + +#: admin/wp-security-user-login-menu.php:367 +msgid "The valid email address format is userid@example.com" +msgstr "" + +#: admin/wp-security-user-login-menu.php:368 +msgid "Example: %s" +msgstr "" + +#: admin/wp-security-user-login-menu.php:375 +msgid "Enable PHP backtrace in email" +msgstr "" + +#: admin/wp-security-user-login-menu.php:379 +msgid "Check this if you want to include the PHP backtrace in notification emails." +msgstr "" + +#: admin/wp-security-user-login-menu.php:379 +msgid "This is internal coding information which makes it easier to investigate where an issued occurred." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:389 +msgid "Currently locked out IP address ranges" +msgstr "현재 잠긴 IP 주소 범위" + +#: admin/wp-security-user-login-menu.php:394 +msgid "To see a list of all locked IP addresses and ranges go to the %s tab in the dashboard menu." +msgstr "잠긴 모든 IP 주소 와 범위 목록을 보려면 대시보드 메뉴의 %s 탭으로 이동합니다." + +#: admin/wp-security-user-login-menu.php:399 +msgid "Login lockout IP whitelist settings" +msgstr "" + +#: admin/wp-security-user-login-menu.php:405 +msgid "Enable login lockout IP whitelist" +msgstr "" + +#: admin/wp-security-user-login-menu.php:416 +msgid "The addresses specified here will never be blocked by the login lockout feature." +msgstr "" + +#: admin/wp-security-user-login-menu.php:450 +msgid "User login feature - Delete all failed login records operation failed." +msgstr "" + +#: admin/wp-security-user-login-menu.php:452 +msgid "All records from the failed logins table were deleted successfully." +msgstr "" + +#: admin/wp-security-user-login-menu.php:467 +msgid "This tab displays the failed login attempts for your site." +msgstr "" + +#: admin/wp-security-user-login-menu.php:468 +msgid "The information below can be handy if you need to do security investigations because it will show you the IP range, username and ID (if applicable) and the time/date of the failed login attempt." +msgstr "" + +#: admin/wp-security-user-login-menu.php:469 +msgid "Failed login records that are older than %1$d days are purged automatically." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:508 +#: admin/wp-security-user-login-menu.php:517 +msgid "Delete all failed login records" +msgstr "실패한 로그인 레코드 모두 삭제" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:514 +msgid "Click this button if you wish to delete all failed login records in one go." +msgstr "한 번에 모든 실패한 로그인 레코드를 삭제하려면 이 단추를 클릭합니다." + +#: admin/wp-security-user-login-menu.php:544 +msgid "You entered a non numeric value for the logout time period field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-user-login-menu.php:569 +msgid "Setting an expiry period for your WP administration session is a simple way to protect against unauthorized access to your site from your computer." +msgstr "" + +#: admin/wp-security-user-login-menu.php:570 +msgid "This feature allows you to specify a time period in minutes after which the admin session will expire and the user will be forced to log back in." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:575 +msgid "Force user logout options" +msgstr "사용자 로그아웃 옵션 강제" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:587 +msgid "Enable force WP user logout" +msgstr "강제 WP 사용자 로그아웃 사용" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:590 +msgid "Check this if you want to force a wp user to be logged out after a configured amount of time" +msgstr "구성된 시간 이후에 WP 사용자를 강제로 로그아웃하도록 하려면 이 방법을 확인합니다." + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:594 +msgid "Logout the WP user after XX minutes" +msgstr "XX 분 후 WP 사용자 로그아웃" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:596 +msgid "(Minutes) The user will be forced to log back in after this time period has elapased." +msgstr "(분) 이 기간이 중복된 후에는 사용자가 다시 로그인해야 합니다." + +#: admin/wp-security-user-login-menu.php:625 +msgid "This tab displays the activity for accounts registered with your site that have logged in using the WordPress login form." +msgstr "" + +#: admin/wp-security-user-login-menu.php:626 +msgid "The information below can be handy if you need to do security investigations because it will show you the last 100 recent login events by username, IP address and time/date." +msgstr "" + +#: admin/wp-security-user-login-menu.php:627 +msgid "Account activity logs that are older than %1$d days are purged automatically." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:697 +msgid "Refresh logged in user data" +msgstr "사용자 데이터에 로그인한 새로 고침" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:701 +msgid "Refresh data" +msgstr "데이터 새로 고침" + +#: admin/wp-security-user-login-menu.php:706 +msgid "This tab displays all users who are currently logged into your site." +msgstr "" + +#: admin/wp-security-user-login-menu.php:707 +msgid "If you suspect there is a user or users who are logged in which should not be, you can block them by inspecting the IP addresses from the data below and adding them to your blacklist." +msgstr "" + +#: admin/wp-security-user-login-menu.php:708 +msgid "You can also instantly log them out by clicking on the \"Force logout\" link when you hover over the row in the user id column." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:713 +msgid "Currently logged in users" +msgstr "현재 로그인한 사용자" + +#: admin/wp-security-user-login-menu.php:761 +msgid "WordPress 5.6 introduced a new feature called \"Application passwords\"." +msgstr "" + +#: admin/wp-security-user-login-menu.php:762 +msgid "This allows you to create a token from the WordPress dashboard which then can be used in the authorization header." +msgstr "" + +#: admin/wp-security-user-login-menu.php:763 +msgid "This feature allows you to disable application passwords as they can leave your site vulnerable to social engineering and phishing scams." +msgstr "" + +#: admin/wp-security-user-login-menu.php:780 +#: classes/grade-system/wp-security-feature-item-manager.php:53 +msgid "Disable application password" +msgstr "" + +#: admin/wp-security-user-login-menu.php:783 +msgid "Check this if you want to disable the application password." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:27 +msgid "Manual approval" +msgstr "수동 승인" + +#: admin/wp-security-user-registration-menu.php:28 +#: classes/grade-system/wp-security-feature-item-manager.php:59 +msgid "Registration CAPTCHA" +msgstr "등록 캡차" + +#: admin/wp-security-user-registration-menu.php:29 +msgid "Registration honeypot" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:55 +msgid "User registration" +msgstr "회원가입" + +#: admin/wp-security-user-registration-menu.php:115 +msgid "User registration settings" +msgstr "사용자 등록 설정" + +#: admin/wp-security-user-registration-menu.php:119 +msgid "Manually approve new registrations" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:123 +msgid "If your site allows people to create their own accounts via the WordPress registration form, then you can minimize spam or bogus registrations by manually approving each registration." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:124 +msgid "This feature will automatically set a newly registered account to \"pending\" until the administrator activates it. Therefore undesirable registrants will be unable to log in without your express approval." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:125 +msgid "You can view all accounts which have been newly registered via the handy table below and you can also perform bulk activation/deactivation/deletion tasks on each account." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:142 +msgid "Enable manual approval of new registrations" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:145 +msgid "Check this if you want to automatically disable all newly registered accounts so that you can approve them manually." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:154 +msgid "Approve registered users" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:206 +msgid "This feature allows you to add a CAPTCHA form on the WordPress registration page." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:207 +msgid "Users who attempt to register will also need to enter the answer to a simple mathematical question - if they enter the wrong answer, the plugin will not allow them to register." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:208 +msgid "Therefore, adding a CAPTCHA form on the registration page is another effective yet simple spam registration prevention technique." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:212 +msgid "Registration page CAPTCHA settings" +msgstr "등록 페이지 캡차 설정" + +#: admin/wp-security-user-registration-menu.php:219 +msgid "The core default behaviour for WordPress Multi Site regarding user registration is that all users are registered via the main site." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:220 +msgid "Therefore, if you would like to add a CAPTCHA form to the registration page for a Multi Site, please go to \"Registration CAPTCHA\" settings on the main site." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:235 +msgid "Enable CAPTCHA on registration page" +msgstr "등록시 보안 문자 사용" + +#: admin/wp-security-user-registration-menu.php:238 +msgid "Check this if you want to insert a CAPTCHA form on the WordPress user registration page (if you allow user registration)." +msgstr "워드 프레스 사용자 등록 페이지에 captcha 양식을 삽입하려는 경우 (사용자 등록을 허용하는 경우)을 확인하십시오." + +#: admin/wp-security-user-registration-menu.php:276 +msgid "This feature allows you to add a special hidden \"honeypot\" field on the WordPress registration page. This will only be visible to robots and not humans." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:277 +msgid "Since robots usually fill in every input field from a registration form, they will also submit a value for the special hidden honeypot field." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:279 +msgid "Therefore, if the plugin detects that this field has a value when the registration form is submitted, then the robot which is attempting to register on your site will be redirected to its localhost address - http://127.0.0.1." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:285 +msgid "Registration form honeypot settings" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:296 +msgid "Enable honeypot on registration page" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:299 +msgid "Check this if you want to enable the honeypot feature for the registration page" +msgstr "" + +#: classes/aios-ajax.php:89 +msgid "Invalid IP retrieve method." +msgstr "" + +#: classes/aios-ajax.php:131 +#: wp-security-core.php:258 +msgid "The security check failed; try refreshing the page." +msgstr "" + +#: classes/aios-ajax.php:152 +#: wp-security-core.php:268 +msgid "You are not allowed to run this command." +msgstr "" + +#: classes/aios-ajax.php:173 +#: wp-security-core.php:282 +msgid "Options can only be saved by network admin" +msgstr "" + +#: classes/aios-ajax.php:202 +msgid "The command \"%s\" was not found" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:39 +msgid "Remove WP generator meta tag" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:45 +msgid "Change display name" +msgstr "표시 이름 변경" + +#: classes/grade-system/wp-security-feature-item-manager.php:57 +msgid "Registration approval" +msgstr "등록 승인" + +#: classes/grade-system/wp-security-feature-item-manager.php:61 +msgid "Enable registration honeypot" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:73 +msgid "WordPress files access" +msgstr "워드 프레스 파일 액세스" + +#: classes/grade-system/wp-security-feature-item-manager.php:77 +msgid "IP and user agent blacklisting" +msgstr "IP 또는 사용자 에이전트 블랙리스트 사용" + +#: classes/grade-system/wp-security-feature-item-manager.php:81 +msgid "Enable basic firewall" +msgstr "기본 방화벽 사용" + +#: classes/grade-system/wp-security-feature-item-manager.php:82 +msgid "Enable pingback vulnerability protection" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:83 +msgid "Block access to debug log file" +msgstr "디버그 로그 파일에 대한 액세스 차단" + +#: classes/grade-system/wp-security-feature-item-manager.php:87 +msgid "Forbid proxy comments" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:88 +msgid "Deny bad queries" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:91 +msgid "5G/6G blacklist" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:97 +msgid "Enable IP blocking for 404 detection" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:101 +msgid "Enable rename login page" +msgstr "이름 바꾸기 페이지 기능 사용" + +#: classes/grade-system/wp-security-feature-item-manager.php:106 +msgid "Lost password CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:107 +msgid "Custom login CAPTCHA" +msgstr "사용자 정의 로그인 캡타" + +#: classes/grade-system/wp-security-feature-item-manager.php:108 +msgid "Woo login CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:109 +msgid "Woo lost password CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:110 +msgid "Woo register CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:112 +msgid "Login IP whitelisting" +msgstr "로그인 IP 화이트리스팅" + +#: classes/grade-system/wp-security-feature-item-manager.php:114 +msgid "Enable login honeypot" +msgstr "로그인 허니팟 사용" + +#: classes/grade-system/wp-security-feature-item-manager.php:118 +msgid "Comment CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:119 +msgid "Block spambots" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:121 +msgid "BuddyPress registration CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:123 +msgid "bbPress new topic CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item.php:29 +msgid "Basic" +msgstr "기본" + +#: classes/grade-system/wp-security-feature-item.php:31 +msgid "Intermediate" +msgstr "중급" + +#: classes/grade-system/wp-security-feature-item.php:33 +msgid "Advanced" +msgstr "고급" + +#: classes/wp-security-captcha.php:47 +#: classes/wp-security-general-init-tasks.php:407 +msgid "Please enter an answer in digits:" +msgstr "숫자로 답변을 입력하십시오." + +#: classes/wp-security-captcha.php:127 +msgid "one" +msgstr "1" + +#: classes/wp-security-captcha.php:128 +msgid "two" +msgstr "2" + +#: classes/wp-security-captcha.php:129 +msgid "three" +msgstr "3" + +#: classes/wp-security-captcha.php:130 +msgid "four" +msgstr "4" + +#: classes/wp-security-captcha.php:131 +msgid "five" +msgstr "5" + +#: classes/wp-security-captcha.php:132 +msgid "six" +msgstr "6" + +#: classes/wp-security-captcha.php:133 +msgid "seven" +msgstr "7" + +#: classes/wp-security-captcha.php:134 +msgid "eight" +msgstr "8" + +#: classes/wp-security-captcha.php:135 +msgid "nine" +msgstr "9" + +#: classes/wp-security-captcha.php:136 +msgid "ten" +msgstr "10" + +#: classes/wp-security-captcha.php:137 +msgid "eleven" +msgstr "11" + +#: classes/wp-security-captcha.php:138 +msgid "twelve" +msgstr "12" + +#: classes/wp-security-captcha.php:139 +msgid "thirteen" +msgstr "13" + +#: classes/wp-security-captcha.php:140 +msgid "fourteen" +msgstr "14" + +#: classes/wp-security-captcha.php:141 +msgid "fifteen" +msgstr "15" + +#: classes/wp-security-captcha.php:142 +msgid "sixteen" +msgstr "16" + +#: classes/wp-security-captcha.php:143 +msgid "seventeen" +msgstr "17" + +#: classes/wp-security-captcha.php:144 +msgid "eighteen" +msgstr "18" + +#: classes/wp-security-captcha.php:145 +msgid "nineteen" +msgstr "19" + +#: classes/wp-security-captcha.php:146 +msgid "twenty" +msgstr "20" + +#: classes/wp-security-cronjob-handler.php:34 +msgid "Every 15 minutes" +msgstr "" + +#: classes/wp-security-debug-logger.php:46 +msgid "Unable to get the reason why" +msgstr "" + +#: classes/wp-security-debug-logger.php:47 +msgid "Unable to clear the logs" +msgstr "" + +#: classes/wp-security-file-scan.php:85 +msgid "All In One WP Security - File change detected!" +msgstr "" + +#: classes/wp-security-file-scan.php:87 +msgid "A file change was detected on your system for site URL" +msgstr "" + +#: classes/wp-security-file-scan.php:87 +msgid ". Scan was generated on" +msgstr "" + +#: classes/wp-security-file-scan.php:88 +msgid "A summary of the scan results is shown below:" +msgstr "" + +#: classes/wp-security-file-scan.php:91 +msgid "Login to your site to view the scan details." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-file-scan.php:313 +msgid "The following files were added to your host" +msgstr "호스트에 다음 파일이 추가되었습니다." + +#: classes/wp-security-file-scan.php:315 +#: classes/wp-security-file-scan.php:323 +#: classes/wp-security-file-scan.php:332 +msgid "modified on: " +msgstr "" + +#: classes/wp-security-file-scan.php:321 +msgid "The following files were removed from your host" +msgstr "" + +#: classes/wp-security-file-scan.php:330 +msgid "The following files were changed on your host" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:212 +#: classes/wp-security-general-init-tasks.php:481 +msgid "Application passwords have been disabled by All In One WP Security & Firewall plugin." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:428 +#: classes/wp-security-general-init-tasks.php:541 +#: classes/wp-security-general-init-tasks.php:574 +#: classes/wp-security-user-login.php:137 +#: classes/wp-security-user-registration.php:74 +msgid "ERROR: Your answer was incorrect - please try again." +msgstr "오류: 당신의 대답은 잘못되었습니다 - 다시 시도하십시오." + +#: classes/wp-security-general-init-tasks.php:463 +msgid "Enter something special:" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:476 +msgid "Application passwords" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:485 +msgid "Change setting" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:487 +msgid "Site admin can only change this setting." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:516 +msgid "Error: You entered an incorrect CAPTCHA answer. Please go back and try again." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:558 +msgid "Your CAPTCHA answer was incorrect - please try again." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:567 +msgid "ERROR: Your IP address is currently locked please contact the administrator!" +msgstr "" + +#. translators: %s: Admin Dashboard > WP Security > Brute Force > Login CAPTCHA Tab Link +#: classes/wp-security-general-init-tasks.php:642 +msgid "Your Google reCAPTCHA site key is wrong. Please fill the correct reCAPTCHA keys %s to use the Google reCAPTCHA feature." +msgstr "" + +#. translators: %s: Admin Dashboard > WP Security > Brute Force > Login CAPTCHA Tab Link +#: classes/wp-security-general-init-tasks.php:642 +#: classes/wp-security-notices.php:99 +msgid "here" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +msgid "Would you like All In One WP Security & Firewall to re-insert the security rules in your .htaccess file which were cleared when you deactivated the plugin?" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +#: templates/may-also-like.php:40 +#: templates/may-also-like.php:43 +#: templates/may-also-like.php:54 +#: templates/may-also-like.php:57 +#: templates/may-also-like.php:68 +#: templates/may-also-like.php:71 +#: templates/may-also-like.php:91 +#: templates/may-also-like.php:103 +#: templates/may-also-like.php:115 +#: templates/may-also-like.php:127 +#: templates/may-also-like.php:139 +#: templates/may-also-like.php:151 +#: templates/may-also-like.php:168 +#: templates/may-also-like.php:171 +#: templates/may-also-like.php:183 +#: templates/may-also-like.php:195 +#: templates/may-also-like.php:207 +#: templates/may-also-like.php:219 +#: templates/may-also-like.php:231 +#: templates/may-also-like.php:243 +#: templates/may-also-like.php:252 +#: templates/may-also-like.php:255 +#: templates/may-also-like.php:264 +#: templates/may-also-like.php:267 +#: templates/may-also-like.php:279 +#: templates/may-also-like.php:297 +#: templates/may-also-like.php:309 +#: templates/may-also-like.php:327 +#: templates/may-also-like.php:339 +#: templates/may-also-like.php:351 +#: templates/may-also-like.php:368 +#: templates/may-also-like.php:380 +msgid "Yes" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +#: templates/may-also-like.php:88 +#: templates/may-also-like.php:100 +#: templates/may-also-like.php:112 +#: templates/may-also-like.php:124 +#: templates/may-also-like.php:136 +#: templates/may-also-like.php:148 +#: templates/may-also-like.php:180 +#: templates/may-also-like.php:192 +#: templates/may-also-like.php:204 +#: templates/may-also-like.php:216 +#: templates/may-also-like.php:228 +#: templates/may-also-like.php:240 +#: templates/may-also-like.php:276 +#: templates/may-also-like.php:294 +#: templates/may-also-like.php:306 +#: templates/may-also-like.php:324 +#: templates/may-also-like.php:336 +#: templates/may-also-like.php:348 +#: templates/may-also-like.php:365 +#: templates/may-also-like.php:377 +#: templates/notices/custom-notice.php:27 +msgid "No" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:674 +msgid "Your registration is pending approval." +msgstr "" + +#: classes/wp-security-notices.php:25 +msgid "The All in One Security plugin has disabled the login whitelist setting that you have enabled in the past." +msgstr "" + +#: classes/wp-security-notices.php:29 +msgid "Your website is running on an Apache webserver, the login whitelisting might not be functional until the recent update of AIOS (because it relied upon Apache-specific module features)." +msgstr "" + +#: classes/wp-security-notices.php:31 +msgid "Your website is running on a non-Apache webserver, so the login whitelisting was not functional until the recent update of AIOS (because it relied upon Apache-specific features)." +msgstr "" + +#: classes/wp-security-notices.php:33 +msgid "It began working with AIOS version 5.0.8." +msgstr "" + +#: classes/wp-security-notices.php:33 +msgid "We have disabled it so that your login page will not be blocked unexpectedly." +msgstr "" + +#: classes/wp-security-notices.php:42 +msgid "Would you like to re-enable login whitelisting?" +msgstr "" + +#: classes/wp-security-notices.php:48 +msgid "Removed database backup feature from the All In One WP Security & Firewall plugin" +msgstr "" + +#: classes/wp-security-notices.php:50 +msgid "Beginning with version 5.0.0, AIOS has replaced the AIOS backup method with the superior UpdraftPlus method." +msgstr "" + +#: classes/wp-security-notices.php:51 +msgid "It remains free and is fully supported by the UpdraftPlus team." +msgstr "" + +#: classes/wp-security-notices.php:54 +msgid "You are seeing this notice because you have previously set up automated database backups in AIOS." +msgstr "" + +#: classes/wp-security-notices.php:55 +msgid "Would you like to set up scheduled backups with UpdraftPlus?" +msgstr "" + +#: classes/wp-security-notices.php:61 +msgid "Setup UpdraftPlus backup plugin" +msgstr "" + +#: classes/wp-security-notices.php:67 +msgid "Important: set up your IP address detection settings" +msgstr "" + +#: classes/wp-security-notices.php:69 +msgid "The All in One Security plugin couldn't be certain about the correct method to detect the IP address for your site visitors with your currently-configured IP address detection settings." +msgstr "" + +#: classes/wp-security-notices.php:70 +msgid "It is important for your security to set the IP address detection settings properly." +msgstr "" + +#: classes/wp-security-notices.php:73 +msgid "Please go to the settings and set them now." +msgstr "" + +#: classes/wp-security-notices.php:79 +msgid "Setup IP address detection settings" +msgstr "" + +#: classes/wp-security-notices.php:85 +msgid "Important: Disabled login whitelist setting" +msgstr "" + +#: classes/wp-security-notices.php:91 +msgid "Turn it back on" +msgstr "" + +#: classes/wp-security-notices.php:92 +msgid "Edit the settings" +msgstr "" + +#: classes/wp-security-notices.php:95 +msgid "Keep it off" +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Hey - We noticed All In One WP Security & Firewall has kept your site safe for a while. If you like us, please consider leaving a positive review to spread the word. Or if you have any issues or questions please leave us a support message %s." +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Thank you so much!" +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Team All In One WP Security & Firewall" +msgstr "" + +#: classes/wp-security-notices.php:109 +msgid "Enhance your security even more by backing up your site" +msgstr "" + +#: classes/wp-security-notices.php:110 +msgid "UpdraftPlus is the world's most trusted backup plugin from the owners of All In One WP Security & Firewall" +msgstr "" + +#: classes/wp-security-notices.php:121 +msgid "After you've secured your site, we recommend you install our WP-Optimize plugin to streamline it for better website performance." +msgstr "" + +#: classes/wp-security-process-renamed-login-page.php:152 +msgid "Not available." +msgstr "" + +#: classes/wp-security-two-factor-login.php:34 +msgid "Two factor authentication - Admin settings" +msgstr "" + +#: classes/wp-security-two-factor-login.php:97 +msgid "Two Factor Auth" +msgstr "" + +#: classes/wp-security-two-factor-login.php:153 +msgid "PHP OpenSSL or mcrypt module required" +msgstr "" + +#: classes/wp-security-two-factor-login.php:153 +msgid "The All In One WP Security plugin's Two Factor Authentication module requires either the PHP openssl (preferred) or mcrypt module to be installed. Please ask your web hosting company to install one of them." +msgstr "" + +#: classes/wp-security-user-login.php:71 +msgid "You have disabled login lockout by defining the AIOS_DISABLE_LOGIN_LOCKOUT constant value as true, and the login lockout setting has enabled it." +msgstr "" + +#. translators: 1: Locked IP Addresses admin page link +#: classes/wp-security-user-login.php:73 +msgid "Delete your login lockout IP from %s and define the AIOS_DISABLE_LOGIN_LOCKOUT constant value as false." +msgstr "" + +#: classes/wp-security-user-login.php:100 +msgid "ERROR: Access from your IP address has been blocked for security reasons. Please contact the administrator." +msgstr "오류: 보안상의 이유로 IP 주소의 액세스가 차단되었습니다. 관리자에게 문의하십시오." + +#: classes/wp-security-user-login.php:108 +msgid "Service temporarily unavailable" +msgstr "일시적으로 사용할 수 없는 서비스" + +#: classes/wp-security-user-login.php:163 +msgid "ACCOUNT PENDING: Your account is currently not active. An administrator needs to activate your account before you can login." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-user-login.php:242 +msgid "ERROR: Invalid login credentials." +msgstr "오류: 잘못된 로그인 자격 증명." + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-user-login.php:392 +msgid "Site Lockout Notification" +msgstr "사이트 잠금 알림" + +#: classes/wp-security-user-login.php:393 +msgid "User login lockout events had occurred due to too many failed login attempts or invalid username:" +msgstr "" + +#: classes/wp-security-user-login.php:396 +msgid "Username:" +msgstr "사용자 이름:" + +#: classes/wp-security-user-login.php:397 +msgid "IP address:" +msgstr "IP 주소:" + +#: classes/wp-security-user-login.php:399 +msgid "IP range:" +msgstr "IP 범위:" + +#: classes/wp-security-user-login.php:404 +msgid "Log into your site WordPress administration panel to see the duration of the lockout or to unlock the user." +msgstr "" + +#: classes/wp-security-user-login.php:515 +msgid "Unlock request notification" +msgstr "요청 알림 잠금 해제" + +#: classes/wp-security-user-login.php:516 +msgid "You have requested for the account with email address %s to be unlocked. Please click the link below to unlock your account:" +msgstr "이메일 주소 %s가 있는 계정의 잠금을 해제하도록 요청했습니다. 계정 잠금을 해제하려면 아래 링크를 클릭하십시오." + +#: classes/wp-security-user-login.php:516 +msgid "Unlock link: %s" +msgstr "링크 잠금 해제: %s" + +#: classes/wp-security-user-login.php:516 +msgid "After clicking the above link you will be able to login to the WordPress administration panel." +msgstr "위의 링크를 클릭하면 WordPress 관리 패널에 로그인할 수 있습니다." + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-user-login.php:739 +msgid "Your session has expired because it has been over %d minutes since your last login." +msgstr "마지막 로그인 이후 %d 분 이상되었기 때문에 세션이 만료되었습니다." + +#: classes/wp-security-user-login.php:740 +#: classes/wp-security-user-login.php:744 +msgid "Please log back in to continue." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-user-login.php:743 +msgid "You were logged out because you just changed the \"admin\" username." +msgstr "방금 \"관리자\" 사용자 이름을 변경했기 때문에 로그아웃되었습니다." + +#: classes/wp-security-user-login.php:773 +msgid "Request unlock" +msgstr "잠금 해제 요청" + +#: classes/wp-security-user-registration.php:68 +msgid "ERROR: You are not allowed to register because your IP address is currently locked!" +msgstr "오류: IP 주소가 현재 잠겨 있기 때문에 등록할 수 없습니다!" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-utility-ip-address.php:217 +#: classes/wp-security-utility-ip-address.php:231 +#: classes/wp-security-utility-ip-address.php:245 +#: classes/wp-security-utility-ip-address.php:257 +#: classes/wp-security-utility-ip-address.php:269 +msgid " is not a valid ip address format." +msgstr "유효한 IP 주소 형식이 아닙니다." + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-utility-ip-address.php:274 +msgid "You cannot ban your own IP address: " +msgstr "자신의 IP 주소를 금지할 수 없습니다." + +#: classes/wp-security-utility.php:254 +msgid "This feature can only be configured by the \"superadmin\" on the main site." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:32 +msgid "ERROR: Unable to process your request!" +msgstr "" + +#: other-includes/wp-security-unlock-request.php:45 +msgid "Please enter a valid email address" +msgstr "올바은 이메일 주소를 입력하세요" + +#: other-includes/wp-security-unlock-request.php:57 +msgid "User account not found!" +msgstr "계정을 찾지 못했습니다." + +#: other-includes/wp-security-unlock-request.php:71 +msgid "Error: No locked entry was found in the database with your IP address range." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:76 +msgid "An email has been sent to you with the unlock instructions." +msgstr "잠금 해제 지침과 함께 이메일이 전송되었습니다." + +#: other-includes/wp-security-unlock-request.php:93 +msgid "You are here because you have been locked out due to too many incorrect login attempts." +msgstr "잘못된 로그인 시도가 너무 많아 서 잠겨 있기 때문에 여기에 있습니다." + +#: other-includes/wp-security-unlock-request.php:94 +msgid "Please enter your email address and you will receive an email with instructions on how to unlock yourself." +msgstr "이메일 주소를 입력하면 잠금을 해제하는 방법에 대한 지침이 있는 이메일을 받게 됩니다." + +#: other-includes/wp-security-unlock-request.php:104 +msgid "Email Address" +msgstr "이메일 주소" + +#: other-includes/wp-security-unlock-request.php:108 +msgid "Send unlock request" +msgstr "" + +#: templates/admin/incompatible-plugin.php:6 +msgid "Two Factor Authentication" +msgstr "" + +#: templates/admin/incompatible-plugin.php:10 +msgid "Two Factor Authentication currently disabled" +msgstr "" + +#: templates/admin/incompatible-plugin.php:12 +#: templates/admin/incompatible-plugin.php:16 +msgid "Two factor authentication in All In One WP Security is currently disabled because the incompatible plugin %s is active." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: templates/automated-database-backup.php:4 +msgid "Automated scheduled backups" +msgstr "자동 예약된 백업" + +#: templates/automated-database-backup.php:9 +msgid "Automate backup in the UpdraftPlus plugin" +msgstr "" + +#: templates/automated-database-backup.php:19 +msgid "The AIOS 5.0.0 version release has removed the automated backup feature." +msgstr "" + +#: templates/automated-database-backup.php:20 +msgid "The AIOS automated backup had issues that made it less robust than we could be happy with." +msgstr "" + +#: templates/automated-database-backup.php:21 +msgid "Follow this link to automate backups in the superior UpdraftPlus backup plugin." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: templates/info/ip-address-ip-range-info.php:5 +msgid "Each IP address must be on a new line." +msgstr "각 IP 주소는 새 줄에 있어야 합니다." + +#: templates/info/ip-address-ip-range-info.php:6 +msgid "To specify an IPv4 range use a wildcard \"*\" character. Acceptable ways to use wildcards is shown in the examples below:" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: templates/info/ip-address-ip-range-info.php:7 +msgid "Example 1: 195.47.89.*" +msgstr "예 1: 195.47.89.*" + +# @ all-in-one-wp-security-and-firewall +#: templates/info/ip-address-ip-range-info.php:8 +msgid "Example 2: 195.47.*.*" +msgstr "示例 2:195.47.*.*" + +# @ all-in-one-wp-security-and-firewall +#: templates/info/ip-address-ip-range-info.php:9 +msgid "Example 3: 195.*.*.*" +msgstr "示例 3:195.*.*.*" + +#: templates/info/ip-address-ip-range-info.php:10 +msgid "To specify an IPv6 range use CIDR format as shown in the examples below:" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:11 +msgid "Example 4: 2401:4900:54c3:af15:2:2:5dc0:0/112" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:12 +msgid "Example 5: 2001:db8:1263::/48" +msgstr "" + +#: templates/may-also-like.php:5 +msgid "All-In-One Security (AIOS) Free vs Premium Comparison Chart" +msgstr "" + +#: templates/may-also-like.php:7 +msgid "FAQs" +msgstr "" + +#: templates/may-also-like.php:9 +msgid "Ask a pre-sales question" +msgstr "" + +#: templates/may-also-like.php:17 +msgid "All In One WP Security & Firewall Free" +msgstr "" + +#: templates/may-also-like.php:26 +#: templates/may-also-like.php:386 +msgid "Installed" +msgstr "" + +#: templates/may-also-like.php:29 +#: templates/may-also-like.php:389 +msgid "Upgrade now" +msgstr "" + +#: templates/may-also-like.php:34 +msgid "Login security feature suite" +msgstr "" + +#: templates/may-also-like.php:35 +msgid "Protect against brute-force attacks and keep bots at bay." +msgstr "" + +#: templates/may-also-like.php:35 +msgid "AIOS takes WordPress' default login security features to a whole new level." +msgstr "" + +#: templates/may-also-like.php:37 +msgid "To see all login security features, visit %s" +msgstr "" + +#: templates/may-also-like.php:48 +msgid "Firewall and file protection feature suite" +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Protection from the latest exploits." +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Activate firewall settings ranging from basic, intermediate and advanced." +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Get comprehensive, instant protection with All-in-One Security." +msgstr "" + +#: templates/may-also-like.php:51 +msgid "To see all firewall and file protection features, visit %s" +msgstr "" + +#: templates/may-also-like.php:62 +msgid "Content protection feature suite" +msgstr "" + +#: templates/may-also-like.php:63 +msgid "Eliminate spam and protect your content to dramatically improve your website's interactions with search engines." +msgstr "" + +#: templates/may-also-like.php:65 +msgid "To see all content protection features, visit %s" +msgstr "" + +#: templates/may-also-like.php:76 +msgid "Malware scanning" +msgstr "" + +#: templates/may-also-like.php:77 +msgid "Finding out by accident that your site has been infected with malware is too late." +msgstr "" + +#: templates/may-also-like.php:79 +msgid "Malware can have a dramatic effect on your site's search rankings and you may not even know about it." +msgstr "" + +#: templates/may-also-like.php:79 +msgid "It can slow your website down, access customer data, send unsolicited emails, change your content or prevent users from accessing it." +msgstr "" + +#: templates/may-also-like.php:84 +msgid "Automatic malware scanning" +msgstr "" + +#: templates/may-also-like.php:85 +msgid "Best-in-class scanning for the latest malware, trojans and spyware 24/7." +msgstr "" + +#: templates/may-also-like.php:96 +msgid "Response time monitoring" +msgstr "" + +#: templates/may-also-like.php:97 +msgid "You'll know immediately if your website's response time is negatively affected." +msgstr "" + +#: templates/may-also-like.php:108 +msgid "Up-time monitoring" +msgstr "" + +#: templates/may-also-like.php:109 +msgid "AIOS checks your website's uptime every 5 minutes." +msgstr "" + +#: templates/may-also-like.php:109 +msgid "We'll notify you straight away if your site/server goes down." +msgstr "" + +#: templates/may-also-like.php:120 +msgid "Prevents blacklisting by search engines" +msgstr "" + +#: templates/may-also-like.php:121 +msgid "AIOS monitors your site's blacklist status daily." +msgstr "" + +#: templates/may-also-like.php:121 +msgid "We'll notify you within 24 hours if something's amiss so you can take action, before it's too late." +msgstr "" + +#: templates/may-also-like.php:132 +msgid "Flexible assignment" +msgstr "" + +#: templates/may-also-like.php:133 +msgid "Register and remove websites from the scanning service at any time." +msgstr "" + +#: templates/may-also-like.php:144 +msgid "Malware reports" +msgstr "" + +#: templates/may-also-like.php:145 +msgid "Reports are available via the 'My Account' page and directly via email." +msgstr "" + +#: templates/may-also-like.php:156 +msgid "Flexible two-factor authentication" +msgstr "" + +#: templates/may-also-like.php:157 +msgid "With Two-Factor Authentication (TFA) users enter their username and password and a one-time code sent to a device to login." +msgstr "" + +#: templates/may-also-like.php:159 +msgid "TFA is a feature in both our free and premium packages, but AIOS Premium affords whole new levels of control over how TFA is implemented." +msgstr "" + +#: templates/may-also-like.php:164 +msgid "Authenticator apps" +msgstr "" + +#: templates/may-also-like.php:165 +msgid "Supports TOTP and HOTP protocols." +msgstr "" + +#: templates/may-also-like.php:165 +msgid "TFA Can be used with Google Authenticator, Microsoft Authenticator, Authy and many more." +msgstr "" + +#: templates/may-also-like.php:176 +msgid "Role specific configuration" +msgstr "" + +#: templates/may-also-like.php:177 +msgid "Make it compulsory for certain roles e.g. for admin and editor roles." +msgstr "" + +#: templates/may-also-like.php:188 +msgid "Require TFA after a set time period" +msgstr "" + +#: templates/may-also-like.php:189 +msgid "For example you could require all admins to have TFA once their accounts are a week old." +msgstr "" + +#: templates/may-also-like.php:200 +msgid "Trusted devices - control how often TFA is required" +msgstr "" + +#: templates/may-also-like.php:201 +msgid "Ask for TFA after a chosen number of days for trusted devices instead of on every login." +msgstr "" + +#: templates/may-also-like.php:212 +msgid "Anti-bot protection" +msgstr "" + +#: templates/may-also-like.php:213 +msgid "Option to hide the existence of forms on WooCommerce login pages unless JavaScript is active." +msgstr "" + +#: templates/may-also-like.php:224 +msgid "Customise TFA design layout" +msgstr "" + +#: templates/may-also-like.php:225 +msgid "Customise the design of TFA so it aligns with your existing web design." +msgstr "" + +#: templates/may-also-like.php:236 +msgid "TFA emergency codes" +msgstr "" + +#: templates/may-also-like.php:237 +msgid "Generate a one-time use emergency code to allow access if your device is lost." +msgstr "" + +#: templates/may-also-like.php:248 +msgid "TFA multisite compatibility" +msgstr "" + +#: templates/may-also-like.php:249 +msgid "TFA is Compatible with multisite networks and sub-sites." +msgstr "" + +#: templates/may-also-like.php:260 +msgid "TFA support for common login forms" +msgstr "" + +#: templates/may-also-like.php:261 +msgid "Supports WooCommerce, Affiliates-WP and Theme my Login login forms." +msgstr "" + +#: templates/may-also-like.php:272 +msgid "TFA support for other login forms" +msgstr "" + +#: templates/may-also-like.php:273 +msgid "Supports Elementor Pro, bbPress and all third-party login forms without any further coding needed." +msgstr "" + +#: templates/may-also-like.php:284 +msgid "Smart 404 blocking" +msgstr "" + +#: templates/may-also-like.php:285 +msgid "404 errors can occur when someone legitimately mistypes a URL, but they're also generated by hackers searching for weaknesses in your site." +msgstr "" + +#: templates/may-also-like.php:290 +msgid "Automatically and permanently blocks bots producing 404s" +msgstr "" + +#: templates/may-also-like.php:291 +msgid "AIOS Premium provides more protection than the competition by automatically and permanently blocking IP addresses of bots and hackers based on how many 404 errors they generate." +msgstr "" + +#: templates/may-also-like.php:302 +msgid "404 error charts" +msgstr "" + +#: templates/may-also-like.php:303 +msgid "Handy charts keep you informed of how many 404s have occurred and which IP address or country is producing them." +msgstr "" + +#: templates/may-also-like.php:314 +msgid "Country blocking" +msgstr "" + +#: templates/may-also-like.php:315 +msgid "Most malicious attacks come from a handful of countries and so it's possible to prevent most attacks with our country blocking tool." +msgstr "" + +#: templates/may-also-like.php:320 +msgid "Block traffic based on country of origin" +msgstr "" + +#: templates/may-also-like.php:321 +msgid "AIOS Premium utilises an IP database that promises 99.5% accuracy." +msgstr "" + +#: templates/may-also-like.php:332 +msgid "Block traffic to specific pages based on country of origin" +msgstr "" + +#: templates/may-also-like.php:333 +msgid "Block access to your whole site or on a page-by-page basis." +msgstr "" + +#: templates/may-also-like.php:344 +msgid "Whitelist some users from blocked countries" +msgstr "" + +#: templates/may-also-like.php:345 +msgid "Whitelist IP addresses or IP ranges even if they are part of a blocked country." +msgstr "" + +#: templates/may-also-like.php:356 +msgid "Premium support" +msgstr "" + +#: templates/may-also-like.php:361 +msgid "Unlimited support" +msgstr "" + +#: templates/may-also-like.php:362 +msgid "Personalised, email support from our team of Security experts, as and when you need it." +msgstr "" + +#: templates/may-also-like.php:373 +msgid "Guaranteed response time" +msgstr "" + +#: templates/may-also-like.php:374 +msgid "We offer a guaranteed response time of three days." +msgstr "" + +#: templates/may-also-like.php:374 +msgid "99% of our Premium customers receive a response to their enquiry within 24 hours during the working week." +msgstr "" + +#: templates/may-also-like.php:397 +msgid "Our other plugins" +msgstr "" + +#: templates/may-also-like.php:411 +msgid "UpdraftPlus – the ultimate protection for your site, hard work and business" +msgstr "" + +#: templates/may-also-like.php:412 +msgid "Simplifies backups and restoration." +msgstr "" + +#: templates/may-also-like.php:412 +msgid "It is the world's highest ranking and most popular scheduled backup plugin, with over three million currently-active installs." +msgstr "" + +#: templates/may-also-like.php:413 +#: templates/may-also-like.php:419 +#: templates/may-also-like.php:425 +#: templates/may-also-like.php:431 +msgid "Try for free" +msgstr "" + +#: templates/may-also-like.php:417 +msgid "WP-Optimize – keep your database fast and efficient" +msgstr "" + +#: templates/may-also-like.php:418 +msgid "Makes your site fast and efficient." +msgstr "" + +#: templates/may-also-like.php:418 +msgid "It cleans the database, compresses images and caches pages for ultimate speed." +msgstr "" + +#: templates/may-also-like.php:423 +msgid "UpdraftCentral – save hours managing multiple WP sites from one place" +msgstr "" + +#: templates/may-also-like.php:424 +msgid "Highly efficient way to manage, optimize, update and backup multiple websites from one place." +msgstr "" + +#: templates/may-also-like.php:429 +msgid "Easy Updates Manager" +msgstr "" + +#: templates/may-also-like.php:430 +msgid "Keeps your WordPress site up to date and bug free." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:2 +msgid "IP address detection settings" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:6 +msgid "The IP address detection settings allow you to specify how visitors' IP addresses are made known to PHP (and hence to WordPress and its plugins)." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:7 +msgid "Usually, this is automatic and there is only one choice." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:8 +msgid "However in some setups, such as those using proxies (including load-balancers and security firewalls like Cloudflare), it may be necessary to set this manually." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: templates/menus/settings/advanced-settings.php:9 +msgid "Attention" +msgstr "주의!" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "It is important to set this correctly - otherwise you may make it possible for a hacker to ban all your visitors (e.g. via banning Cloudflare from connecting to you) instead of being banned himself." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "The default is to use the REMOTE_ADDR PHP server variable. If this variable does not contain the visitor's IP address, then whilst you can make a different selection below, it is better to ask your web hosting company to have it correctly set." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:10 +msgid "This is the most secure setup, because when set correctly it is immune from being spoofed by an attacker." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:16 +msgid "You have no available IP address detection method(s); you must contact your web hosting company." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:22 +#: templates/menus/settings/advanced-settings.php:27 +#: templates/menus/settings/advanced-settings.php:32 +msgid "Your detected IP address according to %s:" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:38 +msgid "If your site is setup on localhost, you won't see your external IP address using your server's IP detection setting; but on a localhost-served site (not available to the outside world), the setting is irrelevant and can be ignored." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:61 +msgid "Choose a $_SERVER variable you would like to detect visitors' IP address using." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:67 +msgid "If your chosen server variable fails the plugin will automatically fall back to retrieving the IP address from $_SERVER[\"REMOTE_ADDR\"]" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:73 +msgid "Your IP address if using this setting:" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:75 +msgid "fetching..." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:81 +#: templates/menus/settings/advanced-settings.php:190 +msgid "getting..." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:89 +msgid "look-up possibly blocked by an ad-blocker or similar tool" +msgstr "" + +#: templates/notices/cookie-based-brute-force-prevention-disabled.php:4 +msgid "Cookie based brute force login prevention currently disabled" +msgstr "" + +#: templates/notices/cookie-based-brute-force-prevention-disabled.php:6 +msgid "Cookie based brute force login prevention is currently disabled via the AIOS_DISABLE_COOKIE_BRUTE_FORCE_PREVENTION constant (which is mostly likely to be defined in your wp-config.php)" +msgstr "" + +#: templates/notices/disable-login-whitelist.php:4 +msgid "Login whitelisting currently disabled" +msgstr "" + +#: templates/notices/disable-login-whitelist.php:6 +msgid "Login whitelisting is currently disabled via the AIOS_DISABLE_LOGIN_WHITELIST constant (which is mostly likely to be defined in your wp-config.php)" +msgstr "" + +#: templates/notices/horizontal-notice.php:8 +#: templates/notices/horizontal-notice.php:40 +msgid "notice image" +msgstr "" + +#: templates/notices/horizontal-notice.php:18 +msgid "Ok, you deserve it" +msgstr "" + +#: templates/notices/horizontal-notice.php:22 +msgid "Maybe later" +msgstr "" + +#: templates/notices/horizontal-notice.php:26 +msgid "Never" +msgstr "" + +#: templates/notices/horizontal-notice.php:66 +msgid "Get UpdraftCentral" +msgstr "" + +#: templates/notices/horizontal-notice.php:68 +msgid "Get UpdraftPlus" +msgstr "" + +#: templates/notices/horizontal-notice.php:70 +msgid "Get WP-Optimize" +msgstr "" + +#: templates/notices/horizontal-notice.php:72 +msgid "Find out more." +msgstr "" + +#: templates/notices/horizontal-notice.php:74 +msgid "Sign up" +msgstr "" + +#: templates/notices/horizontal-notice.php:76 +msgid "Go there" +msgstr "" + +#: templates/notices/horizontal-notice.php:78 +msgid "Read more" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:4 +msgid "Dismiss (for %s months)" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:6 +msgid "Thank you for installing All In One WP Security & Firewall!" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:13 +msgid "Super-charge and secure your WordPress site even more with our other top plugins:" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:17 +msgid "%s makes your site fast and efficient. It cleans the database, compresses images and caches pages for ultimate speed." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:21 +msgid "%s simplifies backups and restoration. It is the world's highest ranking and most popular scheduled backup plugin, with over three million currently-active installs." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:25 +msgid "%s is a highly efficient way to manage, optimize, update and backup multiple websites from one place." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:29 +msgid "%s is a WordPress subscription extension for WooCommerce store owners." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:33 +msgid "More quality plugins" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:33 +msgid "Premium WooCommerce plugins" +msgstr "" + +#: templates/partials/non-apache-feature-notice.php:9 +msgid "This feature works only on the Apache server." +msgstr "" + +#: templates/partials/non-apache-feature-notice.php:10 +msgid "You are using the non-apache server %s, so this feature won't work on your site." +msgstr "" + +#: wp-security-core.php:236 +#: wp-security.php:45 +msgid "This plugin requires PHP version %s." +msgstr "" + +#: wp-security-core.php:237 +msgid "Current site PHP version is %s." +msgstr "" + +#: wp-security-core.php:238 +#: wp-security.php:47 +msgid "You will need to ask your web hosting company to upgrade." +msgstr "" + +#: wp-security-core.php:397 +msgid "Error:" +msgstr "" + +#: wp-security-core.php:397 +msgid "template not found" +msgstr "" + +#: wp-security.php:44 +msgid "All In One WP Security and Firewall plugin has been deactivated." +msgstr "" + +#: wp-security.php:46 +msgid "Your current PHP version is %s." +msgstr "" diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-pl_PL.mo b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-pl_PL.mo new file mode 100755 index 0000000000000000000000000000000000000000..14094369c7f87f87dd6de62a64f54dd0c7a61a65 GIT binary patch literal 1380 zcmYk5y^q{P7{*N!z8sJMDJTUJ6VZUUS$6jlCGzGF1{I0KWyF1iu4Mfj>0-5%hUKH~N=G{|25!{1NE= z{s5l_|7_xagWm6-M*jzTpA#qQ{L`Sn@AD1Mg5K|C@D|1^7-yhAK{MX}3-B56EATY< zO{2dDz0Xe#A2#t{!4UD^!RNrgK=1P}=<`oPJPU@P@AE9^eHrNMHX3~qL`ksS#NPvb zAN!#1_ZAq$ISEUQlq180!q3jJl8R+=ES-%4lH-Z1XCf6)PBUO6N6yQUoKY~+Q&UY< zNJ&M3pDLvxY*kXtRm{pofKja-Ox#48T1*U4;O3OW6;N&o=pZ)wkW$BYGX4P>E47N) z+j-7*6uYj7eHgQSN~cD;C7aDQI~P0s@CKFIIKF4cGUHdKW6Os+VqtuJ$hQp%2M_*^ za8$+k4Vp=B+l2bvevfxId2f^Td(nmd>)l?r8}170_|V{pa^bXzSRvGua(20RtI#tl z$cc_N<2RA0##1pSJ|t1#2Ca@*nJ4jXxVN)+b^S+roo=|T@cgEZ?7&{soEHl57~nIunO%zEtuKdo`Eo>b7_- z3bd6})Uy)z@1~N1L&~UKm-61{?zp)3X^^h)AuVgPTiHs|9J$zTmq%rlA3g@y77f}m jyQ2GdQ3KjG=Id>3<;-f?hW$Fo=AzYD`b^)l@bTb(POE%_ literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-pl_PL.po b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-pl_PL.po new file mode 100755 index 00000000..c3d34581 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-pl_PL.po @@ -0,0 +1,6015 @@ +msgid "" +msgstr "" +"Project-Id-Version: All In One WP Security vv3.7.2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2021-03-13 21:52+0100\n" +"Last-Translator: manuel \n" +"Language-Team: \n" +"Language: pl_PL\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Poedit 2.4.2\n" +"X-Poedit-Basepath: ..\n" +"X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n" +"X-Poedit-SearchPath-0: .\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Textdomain-Support: yes\n" + +#. Plugin Name of the plugin +msgid "All In One WP Security" +msgstr "" + +#. Plugin URI of the plugin +msgid "https://wordpress.org/plugins/all-in-one-wp-security-and-firewall/" +msgstr "" + +#. Description of the plugin +msgid "All round best WordPress security plugin!" +msgstr "" + +#. Author of the plugin +msgid "All In One WP Security & Firewall Team" +msgstr "" + +#. Author URI of the plugin +msgid "https://teamupdraft.com/" +msgstr "" + +#: admin/general/wp-security-list-table.php:483 +msgid "Are you sure you want to perform this bulk action?" +msgstr "" + +#: admin/wp-security-admin-init.php:259 +msgid "Unexpected response:" +msgstr "" + +#: admin/wp-security-admin-init.php:290 +msgid "Enjoyed %1$s? Please leave us a %2$s rating. We really appreciate your support!" +msgstr "" + +#: admin/wp-security-admin-init.php:414 +#: classes/wp-security-two-factor-login.php:95 +msgid "WP Security" +msgstr "" + +#: admin/wp-security-admin-init.php:415 +#: admin/wp-security-dashboard-menu.php:26 +#: admin/wp-security-dashboard-menu.php:76 +msgid "Dashboard" +msgstr "" + +#: admin/wp-security-admin-init.php:416 +#: admin/wp-security-settings-menu.php:95 +msgid "Settings" +msgstr "" + +#: admin/wp-security-admin-init.php:417 +msgid "User Accounts" +msgstr "" + +#: admin/wp-security-admin-init.php:418 +msgid "User Login" +msgstr "" + +#: admin/wp-security-admin-init.php:419 +msgid "User Registration" +msgstr "" + +#: admin/wp-security-admin-init.php:420 +msgid "Database Security" +msgstr "" + +#: admin/wp-security-admin-init.php:424 +msgid "Filesystem Security" +msgstr "" + +#: admin/wp-security-admin-init.php:429 +msgid "Blacklist Manager" +msgstr "" + +#: admin/wp-security-admin-init.php:434 +#: admin/wp-security-firewall-menu.php:60 +msgid "Firewall" +msgstr "" + +#: admin/wp-security-admin-init.php:436 +msgid "Brute Force" +msgstr "" + +#: admin/wp-security-admin-init.php:437 +msgid "Spam Prevention" +msgstr "" + +#: admin/wp-security-admin-init.php:441 +#: admin/wp-security-filescan-menu.php:53 +msgid "Scanner" +msgstr "" + +#: admin/wp-security-admin-init.php:443 +#: admin/wp-security-maintenance-menu.php:51 +msgid "Maintenance" +msgstr "" + +#: admin/wp-security-admin-init.php:444 +#: admin/wp-security-misc-options-menu.php:57 +msgid "Miscellaneous" +msgstr "" + +#: admin/wp-security-admin-init.php:445 +#: admin/wp-security-tools-menu.php:64 +msgid "Tools" +msgstr "" + +#: admin/wp-security-admin-init.php:457 +msgid "Premium Upgrade" +msgstr "" + +#: admin/wp-security-admin-menu.php:67 +msgid "Settings successfully updated." +msgstr "" + +#: admin/wp-security-admin-menu.php:77 +msgid "Successfully deleted the selected record(s)." +msgstr "" + +#: admin/wp-security-admin-menu.php:86 +msgid "Failed to delete the selected record(s)." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:25 +msgid "Ban users" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:51 +msgid "Blacklist manager" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:132 +#: admin/wp-security-firewall-menu.php:1233 +#: admin/wp-security-list-404.php:234 +#: admin/wp-security-list-comment-spammer-ip.php:205 +msgid "The plugin was unable to write to the .htaccess file. Please edit file manually." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:139 +msgid "Ban IPs or user agents" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:142 +msgid "The All In One WP Security Blacklist feature gives you the option of banning certain host IP addresses or ranges and also user agents." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:143 +msgid "This feature will deny total site access for users which have IP addresses or user agents matching those which you have configured in the settings below." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:144 +msgid "The plugin achieves this by making appropriate modifications to your .htaccess file." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:145 +msgid "By blocking people, you are using the most secure first line of defence, which denies all access to blacklisted visitors as soon as they hit your hosting server." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:154 +#: admin/wp-security-firewall-menu.php:1055 +#: templates/may-also-like.php:20 +msgid "All In One WP Security & Firewall Premium" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:155 +#: admin/wp-security-firewall-menu.php:1056 +msgid "You may also be interested in %s." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "This plugin adds a number of extra features including %s and %s." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "smart 404 blocking" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "country IP blocking" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:170 +msgid "IP hosts and user agent blacklist settings" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:182 +#: admin/wp-security-brute-force-menu.php:193 +#: admin/wp-security-brute-force-menu.php:331 +msgid "must read this message" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:183 +#: admin/wp-security-brute-force-menu.php:194 +msgid "This feature can lock you out of admin if it doesn't work correctly on your site. You %s before activating this feature." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:189 +msgid "Enable IP or user agent blacklisting" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:192 +msgid "Check this if you want to enable the banning (or blacklisting) of selected IP addresses and/or user agents specified in the settings below" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:196 +msgid "Enter IP addresses:" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:200 +msgid "Enter one or more IP addresses or IP ranges." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:205 +msgid "Enter user agents:" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:210 +msgid "Enter one or more user agent strings." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:211 +#: admin/wp-security-brute-force-menu.php:374 +#: admin/wp-security-brute-force-menu.php:408 +#: admin/wp-security-brute-force-menu.php:431 +#: admin/wp-security-brute-force-menu.php:452 +#: admin/wp-security-filescan-menu.php:309 +#: admin/wp-security-filescan-menu.php:326 +#: admin/wp-security-firewall-menu.php:175 +#: admin/wp-security-firewall-menu.php:212 +#: admin/wp-security-firewall-menu.php:232 +#: admin/wp-security-firewall-menu.php:258 +#: admin/wp-security-firewall-menu.php:385 +#: admin/wp-security-firewall-menu.php:415 +#: admin/wp-security-firewall-menu.php:446 +#: admin/wp-security-firewall-menu.php:474 +#: admin/wp-security-firewall-menu.php:503 +#: admin/wp-security-firewall-menu.php:681 +#: admin/wp-security-firewall-menu.php:699 +#: admin/wp-security-firewall-menu.php:737 +#: admin/wp-security-firewall-menu.php:868 +#: admin/wp-security-firewall-menu.php:1087 +#: admin/wp-security-firewall-menu.php:1110 +#: admin/wp-security-spam-menu.php:186 +#: admin/wp-security-spam-menu.php:221 +#: admin/wp-security-spam-menu.php:390 +#: admin/wp-security-spam-menu.php:430 +#: admin/wp-security-user-login-menu.php:362 +#: templates/info/ip-address-ip-range-info.php:2 +#: templates/menus/settings/advanced-settings.php:63 +msgid "More info" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:214 +msgid "Each user agent string must be on a new line." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:215 +msgid "Example 1 - A single user agent string to block:" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:217 +msgid "Example 2 - A list of more than 1 user agent strings to block" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:225 +#: admin/wp-security-brute-force-menu.php:213 +#: admin/wp-security-brute-force-menu.php:686 +#: admin/wp-security-brute-force-menu.php:806 +#: admin/wp-security-brute-force-menu.php:868 +#: admin/wp-security-filescan-menu.php:351 +#: admin/wp-security-filesystem-menu.php:242 +#: admin/wp-security-firewall-menu.php:945 +#: admin/wp-security-firewall-menu.php:1129 +#: admin/wp-security-misc-options-menu.php:167 +#: admin/wp-security-misc-options-menu.php:218 +#: admin/wp-security-misc-options-menu.php:278 +#: admin/wp-security-settings-menu.php:619 +#: admin/wp-security-settings-menu.php:680 +#: admin/wp-security-spam-menu.php:233 +#: admin/wp-security-spam-menu.php:407 +#: admin/wp-security-spam-menu.php:526 +#: admin/wp-security-spam-menu.php:588 +#: admin/wp-security-user-login-menu.php:384 +#: admin/wp-security-user-login-menu.php:422 +#: admin/wp-security-user-login-menu.php:601 +#: admin/wp-security-user-login-menu.php:788 +#: admin/wp-security-user-registration-menu.php:150 +#: admin/wp-security-user-registration-menu.php:242 +#: admin/wp-security-user-registration-menu.php:305 +#: templates/menus/settings/advanced-settings.php:217 +msgid "Save settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:33 +#: admin/wp-security-brute-force-menu.php:759 +#: admin/wp-security-dashboard-menu.php:651 +msgid "Rename login page" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:34 +#: admin/wp-security-brute-force-menu.php:154 +msgid "Cookie based brute force prevention" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:35 +#: classes/grade-system/wp-security-feature-item-manager.php:105 +msgid "Login CAPTCHA" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:36 +#: admin/wp-security-brute-force-menu.php:746 +msgid "Login whitelist" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:37 +msgid "Honeypot" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:67 +msgid "Brute force" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:105 +msgid "Please enter a value for your login page slug." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:109 +msgid "You cannot use the value \"wp-admin\" for your login page slug." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:111 +msgid "You must use alpha numeric characters for your login page slug." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:116 +#: admin/wp-security-filescan-menu.php:174 +#: admin/wp-security-firewall-menu.php:151 +#: admin/wp-security-firewall-menu.php:1011 +#: admin/wp-security-spam-menu.php:101 +#: admin/wp-security-spam-menu.php:270 +#: admin/wp-security-spam-menu.php:302 +#: admin/wp-security-user-login-menu.php:184 +#: admin/wp-security-user-login-menu.php:553 +#: templates/partials/non-apache-feature-notice.php:9 +msgid "Attention:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:133 +msgid "Could not delete the Cookie-based directives from the .htaccess file. Please check the file permissions." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:155 +msgid "Login page white list" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:156 +msgid "An effective Brute Force prevention technique is to change the default WordPress login page URL." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:157 +msgid "Normally if you wanted to login to WordPress you would type your site's home URL followed by wp-login.php." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:158 +msgid "This feature allows you to change the login URL by setting your own slug and renaming the last portion of the login URL which contains the wp-login.php to any string that you like." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:159 +msgid "By doing this, malicious bots and hackers will not be able to access your login page because they will not know the correct login page URL." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:161 +msgid "You may also be interested in the following alternative brute force prevention features:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:172 +msgid "Your WordPress login page URL has been renamed." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:173 +msgid "Your current login URL is:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:181 +msgid "Rename login page settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:195 +msgid "NOTE: If you are hosting your site on WPEngine or a provider which performs server caching, you will need to ask the host support people to NOT cache your renamed login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:200 +msgid "Enable rename login page feature" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:203 +msgid "Check this if you want to enable the rename login page feature" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:207 +msgid "Login page URL" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:209 +msgid "Enter a string which will represent your secure login page slug. You are encouraged to choose something which is hard to guess and only you will remember." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:243 +msgid "Settings have not been saved - your secret word must consist only of alphanumeric characters, ie, letters and/or numbers only." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:257 +msgid "You have successfully enabled the cookie based brute force prevention feature" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:258 +msgid "From now on you will need to log into your WP Admin using the following URL:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:260 +msgid "It is important that you save this URL value somewhere in case you forget it, OR," +msgstr "" + +#: admin/wp-security-brute-force-menu.php:261 +msgid "simply remember to add a \"?%s=1\" to your current site URL address." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:265 +msgid "You have successfully saved cookie based brute force prevention feature settings." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:295 +msgid "Brute force prevention firewall settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:300 +msgid "A Brute Force Attack is when a hacker tries many combinations of usernames and passwords until they succeed in guessing the right combination." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:301 +msgid "Due to the fact that at any one time there may be many concurrent login attempts occurring on your site via malicious automated robots, this also has a negative impact on your server's memory and performance." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:302 +msgid "The features in this tab will stop the majority of brute force login attacks thus providing even better protection for your WP login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:307 +#: admin/wp-security-firewall-menu.php:654 +msgid "backup" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:308 +msgid "video tutorial" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:309 +msgid "To learn more about how to use this feature, please watch the following %s." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:310 +#: admin/wp-security-brute-force-menu.php:758 +msgid "Cookie-Based Brute Force Login Prevention" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:320 +#: admin/wp-security-user-login-menu.php:253 +msgid "Cookie based brute force login prevention" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:331 +msgid "This feature can lock you out of admin if it doesn't work correctly on your site. You " +msgstr "" + +#: admin/wp-security-brute-force-menu.php:342 +msgid "The cookie test was successful. You can now enable this feature." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:350 +msgid "The cookie test failed on this server. Consequently, this feature cannot be used on this site." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:357 +msgid "Before using this feature, you must perform a cookie test first." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:359 +msgid "This ensures that your browser cookie is working correctly and that you won't lock yourself out." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:364 +msgid "Perform cookie test" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:370 +#: classes/grade-system/wp-security-feature-item-manager.php:103 +msgid "Enable brute force attack prevention" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:373 +msgid "Check this if you want to protect your login page from Brute Force Attack." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:378 +msgid "This feature will deny access to your WordPress login page for all people except those who have a special cookie in their browser." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:380 +msgid "To use this feature do the following:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:382 +msgid "1) Enable the checkbox." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:384 +msgid "2) Enter a secret word consisting of alphanumeric characters which will be difficult to guess. This secret word will be useful whenever you need to know the special URL which you will use to access the login page (see point below)." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:386 +msgid "3) You will then be provided with a special login URL. You will need to use this URL to login to your WordPress site instead of the usual login URL. NOTE: The system will deposit a special cookie in your browser which will allow you access to the WordPress administration login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:388 +msgid "Any person trying to access your login page who does not have the special cookie in their browser will be automatically blocked." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:395 +msgid "Secret word" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:397 +msgid "Choose a secret word consisting of alphanumeric characters which you can use to access your special URL. Your are highly encouraged to choose a word which will be difficult to guess." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:401 +msgid "Re-direct URL" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:405 +msgid "Specify a URL to redirect a hacker to when they try to access your WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:412 +msgid "The URL specified here can be any site's URL and does not have to be your own. For example you can be as creative as you like and send hackers to the CIA or NSA home page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:414 +msgid "This field will default to: http://127.0.0.1 if you do not enter a value." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:416 +msgid "Useful Tip:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:418 +msgid "It's a good idea to not redirect attempted brute force login attempts to your site because it increases the load on your server." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:420 +msgid "Redirecting a hacker or malicious bot back to \"http://127.0.0.1\" is ideal because it deflects them back to their own local host and puts the load on their server instead of yours." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:427 +msgid "My site has posts or pages which are password protected" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:430 +msgid "Check this if you are using the native WordPress password protection feature for some or all of your blog posts or pages." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:435 +msgid "In the cases where you are protecting some of your posts or pages using the in-built WordPress password protection feature, a few extra lines of directives and exceptions need to be added so that people trying to access pages are not automatically blocked." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:437 +msgid "By enabling this checkbox, the plugin will add the necessary rules and exceptions so that people trying to access these pages are not automatically blocked." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:439 +msgid "Helpful Tip:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:441 +msgid "If you do not use the WordPress password protection feature for your posts or pages then it is highly recommended that you leave this checkbox disabled." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:448 +msgid "My site has a theme or plugins which use AJAX" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:451 +msgid "Check this if your site uses AJAX functionality." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:456 +msgid "In the cases where your WordPress installation has a theme or plugin that uses AJAX, a few extra lines of directives and exceptions need to be added to prevent AJAX requests from being automatically blocked by the brute force prevention feature." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:458 +msgid "By enabling this checkbox, the plugin will add the necessary rules and exceptions so that AJAX operations will work as expected." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:467 +msgid "Save feature settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:525 +msgid "This feature allows you to add a CAPTCHA form on various WordPress login pages and forms." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:526 +msgid "Adding a CAPTCHA form on a login page or form is another effective yet simple \"Brute Force\" prevention technique." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:527 +msgid "You have the option of using either %s or a plain maths CAPTCHA form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:528 +msgid "If you enable Google reCAPTCHA the reCAPTCHA widget will be displayed for all forms the CAPTCHA settings below." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:529 +msgid "If Google reCAPTCHA is disabled the simple maths CAPTCHA form will apply and users will need to enter the answer to a simple mathematical question." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:535 +msgid "Google reCAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:540 +msgid "By enabling these settings the Google reCAPTCHA v2 widget will be applied by default for all forms with CAPTCHA enabled." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:549 +msgid "reCAPTCHA will not work because you have disabled login lockout by activating the AIOS_DISABLE_LOGIN_LOCKOUT constant value in a configuration file." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:550 +msgid "To enable it, define AIOS_DISABLE_LOGIN_LOCKOUT constant value as false, or remove it." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:558 +msgid "Use Google reCAPTCHA as default" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:561 +msgid "Check this if you want to default to Google reCAPTCHA for all settings below. (If this is left unchecked, all CAPTCHA forms will revert to the plain maths CAPTCHA)" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:565 +msgid "Site key" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:571 +msgid "Secret key" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:580 +msgid "Login form CAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:589 +msgid "Enable CAPTCHA on login page" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:592 +msgid "Check this if you want to insert a CAPTCHA form on the login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:598 +msgid "Lost password form CAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:608 +msgid "Enable CAPTCHA on lost password page" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:611 +msgid "Check this if you want to insert a CAPTCHA form on the lost password page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:617 +msgid "Custom login form CAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:626 +msgid "Enable CAPTCHA on custom login form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:629 +msgid "Check this if you want to insert CAPTCHA on a custom login form generated by the following WP function: wp_login_form()" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:639 +msgid "WooCommerce forms CAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:648 +msgid "Enable CAPTCHA on WooCommerce login form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:651 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce login form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:661 +msgid "Enable CAPTCHA on WooCommerce lost password form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:664 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce lost password form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:674 +msgid "Enable CAPTCHA on WooCommerce registration form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:677 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce registration form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:749 +msgid "The All In One WP Security Whitelist feature gives you the option of only allowing certain IP addresses or ranges to have access to your WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:750 +msgid "This feature will deny login access for all IP addresses which are not in your whitelist as configured in the settings below." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:751 +msgid "The plugin achieves this by writing the appropriate directives to your .htaccess file." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:752 +msgid "By allowing/blocking IP addresses, you are using the most secure first line of defence because login access will only be granted to whitelisted IP addresses and other addresses will be blocked as soon as they try to access your login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:760 +msgid "Attention: If in addition to enabling the white list feature, you also have one of the %s or %s features enabled, you will still need to use your secret word or special slug in the URL when trying to access your WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:761 +msgid "These features are NOT functionally related. Having both of them enabled on your site means you are creating 2 layers of security." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:772 +msgid "Login IP whitelist settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:783 +msgid "Enable IP whitelisting" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:786 +#: admin/wp-security-user-login-menu.php:408 +msgid "Check this if you want to enable the whitelisting of selected IP addresses specified in the settings below" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:790 +msgid "Your current IP address" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:793 +msgid "You can copy and paste this address in the text box below if you want to include it in your login whitelist." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:797 +#: admin/wp-security-user-login-menu.php:412 +msgid "Enter whitelisted IP addresses:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:801 +#: admin/wp-security-user-login-menu.php:416 +msgid "Enter one or more IP addresses or IP ranges you wish to include in your whitelist." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:801 +msgid "Only the addresses specified here will have access to the WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:839 +msgid "This feature allows you to add a special hidden \"honeypot\" field on the WordPress login page. This will only be visible to robots and not humans." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:840 +msgid "Since robots usually fill in every input field from a login form, they will also submit a value for the special hidden honeypot field." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:841 +#: admin/wp-security-user-registration-menu.php:278 +msgid "The way honeypots work is that a hidden field is placed somewhere inside a form which only robots will submit. If that field contains a value when the form is submitted then a robot has most likely submitted the form and it is consequently dealt with." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:842 +msgid "Therefore, if the plugin detects that this field has a value when the login form is submitted, then the robot which is attempting to login to your site will be redirected to its localhost address - http://127.0.0.1." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:848 +msgid "Login form honeypot settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:859 +msgid "Enable honeypot on login page" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:862 +msgid "Check this if you want to enable the honeypot feature for the login page" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:27 +#: admin/wp-security-dashboard-menu.php:374 +#: classes/wp-security-user-login.php:74 +msgid "Locked IP addresses" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:28 +msgid "Permanent block list" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:29 +msgid "Logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:33 +msgid "Premium upgrade" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:131 +#: admin/wp-security-dashboard-menu.php:518 +#: admin/wp-security-user-login-menu.php:53 +#: classes/grade-system/wp-security-feature-item-manager.php:49 +msgid "Login lockout" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:132 +msgid "This tab displays the list of all IP addresses which are currently temporarily locked out due to the login lockout feature:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:138 +msgid "Currently locked out IP addresses and ranges" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:183 +msgid "This tab displays the list of all permanently blocked IP addresses." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:184 +#: admin/wp-security-spam-menu.php:339 +msgid "NOTE: This feature does NOT use the .htaccess file to permanently block the IP addresses so it should be compatible with all web servers running WordPress." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:189 +msgid "Permanently blocked IP addresses" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:200 +#: admin/wp-security-firewall-menu.php:1151 +#: admin/wp-security-user-login-menu.php:485 +#: admin/wp-security-user-login-menu.php:643 +#: admin/wp-security-user-registration-menu.php:164 +msgid "Search" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:238 +#: admin/wp-security-dashboard-menu.php:249 +#: admin/wp-security-dashboard-menu.php:260 +msgid "All In One WP Security & Firewall" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:250 +msgid "Debug logs have been cleared." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:261 +msgid "Unable to clear the logs; an invalid nonce was provided" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:274 +msgid "Debug log options" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:281 +msgid "Clear logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:289 +msgid "Debug logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:362 +msgid "Security strength meter" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:363 +msgid "Security points breakdown" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:364 +msgid "Spread the word" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:365 +msgid "Get to know the developers" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:366 +msgid "Critical feature status" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:367 +msgid "Last 5 logins" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:368 +msgid "Maintenance mode status" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:373 +#: admin/wp-security-dashboard-menu.php:664 +#: admin/wp-security-user-login-menu.php:57 +msgid "Logged in users" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:417 +msgid "Total Achievable Points: " +msgstr "" + +#: admin/wp-security-dashboard-menu.php:419 +msgid "Current Score of Your Site: " +msgstr "" + +#: admin/wp-security-dashboard-menu.php:472 +msgid "We are working hard to make your WordPress site more secure. Please support us, here is how:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:473 +msgid "Follow us on" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:477 +msgid "Post to Twitter" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:481 +msgid "Give us a good rating" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:488 +msgid "Wanna know more about the developers behind this plugin?" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:499 +msgid "Below is the current status of the critical features that you should activate on your site to achieve a minimum level of recommended security" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:503 +msgid "Admin username" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:533 +msgid "File permission" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:548 +msgid "Basic firewall" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:577 +msgid "No data found." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:581 +msgid "Last 5 logins summary:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:585 +msgid "User" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:586 +#: admin/wp-security-list-404.php:95 +#: admin/wp-security-list-login-fails.php:56 +#: admin/wp-security-list-permanent-blocked-ip.php:68 +msgid "Date" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:587 +msgid "IP" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:608 +msgid "Maintenance mode is currently enabled. Remember to turn it off when you are done" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:610 +msgid "Maintenance mode is currently off." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:614 +msgid "Maintenance mode" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:632 +msgid "Cookie based brute force" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:636 +#: admin/wp-security-dashboard-menu.php:654 +msgid "The %s feature is currently active." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:637 +#: admin/wp-security-dashboard-menu.php:655 +msgid "Your new WordPress login URL is now:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:666 +msgid "Number of users currently logged into your site (including you) is:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:667 +msgid "There are no other users currently logged in." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:680 +msgid "Number of users currently logged in site-wide (including you) is:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:681 +msgid "There are no other site-wide users currently logged in." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:694 +#: admin/wp-security-dashboard-menu.php:711 +msgid "Go to the %s menu to see more details" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:707 +msgid "There are no IP addresses currently locked out." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:710 +msgid "Number of temporarily locked out IP addresses: " +msgstr "" + +#: admin/wp-security-database-menu.php:52 +msgid "UpdraftPlus is installed but currently not active." +msgstr "" + +#: admin/wp-security-database-menu.php:52 +msgid "Follow this link to activate UpdraftPlus, to take a backup." +msgstr "" + +#: admin/wp-security-database-menu.php:57 +msgid "Follow this link to install UpdraftPlus, to take a database backup." +msgstr "" + +#: admin/wp-security-database-menu.php:87 +#: admin/wp-security-database-menu.php:92 +msgid "Database backup" +msgstr "" + +#: admin/wp-security-database-menu.php:91 +#: classes/grade-system/wp-security-feature-item-manager.php:65 +msgid "Database prefix" +msgstr "" + +#: admin/wp-security-database-menu.php:119 +msgid "Database security" +msgstr "" + +#: admin/wp-security-database-menu.php:147 +msgid "Nonce check failed for DB prefix change operation!" +msgstr "" + +#: admin/wp-security-database-menu.php:155 +msgid "The plugin has detected that it cannot write to the wp-config.php file. This feature can only be used if the plugin can successfully write to the wp-config.php file." +msgstr "" + +#: admin/wp-security-database-menu.php:168 +msgid "Please enter a value for the DB prefix." +msgstr "" + +#: admin/wp-security-database-menu.php:177 +msgid "ERROR: The table prefix can only contain numbers, letters, and underscores." +msgstr "" + +#: admin/wp-security-database-menu.php:186 +#: admin/wp-security-database-menu.php:245 +msgid "Change database prefix" +msgstr "" + +#: admin/wp-security-database-menu.php:189 +msgid "Your WordPress database is the most important asset of your website because it contains a lot of your site's precious information." +msgstr "" + +#: admin/wp-security-database-menu.php:190 +msgid "The database is also a target for hackers via methods such as SQL injections and malicious and automated code which targets certain tables." +msgstr "" + +#: admin/wp-security-database-menu.php:191 +msgid "One way to add a layer of protection for your DB is to change the default WordPress table prefix from \"wp_\" to something else which will be difficult for hackers to guess." +msgstr "" + +#: admin/wp-security-database-menu.php:192 +msgid "This feature allows you to easily change the prefix to a value of your choice or to a random value set by this plugin." +msgstr "" + +#: admin/wp-security-database-menu.php:198 +msgid "Database prefix options" +msgstr "" + +#: admin/wp-security-database-menu.php:210 +msgid "database backup" +msgstr "" + +#: admin/wp-security-database-menu.php:211 +msgid "It is recommended that you perform a %s before using this feature" +msgstr "" + +#: admin/wp-security-database-menu.php:221 +msgid "Current database table prefix" +msgstr "" + +#: admin/wp-security-database-menu.php:227 +msgid "Your site is currently using the default WordPress database prefix value of \"wp_\"." +msgstr "" + +#: admin/wp-security-database-menu.php:227 +msgid "To increase your site's security you should consider changing the database prefix value to another value." +msgstr "" + +#: admin/wp-security-database-menu.php:234 +msgid "Generate new database table prefix" +msgstr "" + +#: admin/wp-security-database-menu.php:238 +msgid "Check this if you want the plugin to generate a random 6 character string for the table prefix" +msgstr "" + +#: admin/wp-security-database-menu.php:239 +msgid "OR" +msgstr "" + +#: admin/wp-security-database-menu.php:241 +msgid "Choose your own database prefix by specifying a string which contains letters and/or numbers and/or underscores. Example: xyz_" +msgstr "" + +#: admin/wp-security-database-menu.php:265 +msgid "Take a database backup using UpdraftPlus" +msgstr "" + +#: admin/wp-security-database-menu.php:270 +msgid "Manual backup" +msgstr "" + +#: admin/wp-security-database-menu.php:274 +msgid "UpdraftPlus Backup/Restore" +msgstr "" + +#: admin/wp-security-database-menu.php:274 +msgid "Your backups are on the UpdraftPlus Backup/Restore admin page." +msgstr "" + +#: admin/wp-security-database-menu.php:276 +msgid "Create database backup now" +msgstr "" + +#: admin/wp-security-database-menu.php:308 +msgid "Error - Could not get tables or no tables found!" +msgstr "" + +#: admin/wp-security-database-menu.php:312 +msgid "Starting DB prefix change operations....." +msgstr "" + +#: admin/wp-security-database-menu.php:314 +msgid "Your WordPress system has a total of %s tables and your new DB prefix will be: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:320 +#: classes/wp-security-utility.php:306 +msgid "Failed to make a backup of the wp-config.php file. This operation will not go ahead." +msgstr "" + +#: admin/wp-security-database-menu.php:324 +msgid "A backup copy of your wp-config.php file was created successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:351 +msgid "%s table name update failed" +msgstr "" + +#: admin/wp-security-database-menu.php:363 +msgid "Please change the prefix manually for the above tables to: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:366 +msgid "%s tables had their prefix updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:387 +msgid "wp-config.php file was updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:390 +msgid "The \"wp-config.php\" file was not able to be modified." +msgstr "" + +#: admin/wp-security-database-menu.php:390 +msgid "Please modify this file manually using your favourite editor and search for variable \"$table_prefix\" and assign the following value to that variable: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:401 +#: admin/wp-security-database-menu.php:420 +msgid "Update of table %s failed: unable to change %s to %s" +msgstr "" + +#: admin/wp-security-database-menu.php:405 +msgid "The options table records which had references to the old DB prefix were updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:424 +msgid "The %s table records which had references to the old DB prefix were updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:452 +msgid "Error updating user_meta table where new meta_key = %s, old meta_key = %s and user_id = %s." +msgstr "" + +#: admin/wp-security-database-menu.php:457 +msgid "The usermeta table records which had references to the old DB prefix were updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:459 +msgid "The database prefix change tasks have been completed." +msgstr "" + +#: admin/wp-security-database-menu.php:503 +msgid "Checking for MySQL tables of type \"view\"....." +msgstr "" + +#: admin/wp-security-database-menu.php:520 +msgid "Update of the following MySQL view definition failed: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:527 +msgid "%s view definitions were updated successfully!" +msgstr "" + +#: admin/wp-security-filescan-menu.php:26 +#: classes/grade-system/wp-security-feature-item-manager.php:127 +msgid "File change detection" +msgstr "" + +#: admin/wp-security-filescan-menu.php:27 +msgid "Malware scan" +msgstr "" + +#: admin/wp-security-filescan-menu.php:88 +msgid "There have been no file changes since the last scan." +msgstr "" + +#: admin/wp-security-filescan-menu.php:98 +msgid "Nonce check failed for manual file change detection scan operation!" +msgstr "" + +#: admin/wp-security-filescan-menu.php:104 +msgid "There was an error during the file change detection scan. Please check the AIOS logs." +msgstr "" + +#: admin/wp-security-filescan-menu.php:110 +msgid "The plugin has detected that this is your first file change detection scan. The file details from this scan will be used to detect file changes for future scans." +msgstr "" + +#: admin/wp-security-filescan-menu.php:112 +msgid "Scan complete - There were no file changes detected!" +msgstr "" + +#: admin/wp-security-filescan-menu.php:133 +msgid "You entered a non numeric value for the \"backup time interval\" field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-filescan-menu.php:167 +msgid "The following address was removed because it is not a valid email address: " +msgstr "" + +#: admin/wp-security-filescan-menu.php:206 +msgid "NEW SCAN COMPLETED: The plugin has detected that you have made changes to the \"File Types To Ignore\" or \"Files To Ignore\" fields." +msgstr "" + +#: admin/wp-security-filescan-menu.php:206 +msgid "In order to ensure that future scan results are accurate, the old scan data has been refreshed." +msgstr "" + +#: admin/wp-security-filescan-menu.php:215 +msgid "All In One WP Security & Firewall has detected that there was a change in your host's files." +msgstr "" + +#: admin/wp-security-filescan-menu.php:217 +msgid "View scan details and clear this message" +msgstr "" + +#: admin/wp-security-filescan-menu.php:226 +msgid "If given an opportunity hackers can insert their code or files into your system which they can then use to carry out malicious acts on your site." +msgstr "" + +#: admin/wp-security-filescan-menu.php:227 +msgid "Being informed of any changes in your files can be a good way to quickly prevent a hacker from causing damage to your website." +msgstr "" + +#: admin/wp-security-filescan-menu.php:228 +msgid "In general, WordPress core and plugin files and file types such as \".php\" or \".js\" should not change often and when they do, it is important that you are made aware when a change occurs and which file was affected." +msgstr "" + +#: admin/wp-security-filescan-menu.php:229 +msgid "The \"File Change Detection Feature\" will notify you of any file change which occurs on your system, including the addition and deletion of files by performing a regular automated or manual scan of your system's files." +msgstr "" + +#: admin/wp-security-filescan-menu.php:230 +msgid "This feature also allows you to exclude certain files or folders from the scan in cases where you know that they change often as part of their normal operation. (For example log files and certain caching plugin files may change often and hence you may choose to exclude such files from the file change detection scan)" +msgstr "" + +#: admin/wp-security-filescan-menu.php:241 +msgid "It appears that your server is using an old PHP version which is missing the %s. The file scanner feature needs this class in order to work. If you would like to use this feature please upgrade your server PHP version to 5.3 or greater." +msgstr "" + +#: admin/wp-security-filescan-menu.php:249 +msgid "Manual file change detection scan" +msgstr "" + +#: admin/wp-security-filescan-menu.php:255 +msgid "To perform a manual file change detection scan click on the button below." +msgstr "" + +#: admin/wp-security-filescan-menu.php:258 +msgid "Perform scan now" +msgstr "" + +#: admin/wp-security-filescan-menu.php:262 +msgid "View last saved file change results" +msgstr "" + +#: admin/wp-security-filescan-menu.php:268 +msgid "Click the button below to view the saved file change results from the last scan." +msgstr "" + +#: admin/wp-security-filescan-menu.php:271 +msgid "View last file change" +msgstr "" + +#: admin/wp-security-filescan-menu.php:275 +msgid "File change detection settings" +msgstr "" + +#: admin/wp-security-filescan-menu.php:287 +msgid "Enable automated file change detection scan" +msgstr "" + +#: admin/wp-security-filescan-menu.php:290 +msgid "Check this if you want the system to automatically/periodically scan your files to check for file changes based on the settings below" +msgstr "" + +#: admin/wp-security-filescan-menu.php:294 +msgid "Scan time interval" +msgstr "" + +#: admin/wp-security-filescan-menu.php:297 +msgid "Hours" +msgstr "" + +#: admin/wp-security-filescan-menu.php:298 +msgid "Days" +msgstr "" + +#: admin/wp-security-filescan-menu.php:299 +msgid "Weeks" +msgstr "" + +#: admin/wp-security-filescan-menu.php:301 +msgid "Set the value for how often you would like a scan to occur" +msgstr "" + +#: admin/wp-security-filescan-menu.php:305 +msgid "File types to ignore" +msgstr "" + +#: admin/wp-security-filescan-menu.php:308 +msgid "Enter each file type or extension on a new line which you wish to exclude from the file change detection scan." +msgstr "" + +#: admin/wp-security-filescan-menu.php:312 +msgid "You can exclude file types from the scan which would not normally pose any security threat if they were changed. These can include things such as image files." +msgstr "" + +#: admin/wp-security-filescan-menu.php:313 +msgid "Example: If you want the scanner to ignore files of type jpg, png, and bmp, then you would enter the following:" +msgstr "" + +#: admin/wp-security-filescan-menu.php:314 +msgid "jpg" +msgstr "" + +#: admin/wp-security-filescan-menu.php:315 +msgid "png" +msgstr "" + +#: admin/wp-security-filescan-menu.php:316 +msgid "bmp" +msgstr "" + +#: admin/wp-security-filescan-menu.php:322 +msgid "Files/Directories to ignore" +msgstr "" + +#: admin/wp-security-filescan-menu.php:325 +msgid "Enter each file or directory on a new line which you wish to exclude from the file change detection scan." +msgstr "" + +#: admin/wp-security-filescan-menu.php:329 +msgid "You can exclude specific files/directories from the scan which would not normally pose any security threat if they were changed. These can include things such as log files." +msgstr "" + +#: admin/wp-security-filescan-menu.php:330 +msgid "Example: If you want the scanner to ignore certain files in different directories or whole directories, then you would enter the following:" +msgstr "" + +#: admin/wp-security-filescan-menu.php:331 +msgid "cache/config/master.php" +msgstr "" + +#: admin/wp-security-filescan-menu.php:332 +msgid "somedirectory" +msgstr "" + +#: admin/wp-security-filescan-menu.php:339 +msgid "Send email when change detected" +msgstr "" + +#: admin/wp-security-filescan-menu.php:343 +msgid "Check this if you want the system to email you if a file change was detected" +msgstr "" + +#: admin/wp-security-filescan-menu.php:347 +msgid "Enter one or more email addresses on a new line." +msgstr "" + +#: admin/wp-security-filescan-menu.php:364 +msgid "What is malware?" +msgstr "" + +#: admin/wp-security-filescan-menu.php:365 +msgid "The word malware stands for Malicious Software. It can consist of things like trojan horses, adware, worms, spyware and any other undesirable code which a hacker will try to inject into your website." +msgstr "" + +#: admin/wp-security-filescan-menu.php:366 +msgid "Often when malware code has been inserted into your site you will normally not notice anything out of the ordinary based on appearances, but it can have a dramatic effect on your site's search ranking." +msgstr "" + +#: admin/wp-security-filescan-menu.php:367 +msgid "This is because the bots and spiders from search engines such as Google have the capability to detect malware when they are indexing the pages on your site, and consequently they can blacklist your website which will in turn affect your search rankings." +msgstr "" + +#: admin/wp-security-filescan-menu.php:369 +msgid "CLICK HERE" +msgstr "" + +#: admin/wp-security-filescan-menu.php:371 +msgid "Scanning for malware" +msgstr "" + +#: admin/wp-security-filescan-menu.php:372 +msgid "Due to the constantly changing and complex nature of Malware, scanning for such things using a standalone plugin will not work reliably. This is something best done via an external scan of your site regularly." +msgstr "" + +#: admin/wp-security-filescan-menu.php:373 +msgid "This is why we have created an easy-to-use scanning service which is hosted off our own server which will scan your site for malware once every day and notify you if it finds anything." +msgstr "" + +#: admin/wp-security-filescan-menu.php:374 +msgid "When you sign up for this service you will get the following:" +msgstr "" + +#: admin/wp-security-filescan-menu.php:376 +msgid "Automatic daily scan of 1 website" +msgstr "" + +#: admin/wp-security-filescan-menu.php:377 +msgid "Automatic malware and blacklist monitoring" +msgstr "" + +#: admin/wp-security-filescan-menu.php:378 +msgid "Automatic email alerting" +msgstr "" + +#: admin/wp-security-filescan-menu.php:379 +msgid "Site uptime monitoring" +msgstr "" + +#: admin/wp-security-filescan-menu.php:380 +msgid "Site response time monitoring" +msgstr "" + +#: admin/wp-security-filescan-menu.php:381 +msgid "We provide advice for malware cleanup" +msgstr "" + +#: admin/wp-security-filescan-menu.php:382 +msgid "Blacklist removal" +msgstr "" + +#: admin/wp-security-filescan-menu.php:383 +msgid "No contract (cancel anytime)" +msgstr "" + +#: admin/wp-security-filescan-menu.php:385 +msgid "To learn more please %s." +msgstr "" + +#: admin/wp-security-filescan-menu.php:406 +msgid "Latest file change scan results" +msgstr "" + +#: admin/wp-security-filescan-menu.php:416 +msgid "The following files were added to your host." +msgstr "" + +#: admin/wp-security-filescan-menu.php:419 +#: admin/wp-security-filescan-menu.php:440 +#: admin/wp-security-filescan-menu.php:464 +msgid "File" +msgstr "" + +#: admin/wp-security-filescan-menu.php:420 +#: admin/wp-security-filescan-menu.php:441 +#: admin/wp-security-filescan-menu.php:465 +msgid "File size" +msgstr "" + +#: admin/wp-security-filescan-menu.php:421 +#: admin/wp-security-filescan-menu.php:442 +#: admin/wp-security-filescan-menu.php:466 +msgid "File modified" +msgstr "" + +#: admin/wp-security-filescan-menu.php:437 +msgid "The following files were removed from your host." +msgstr "" + +#: admin/wp-security-filescan-menu.php:461 +msgid "The following files were changed on your host." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:26 +#: classes/grade-system/wp-security-feature-item-manager.php:69 +msgid "File permissions" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:27 +msgid "PHP file editing" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:28 +msgid "WP file access" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:29 +msgid "Host system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:55 +msgid "Filesystem security" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:80 +msgid "Nonce check failed for manual DB backup operation!" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:90 +msgid "The permissions for %s were successfully changed to %s" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:94 +msgid "Unable to change permissions for %s!" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:100 +msgid "File permissions scan" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:103 +msgid "Your WordPress file and folder permission settings govern the accessibility and read/write privileges of the files and folders which make up your WP installation." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:104 +msgid "Your WP installation already comes with reasonably secure file permission settings for the filesystem." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:105 +msgid "However, sometimes people or other plugins modify the various permission settings of certain core WP folders or files such that they end up making their site less secure because they chose the wrong permission values." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:106 +msgid "This feature will scan the critical WP core folders and files and will highlight any permission settings which are insecure." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:114 +msgid "This plugin has detected that your site is running on a Windows server." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:115 +msgid "This feature is not applicable for Windows server installations." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:121 +msgid "WP directory and file permissions scan results" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:133 +#: admin/wp-security-filesystem-menu.php:152 +msgid "Name" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:134 +#: admin/wp-security-filesystem-menu.php:153 +msgid "File/Folder" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:135 +#: admin/wp-security-filesystem-menu.php:154 +msgid "Current permissions" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:136 +#: admin/wp-security-filesystem-menu.php:155 +msgid "Recommended permissions" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:137 +#: admin/wp-security-filesystem-menu.php:156 +msgid "Recommended action" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:195 +msgid "Your PHP file editing settings were saved successfully." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:199 +msgid "Operation failed! Unable to modify or make a backup of wp-config.php file!" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:212 +#: classes/grade-system/wp-security-feature-item-manager.php:71 +msgid "File editing" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:215 +msgid "The WordPress Dashboard by default allows administrators to edit PHP files, such as plugin and theme files." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:216 +msgid "This is often the first tool an attacker will use if able to login, since it allows code execution." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:217 +msgid "This feature will disable the ability for people to edit PHP files via the dashboard." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:223 +msgid "Disable PHP file editing" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:235 +msgid "Disable ability to edit PHP files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:238 +msgid "Check this if you want to remove the ability for people to edit PHP files via the WP dashboard" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:282 +msgid "You have successfully saved the Prevent Access to Default WP Files configuration." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:286 +#: admin/wp-security-firewall-menu.php:126 +#: admin/wp-security-firewall-menu.php:346 +#: admin/wp-security-firewall-menu.php:613 +#: admin/wp-security-firewall-menu.php:912 +#: admin/wp-security-settings-menu.php:772 +#: admin/wp-security-spam-menu.php:124 +msgid "Could not write to the .htaccess file. Please check the file permissions." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:291 +msgid "WordPress files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:294 +msgid "This feature allows you to prevent access to files such as %s, %s and %s which are delivered with all WP installations." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:295 +msgid "By preventing access to these files you are hiding some key pieces of information (such as WordPress version info) from potential hackers." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:300 +msgid "Prevent access to default WP files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:311 +msgid "Prevent access to WP default install files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:314 +msgid "Check this if you want to prevent access to readme.html, license.txt and wp-config-sample.php." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:318 +msgid "Save setting" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:342 +msgid "System logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:345 +msgid "Sometimes your hosting platform will produce error or warning logs in a file called \"error_log\"." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:346 +msgid "Depending on the nature and cause of the error or warning, your hosting server can create multiple instances of this file in numerous directory locations of your WordPress installation." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:347 +msgid "By occasionally viewing the contents of these logs files you can keep informed of any underlying problems on your system which you might need to address." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:353 +msgid "View system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:355 +msgid "Please click the button below to view the latest system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:358 +msgid "Enter System Log File Name" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:360 +msgid "Enter your system log file name. (Defaults to error_log)" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:363 +msgid "View latest system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:365 +msgid "Loading..." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:382 +msgid "No system logs were found." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:435 +msgid "Set recommended permissions" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:441 +msgid "No action required" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:481 +msgid "Showing latest entries of error_log file: %s" +msgstr "" + +#: admin/wp-security-firewall-menu.php:28 +msgid "Basic firewall rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:29 +msgid "Additional firewall rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:30 +msgid "6G Blacklist firewall rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:31 +msgid "Internet bots" +msgstr "" + +#: admin/wp-security-firewall-menu.php:32 +msgid "Prevent hotlinks" +msgstr "" + +#: admin/wp-security-firewall-menu.php:33 +msgid "404 detection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:34 +msgid "Custom rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:122 +#: admin/wp-security-firewall-menu.php:908 +#: admin/wp-security-spam-menu.php:120 +#: admin/wp-security-spam-menu.php:494 +#: admin/wp-security-spam-menu.php:556 +#: admin/wp-security-user-registration-menu.php:95 +msgid "Settings were successfully saved" +msgstr "" + +#: admin/wp-security-firewall-menu.php:131 +#: admin/wp-security-firewall-menu.php:651 +msgid "Firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:138 +msgid "This should not have any impact on your site's general functionality but if you wish you can take a %s of your .htaccess file before proceeding." +msgstr "" + +#: admin/wp-security-firewall-menu.php:139 +msgid "The features in this tab allow you to activate some basic firewall security protection rules for your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:140 +msgid "The firewall functionality is achieved via the insertion of special code into your currently active .htaccess file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:151 +msgid "You have enabled the \"Completely Block Access To XMLRPC\" checkbox which means all XMLRPC functionality will be blocked." +msgstr "" + +#: admin/wp-security-firewall-menu.php:152 +msgid "By leaving this feature enabled you will prevent Jetpack or Wordpress iOS or other apps which need XMLRPC from working correctly on your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:153 +msgid "If you still need XMLRPC then uncheck the \"Completely Block Access To XMLRPC\" checkbox and enable only the \"Disable Pingback Functionality From XMLRPC\" checkbox." +msgstr "" + +#: admin/wp-security-firewall-menu.php:163 +msgid "Basic firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:171 +msgid "Enable basic firewall protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:174 +msgid "Check this if you want to apply basic firewall protection to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:178 +msgid "This setting will implement the following basic firewall protection mechanisms on your site:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:179 +msgid "1) Protect your htaccess file by denying access to it." +msgstr "" + +#: admin/wp-security-firewall-menu.php:180 +msgid "2) Disable the server signature." +msgstr "" + +#: admin/wp-security-firewall-menu.php:181 +msgid "3) Limit file upload size (%sMB)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:182 +msgid "4) Protect your wp-config.php file by denying access to it." +msgstr "" + +#: admin/wp-security-firewall-menu.php:183 +msgid "The above firewall features will be applied via your .htaccess file and should not affect your site's overall functionality." +msgstr "" + +#: admin/wp-security-firewall-menu.php:184 +msgid "You are still advised to take a backup of your active .htaccess file just in case." +msgstr "" + +#: admin/wp-security-firewall-menu.php:190 +msgid "Max file upload size (MB)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:192 +msgid "The value for the maximum file upload size used in the .htaccess file. (Defaults to %sMB if left blank)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:200 +msgid "WordPress XMLRPC and pingback vulnerability protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:208 +msgid "Completely block access to XMLRPC" +msgstr "" + +#: admin/wp-security-firewall-menu.php:211 +msgid "Check this if you are not using the WP XML-RPC functionality and you want to completely block external access to XMLRPC." +msgstr "" + +#: admin/wp-security-firewall-menu.php:215 +msgid "This setting will add a directive in your .htaccess to disable access to the WordPress xmlrpc.php file which is responsible for the XML-RPC functionality in WordPress." +msgstr "" + +#: admin/wp-security-firewall-menu.php:216 +msgid "Hackers can exploit various vulnerabilities in the WordPress XML-RPC API in a number of ways such as:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:217 +msgid "1) Denial of Service (DoS) attacks" +msgstr "" + +#: admin/wp-security-firewall-menu.php:218 +msgid "2) Hacking internal routers." +msgstr "" + +#: admin/wp-security-firewall-menu.php:219 +msgid "3) Scanning ports in internal networks to get info from various hosts." +msgstr "" + +#: admin/wp-security-firewall-menu.php:220 +msgid "Apart from the security protection benefit, this feature may also help reduce load on your server, particularly if your site currently has a lot of unwanted traffic hitting the XML-RPC API on your installation." +msgstr "" + +#: admin/wp-security-firewall-menu.php:221 +msgid "NOTE: You should only enable this feature if you are not currently using the XML-RPC functionality on your WordPress installation." +msgstr "" + +#: admin/wp-security-firewall-menu.php:222 +msgid "Leave this feature disabled and use the feature below if you want pingback protection but you still need XMLRPC." +msgstr "" + +#: admin/wp-security-firewall-menu.php:228 +msgid "Disable pingback functionality from XMLRPC" +msgstr "" + +#: admin/wp-security-firewall-menu.php:231 +msgid "If you use Jetpack or WP iOS or other apps which need WP XML-RPC functionality then check this. This will enable protection against WordPress pingback vulnerabilities." +msgstr "" + +#: admin/wp-security-firewall-menu.php:235 +msgid "NOTE: If you use Jetpack or the Wordpress iOS or other apps then you should enable this feature but leave the \"Completely Block Access To XMLRPC\" checkbox unchecked." +msgstr "" + +#: admin/wp-security-firewall-menu.php:236 +msgid "The feature will still allow XMLRPC functionality on your site but will disable the pingback methods." +msgstr "" + +#: admin/wp-security-firewall-menu.php:237 +msgid "This feature will also remove the \"X-Pingback\" header if it is present." +msgstr "" + +#: admin/wp-security-firewall-menu.php:246 +msgid "Block access to debug log file" +msgstr "" + +#: admin/wp-security-firewall-menu.php:254 +msgid "Block access to debug.log file" +msgstr "" + +#: admin/wp-security-firewall-menu.php:257 +msgid "Check this if you want to block access to the debug.log file that WordPress creates when debug logging is enabled." +msgstr "" + +#: admin/wp-security-firewall-menu.php:261 +msgid "WordPress has an option to turn on the debug logging to a file located in wp-content/debug.log. This file may contain sensitive information." +msgstr "" + +#: admin/wp-security-firewall-menu.php:262 +msgid "Using this option will block external access to this file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:262 +msgid "You can still access this file by logging into your site via FTP." +msgstr "" + +#: admin/wp-security-firewall-menu.php:270 +msgid "Save basic firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:342 +msgid "You have successfully saved the Additional Firewall Protection configuration" +msgstr "" + +#: admin/wp-security-firewall-menu.php:356 +msgid "Additional firewall protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:360 +msgid "Due to the nature of the code being inserted to the .htaccess file, this feature may break some functionality for certain plugins and you are therefore advised to take a %s of .htaccess before applying this configuration." +msgstr "" + +#: admin/wp-security-firewall-menu.php:362 +msgid "This feature allows you to activate more advanced firewall settings to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:363 +msgid "The advanced firewall rules are applied via the insertion of special code to your currently active .htaccess file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:372 +msgid "Listing of directory contents" +msgstr "" + +#: admin/wp-security-firewall-menu.php:381 +#: classes/grade-system/wp-security-feature-item-manager.php:85 +msgid "Disable index views" +msgstr "" + +#: admin/wp-security-firewall-menu.php:384 +msgid "Check this if you want to disable directory and file listing." +msgstr "" + +#: admin/wp-security-firewall-menu.php:389 +msgid "By default, an Apache server will allow the listing of the contents of a directory if it doesn't contain an index.php file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:391 +msgid "This feature will prevent the listing of contents for all directories." +msgstr "" + +#: admin/wp-security-firewall-menu.php:393 +msgid "NOTE: In order for this feature to work \"AllowOverride\" of the Indexes directive must be enabled in your httpd.conf file. Ask your hosting provider to check this if you don't have access to httpd.conf" +msgstr "" + +#: admin/wp-security-firewall-menu.php:402 +msgid "Trace and track" +msgstr "" + +#: admin/wp-security-firewall-menu.php:411 +#: classes/grade-system/wp-security-feature-item-manager.php:86 +msgid "Disable trace and track" +msgstr "" + +#: admin/wp-security-firewall-menu.php:414 +msgid "Check this if you want to disable trace and track." +msgstr "" + +#: admin/wp-security-firewall-menu.php:419 +msgid "HTTP Trace attack (XST) can be used to return header requests and grab cookies and other information." +msgstr "" + +#: admin/wp-security-firewall-menu.php:421 +msgid "This hacking technique is usually used together with cross site scripting attacks (XSS)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:423 +msgid "Disabling trace and track on your site will help prevent HTTP Trace attacks." +msgstr "" + +#: admin/wp-security-firewall-menu.php:432 +msgid "Proxy comment posting" +msgstr "" + +#: admin/wp-security-firewall-menu.php:442 +msgid "Forbid proxy comment posting" +msgstr "" + +#: admin/wp-security-firewall-menu.php:445 +msgid "Check this if you want to forbid proxy comment posting." +msgstr "" + +#: admin/wp-security-firewall-menu.php:450 +msgid "This setting will deny any requests that use a proxy server when posting comments." +msgstr "" + +#: admin/wp-security-firewall-menu.php:451 +msgid "By forbidding proxy comments you are in effect eliminating some spam and other proxy requests." +msgstr "" + +#: admin/wp-security-firewall-menu.php:460 +msgid "Bad query strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:470 +msgid "Deny bad query strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:473 +msgid "This will help protect you against malicious queries via XSS." +msgstr "" + +#: admin/wp-security-firewall-menu.php:478 +msgid "This feature will write rules in your .htaccess file to prevent malicious string attacks on your site using XSS." +msgstr "" + +#: admin/wp-security-firewall-menu.php:479 +msgid "NOTE: Some of these strings might be used for plugins or themes and hence this might break some functionality." +msgstr "" + +#: admin/wp-security-firewall-menu.php:480 +#: admin/wp-security-firewall-menu.php:510 +msgid "You are therefore strongly advised to take a backup of your active .htaccess file before applying this feature." +msgstr "" + +#: admin/wp-security-firewall-menu.php:489 +#: classes/grade-system/wp-security-feature-item-manager.php:89 +msgid "Advanced character string filter" +msgstr "" + +#: admin/wp-security-firewall-menu.php:499 +msgid "Enable advanced character string filter" +msgstr "" + +#: admin/wp-security-firewall-menu.php:502 +msgid "This will block bad character matches from XSS." +msgstr "" + +#: admin/wp-security-firewall-menu.php:507 +msgid "This is an advanced character string filter to prevent malicious string attacks on your site coming from Cross Site Scripting (XSS)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:508 +msgid "This setting matches for common malicious string patterns and exploits and will produce a 403 error for the hacker attempting the query." +msgstr "" + +#: admin/wp-security-firewall-menu.php:509 +msgid "NOTE: Some strings for this setting might break some functionality." +msgstr "" + +#: admin/wp-security-firewall-menu.php:518 +msgid "Save additional firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:609 +msgid "You have successfully saved the 5G/6G Firewall Protection configuration" +msgstr "" + +#: admin/wp-security-firewall-menu.php:633 +msgid "All in One WP Security and Firewall" +msgstr "" + +#: admin/wp-security-firewall-menu.php:634 +msgid "We were unable to access the firewall's configuration file:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:636 +msgid "As a result, the firewall will be unavailable." +msgstr "" + +#: admin/wp-security-firewall-menu.php:637 +msgid "Please check your PHP error log for further information." +msgstr "" + +#: admin/wp-security-firewall-menu.php:638 +msgid "If you're unable to locate your PHP log file, please contact your web hosting company to ask them where it can be found on their setup." +msgstr "" + +#: admin/wp-security-firewall-menu.php:655 +msgid "This feature allows you to activate the %s (or legacy %s) firewall security protection rules designed and produced by %s." +msgstr "" + +#: admin/wp-security-firewall-menu.php:656 +msgid "The 6G Blacklist is updated and improved version of 5G Blacklist. If you have 5G Blacklist active, you might consider activating 6G Blacklist instead." +msgstr "" + +#: admin/wp-security-firewall-menu.php:657 +msgid "The 6G Blacklist is a simple, flexible blacklist that helps reduce the number of malicious URL requests that hit your website." +msgstr "" + +#: admin/wp-security-firewall-menu.php:658 +msgid "The added advantage of applying the 6G firewall to your site is that it has been tested and confirmed by the people at PerishablePress.com to be an optimal and least disruptive set of .htaccess security rules for general WP sites running on an Apache server or similar." +msgstr "" + +#: admin/wp-security-firewall-menu.php:659 +msgid "Therefore the 6G firewall rules should not have any impact on your site's general functionality but if you wish you can take a %s of your .htaccess file before proceeding." +msgstr "" + +#: admin/wp-security-firewall-menu.php:665 +msgid "6G blacklist/firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:677 +msgid "Enable 6G firewall protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:680 +msgid "Check this if you want to apply the 6G Blacklist firewall protection from perishablepress.com to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:684 +msgid "This setting will implement the 6G security firewall protection mechanisms on your site which include the following things:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:685 +#: admin/wp-security-firewall-menu.php:703 +msgid "1) Block forbidden characters commonly used in exploitative attacks." +msgstr "" + +#: admin/wp-security-firewall-menu.php:686 +#: admin/wp-security-firewall-menu.php:704 +msgid "2) Block malicious encoded URL characters such as the \".css(\" string." +msgstr "" + +#: admin/wp-security-firewall-menu.php:687 +#: admin/wp-security-firewall-menu.php:705 +msgid "3) Guard against the common patterns and specific exploits in the root portion of targeted URLs." +msgstr "" + +#: admin/wp-security-firewall-menu.php:688 +#: admin/wp-security-firewall-menu.php:706 +msgid "4) Stop attackers from manipulating query strings by disallowing illicit characters." +msgstr "" + +#: admin/wp-security-firewall-menu.php:689 +#: admin/wp-security-firewall-menu.php:707 +msgid "....and much more." +msgstr "" + +#: admin/wp-security-firewall-menu.php:695 +msgid "Enable legacy 5G firewall protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:698 +msgid "Check this if you want to apply the 5G Blacklist firewall protection from perishablepress.com to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:702 +msgid "This setting will implement the 5G security firewall protection mechanisms on your site which include the following things:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:713 +msgid "Save 5G/6G firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:721 +msgid "6G block request methods" +msgstr "" + +#: admin/wp-security-firewall-menu.php:725 +msgid "HTTP Request methods are used by browsers and clients to communicate with servers to get responses." +msgstr "" + +#: admin/wp-security-firewall-menu.php:726 +msgid "GET and POST are the most commonly used methods to request and submit data for specified resources of the server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:732 +msgid "Block %s method" +msgstr "" + +#: admin/wp-security-firewall-menu.php:735 +msgid "Check this to block the %s request method" +msgstr "" + +#: admin/wp-security-firewall-menu.php:740 +msgid "Some WooCommerce extensions use the PUT request method in addition to GET and POST." +msgstr "" + +#: admin/wp-security-firewall-menu.php:740 +msgid "This means WooCommerce users shouldn't block the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:741 +msgid "A few REST requests use the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:741 +msgid "If your site is communicated by the WP REST API, you should not block the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:749 +msgid "Save request methods settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:757 +msgid "6G other settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:761 +msgid "Block query strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:764 +msgid "Check this to block all query strings recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:768 +msgid "Block request strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:771 +msgid "Check this to block all request strings recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:775 +msgid "Block referrers" +msgstr "" + +#: admin/wp-security-firewall-menu.php:778 +msgid "Check this to block all referrers recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:782 +msgid "Block user-agents" +msgstr "" + +#: admin/wp-security-firewall-menu.php:785 +msgid "Check this to block all user-agents recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:789 +msgid "Save other settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:823 +msgid "The Internet bot settings were successfully saved" +msgstr "" + +#: admin/wp-security-firewall-menu.php:827 +msgid "Internet bot settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:833 +msgid "What is an Internet Bot" +msgstr "" + +#: admin/wp-security-firewall-menu.php:834 +msgid "%s?" +msgstr "" + +#: admin/wp-security-firewall-menu.php:836 +msgid "A bot is a piece of software which runs on the Internet and performs automatic tasks. For example when Google indexes your pages it uses automatic bots to achieve this task." +msgstr "" + +#: admin/wp-security-firewall-menu.php:837 +msgid "A lot of bots are legitimate and non-malicious but not all bots are good and often you will find some which try to impersonate legitimate bots such as \"Googlebot\" but in reality they have nohing to do with Google at all." +msgstr "" + +#: admin/wp-security-firewall-menu.php:838 +msgid "Although most of the bots out there are relatively harmless sometimes website owners want to have more control over which bots they allow into their site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:839 +msgid "This feature allows you to block bots which are impersonating as a Googlebot but actually aren't. (In other words they are fake Google bots)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:840 +msgid "Googlebots have a unique identity which cannot easily be forged and this feature will identify any fake Google bots and block them from reading your site's pages." +msgstr "" + +#: admin/wp-security-firewall-menu.php:846 +msgid "Attention: Sometimes non-malicious Internet organizations might have bots which impersonate as a \"Googlebot\"." +msgstr "" + +#: admin/wp-security-firewall-menu.php:847 +msgid "Just be aware that if you activate this feature the plugin will block all bots which use the \"Googlebot\" string in their User Agent information but are NOT officially from Google (irrespective whether they are malicious or not)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:848 +msgid "All other bots from other organizations such as \"Yahoo\", \"Bing\" etc will not be affected by this feature." +msgstr "" + +#: admin/wp-security-firewall-menu.php:854 +#: admin/wp-security-firewall-menu.php:864 +#: classes/grade-system/wp-security-feature-item-manager.php:93 +msgid "Block fake Googlebots" +msgstr "" + +#: admin/wp-security-firewall-menu.php:867 +msgid "Check this if you want to block all fake Googlebots." +msgstr "" + +#: admin/wp-security-firewall-menu.php:871 +msgid "This feature will check if the User Agent information of a bot contains the string \"Googlebot\"." +msgstr "" + +#: admin/wp-security-firewall-menu.php:872 +msgid "It will then perform a few tests to verify if the bot is legitimately from Google and if so it will allow the bot to proceed." +msgstr "" + +#: admin/wp-security-firewall-menu.php:873 +msgid "If the bot fails the checks then the plugin will mark it as being a fake Googlebot and it will block it" +msgstr "" + +#: admin/wp-security-firewall-menu.php:880 +msgid "Save internet bot settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:916 +#: admin/wp-security-firewall-menu.php:938 +#: classes/grade-system/wp-security-feature-item-manager.php:95 +msgid "Prevent image hotlinking" +msgstr "" + +#: admin/wp-security-firewall-menu.php:919 +msgid "A Hotlink is where someone displays an image on their site which is actually located on your site by using a direct link to the source of the image on your server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:920 +msgid "Due to the fact that the image being displayed on the other person's site is coming from your server, this can cause leaking of bandwidth and resources for you because your server has to present this image for the people viewing it on someone elses's site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:921 +msgid "This feature will prevent people from directly hotlinking images from your site's pages by writing some directives in your .htaccess file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:926 +msgid "Prevent hotlinking" +msgstr "" + +#: admin/wp-security-firewall-menu.php:941 +msgid "Check this if you want to prevent hotlinking to images on your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:961 +msgid "Nonce check failed for delete all 404 event logs operation!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:972 +msgid "404 Detection Feature - Delete all 404 event logs operation failed!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:976 +msgid "All 404 event logs were deleted from the DB successfully!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1000 +msgid "You entered a non numeric value for the lockout time length field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1006 +msgid "You entered an incorrect format for the \"Redirect URL\" field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1039 +msgid "404 detection configuration" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1042 +msgid "A 404 or Not Found error occurs when somebody tries to access a non-existent page on your website." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1043 +msgid "Typically, most 404 errors happen quite innocently when people have mis-typed a URL or used an old link to page which doesn't exist anymore." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1044 +msgid "However, in some cases you may find many repeated 404 errors which occur in a relatively short space of time and from the same IP address which are all attempting to access a variety of non-existent page URLs." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1045 +msgid "Such behaviour can mean that a hacker might be trying to find a particular page or URL for sinister reasons." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1046 +msgid "This feature allows you to monitor all 404 events which occur on your site, and it also gives you the option of blocking IP addresses for a configured length of time." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1047 +msgid "If you want to temporarily block or blacklist an IP address, simply click the \"Temp Block\" or \"Blacklist IP\" link for the applicable IP entry in the \"404 Event Logs\" table below." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1071 +msgid "404 detection options" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1083 +msgid "Enable 404 IP detection and lockout" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1086 +msgid "Check this if you want to enable the lockout of selected IP addresses." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1091 +msgid "When you enable this checkbox, all 404 events on your site will be logged in the table below. You can monitor these events and select some IP addresses listed in the table below and block them for a specified amount of time. All IP addresses you select to be blocked from the \"404 Event Logs\" table section will be unable to access your site during the time specified." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1099 +msgid "Enable 404 event logging" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1102 +msgid "Check this if you want to enable the logging of 404 events" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1107 +msgid "Time length of 404 lockout (minutes)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1109 +msgid "Set the length of time for which a blocked IP address will be prevented from visiting your site" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1114 +msgid "You can lock any IP address which is recorded in the \"404 Event Logs\" table section below." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1116 +msgid "To temporarily lock an IP address, hover over the ID column and click the \"Temp Block\" link for the applicable IP entry." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1123 +msgid "404 lockout redirect URL" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1125 +msgid "A blocked visitor will be automatically redirected to this URL." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1135 +msgid "This list displays the 404 event logs when somebody tries to access a non-existent page on your website." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1136 +msgid "404 event logs that are older than %1$d days are purged automatically." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1141 +msgid "404 event logs" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1163 +#: admin/wp-security-firewall-menu.php:1172 +#: admin/wp-security-user-login-menu.php:495 +#: admin/wp-security-user-login-menu.php:504 +#: admin/wp-security-user-login-menu.php:653 +#: admin/wp-security-user-login-menu.php:662 +msgid "Export to CSV" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1169 +#: admin/wp-security-user-login-menu.php:501 +#: admin/wp-security-user-login-menu.php:659 +msgid "Click this button if you wish to download this log in CSV format." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1176 +#: admin/wp-security-firewall-menu.php:1185 +msgid "Delete all 404 event logs" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1182 +msgid "Click this button if you wish to purge all 404 event logs from the DB." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1241 +msgid "Custom .htaccess rules settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1248 +msgid "This feature can be used to apply your own custom .htaccess rules and directives." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1249 +msgid "It is useful for when you want to tweak our existing firewall rules or when you want to add your own." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1250 +msgid "NOTE: This feature can only be used if your site is hosted in an apache or similar web server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1256 +msgid "Warning: Only use this feature if you know what you are doing." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1257 +msgid "Incorrect .htaccess rules or directives can break or prevent access to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1258 +msgid "It is your responsibility to ensure that you are entering the correct code!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1259 +msgid "If you break your site you will need to access your server via FTP or something similar and then edit your .htaccess file and delete the changes you made." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1265 +msgid "Custom .htaccess rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1269 +msgid "Enable custom .htaccess rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1272 +msgid "Check this if you want to enable custom rules entered in the text box below" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1276 +msgid "Place custom rules at the top" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1279 +msgid "Check this if you want to place your custom rules at the beginning of all the rules applied by this plugin" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1283 +msgid "Enter custom .htaccess rules:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1287 +msgid "Enter your custom .htaccess rules/directives." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1292 +msgid "Save custom rules" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:338 +#: admin/wp-security-firewall-setup-notice.php:407 +#: admin/wp-security-firewall-setup-notice.php:479 +#: admin/wp-security-firewall-setup-notice.php:595 +#: wp-security.php:43 +msgid "All In One WP Security and Firewall" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:340 +msgid "We were unable to create the file necessary to give you the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:341 +msgid "Your firewall will have reduced protection which means some of your firewall's functionality will be unavailable." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:342 +msgid "If you would like to manually set up the necessary file, please follow these steps:" +msgstr "" + +#. translators: %s Bootstrap file name. +#. translators: %s Firewall file name. +#: admin/wp-security-firewall-setup-notice.php:346 +#: admin/wp-security-firewall-setup-notice.php:453 +msgid "1. Create a file with the name %s in the same directory as your WordPress install is in, i.e.:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:350 +msgid "2. Paste in the following code:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:352 +#: admin/wp-security-firewall-setup-notice.php:462 +msgid "3. Save the file and press the 'Try again' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:372 +msgid "1. Open the following file:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:378 +msgid "2. Look for the auto_prepend_file directive." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:382 +msgid "2. Look for the following:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:388 +msgid "3. Change it to the following:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:392 +msgid "4. Save the file and press the 'Try again' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:392 +#: admin/wp-security-firewall-setup-notice.php:441 +msgid "You may have to wait up to 5 minutes before the settings take effect." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:410 +msgid "Your firewall has been installed with the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:411 +msgid "You may have to wait 5 minutes for the changes to take effect." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:434 +msgid "1. Open your php.ini file." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:437 +msgid "2. Set the auto_prepend_file directive like below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:441 +msgid "3. Restart the webserver and refresh the page" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:458 +msgid "2. Paste in the following directives:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:482 +msgid "We were unable to set up your firewall with the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:483 +msgid "Your firewall will have reduced functionality." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:487 +msgid "To give your site the highest level of protection, please follow these steps:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:500 +msgid "Note: if you're unable to perform any of the aforementioned steps, please ask your web hosting provider for further assistance." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:517 +msgid "Try again" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:539 +msgid "We have detected that your AIOS firewall is not fully installed, and therefore does not have the highest level of protection. " +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:540 +msgid "Your firewall will have reduced functionality until it has been upgraded. " +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:542 +msgid "Upgrade your protection now" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:598 +msgid "Our PHP-based firewall has been created to give you even greater protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:602 +msgid "If you already have our .htaccess-based firewall enabled, you will still need to set up the PHP-based firewall to benefit from its protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:605 +msgid "To set up the PHP-based firewall, press the 'Set up now' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:608 +msgid "Set up now" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:614 +#: templates/notices/custom-notice.php:10 +#: templates/notices/custom-notice.php:12 +#: templates/notices/horizontal-notice.php:50 +#: templates/notices/horizontal-notice.php:52 +#: templates/notices/htaccess-to-php-feature-notice.php:10 +#: templates/notices/htaccess-to-php-feature-notice.php:12 +msgid "Dismiss" +msgstr "" + +#: admin/wp-security-list-404.php:91 +msgid "Event type" +msgstr "" + +#: admin/wp-security-list-404.php:92 +#: admin/wp-security-list-logged-in-users.php:46 +#: admin/wp-security-list-registered-users.php:74 +msgid "IP address" +msgstr "" + +#: admin/wp-security-list-404.php:93 +msgid "Attempted URL" +msgstr "" + +#: admin/wp-security-list-404.php:94 +msgid "Referer" +msgstr "" + +#: admin/wp-security-list-404.php:96 +msgid "Lock status" +msgstr "" + +#: admin/wp-security-list-404.php:118 +msgid "Temp block IP" +msgstr "" + +#: admin/wp-security-list-404.php:119 +msgid "Blacklist IP" +msgstr "" + +#: admin/wp-security-list-404.php:120 +#: admin/wp-security-list-acct-activity.php:82 +#: admin/wp-security-list-locked-ip.php:37 +#: admin/wp-security-list-locked-ip.php:84 +#: admin/wp-security-list-login-fails.php:73 +#: admin/wp-security-list-registered-users.php:93 +msgid "Delete" +msgstr "" + +#: admin/wp-security-list-404.php:128 +#: admin/wp-security-list-404.php:136 +#: admin/wp-security-list-404.php:143 +#: admin/wp-security-list-acct-activity.php:92 +#: admin/wp-security-list-comment-spammer-ip.php:95 +#: admin/wp-security-list-locked-ip.php:97 +#: admin/wp-security-list-locked-ip.php:105 +#: admin/wp-security-list-login-fails.php:85 +#: admin/wp-security-list-permanent-blocked-ip.php:96 +#: admin/wp-security-list-registered-users.php:107 +#: admin/wp-security-list-registered-users.php:115 +#: admin/wp-security-list-registered-users.php:123 +msgid "Please select some records using the checkboxes" +msgstr "" + +#: admin/wp-security-list-404.php:278 +msgid "Nonce check failed for delete selected 404 event logs operation!" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:35 +msgid "Are you sure you want to delete this item?" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:46 +msgid "Login session still active" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:60 +#: admin/wp-security-list-locked-ip.php:60 +#: admin/wp-security-list-logged-in-users.php:44 +#: admin/wp-security-list-login-fails.php:54 +#: admin/wp-security-list-registered-users.php:69 +msgid "User ID" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:61 +#: admin/wp-security-list-locked-ip.php:61 +#: admin/wp-security-list-login-fails.php:55 +msgid "Username" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:62 +msgid "Login date" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:63 +msgid "Logout date" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:136 +msgid "Nonce check failed for delete selected account activity logs operation!" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:59 +msgid "Spammer IP" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:60 +msgid "Number of spam comments from this IP" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:61 +msgid "Status" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:81 +msgid "Block" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:130 +#: admin/wp-security-list-comment-spammer-ip.php:179 +msgid "Nonce check failed for delete selected blocked IP operation!" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:137 +msgid "The selected IP addresses are now permanently blocked!" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:193 +msgid "The selected IP addresses were saved in the blacklist configuration settings." +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:201 +msgid "The .htaccess file was successfully modified to include the selected IP addresses." +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:212 +msgid "NOTE: The .htaccess file was not modified because you have disabled the \"Enable IP or User Agent Blacklisting\" check box." +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:213 +msgid "To block these IP addresses you will need to enable the above flag in the %s menu" +msgstr "" + +#: admin/wp-security-list-debug.php:47 +msgid "Level" +msgstr "" + +#: admin/wp-security-list-debug.php:48 +msgid "Message" +msgstr "" + +#: admin/wp-security-list-debug.php:49 +msgid "Type" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:36 +#: admin/wp-security-list-locked-ip.php:83 +msgid "Unlock" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:59 +msgid "Locked IP/range" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:62 +#: admin/wp-security-list-permanent-blocked-ip.php:67 +msgid "Reason" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:63 +msgid "Date locked" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:64 +msgid "Release date" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:134 +msgid "The selected IP entries were unlocked successfully." +msgstr "" + +#: admin/wp-security-list-locked-ip.php:140 +msgid "Nonce check failed for unlock IP operation!" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:147 +msgid "The selected IP entry was unlocked successfully." +msgstr "" + +#: admin/wp-security-list-logged-in-users.php:45 +#: admin/wp-security-list-registered-users.php:70 +msgid "Login name" +msgstr "" + +#: admin/wp-security-list-logged-in-users.php:87 +msgid "Nonce check failed for force user logout operation!" +msgstr "" + +#: admin/wp-security-list-logged-in-users.php:96 +msgid "The selected user was logged out successfully!" +msgstr "" + +#: admin/wp-security-list-login-fails.php:53 +msgid "Login IP range" +msgstr "" + +#: admin/wp-security-list-login-fails.php:130 +msgid "Nonce check failed for delete failed login record operation!" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:66 +msgid "Blocked IP" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:87 +msgid "Unblock" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:122 +#: admin/wp-security-list-permanent-blocked-ip.php:139 +msgid "Successfully unblocked and deleted the selected record(s)." +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:126 +#: admin/wp-security-list-permanent-blocked-ip.php:143 +msgid "Failed to unblock and delete the selected record(s)." +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:133 +msgid "Nonce check failed for unblock IP operation!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:71 +msgid "Email" +msgstr "" + +#: admin/wp-security-list-registered-users.php:72 +msgid "Register date" +msgstr "" + +#: admin/wp-security-list-registered-users.php:73 +msgid "Account status" +msgstr "" + +#: admin/wp-security-list-registered-users.php:92 +msgid "Approve" +msgstr "" + +#: admin/wp-security-list-registered-users.php:94 +msgid "Block IP" +msgstr "" + +#: admin/wp-security-list-registered-users.php:159 +msgid "The selected accounts were approved successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:163 +msgid "The following accounts failed to update successfully: " +msgstr "" + +#: admin/wp-security-list-registered-users.php:171 +msgid "The selected account was approved successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:190 +msgid "Your account is now active" +msgstr "" + +#: admin/wp-security-list-registered-users.php:191 +msgid "Your account with username: " +msgstr "" + +#: admin/wp-security-list-registered-users.php:191 +msgid " is now active" +msgstr "" + +#: admin/wp-security-list-registered-users.php:222 +msgid "The selected accounts were deleted successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:230 +msgid "Nonce check failed for delete registered user account operation!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:238 +msgid "The selected account was deleted successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:264 +msgid "The selected IP addresses were successfully added to the permanent block list!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:265 +#: admin/wp-security-list-registered-users.php:282 +msgid "View Blocked IPs" +msgstr "" + +#: admin/wp-security-list-registered-users.php:274 +msgid "Nonce check failed for block IP operation of registered user!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:281 +msgid "The selected IP was successfully added to the permanent block list!" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:25 +msgid "Visitor lockout" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:85 +msgid "Site lockout feature settings saved!" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:92 +msgid "General visitor lockout" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:98 +msgid "This feature allows you to put your site into \"maintenance mode\" by locking down the front-end to all visitors except logged in users with super admin privileges." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:99 +msgid "Locking your site down to general visitors can be useful if you are investigating some issues on your site or perhaps you might be doing some maintenance and wish to keep out all traffic for security reasons." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:104 +msgid "Enable front-end lockout" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:107 +msgid "Check this if you want all visitors except those who are logged in as administrator to be locked out of the front-end of your site." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:111 +msgid "Enter a message:" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:123 +msgid "Enter a message you wish to display to visitors when your site is in maintenance mode." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:130 +msgid "Save site lockout settings" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:28 +msgid "Copy protection" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:29 +msgid "Frames" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:30 +msgid "Users enumeration" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:31 +msgid "WP REST API" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:89 +msgid "Copy Protection feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:94 +msgid "Disable the ability to copy text" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:100 +msgid "This feature allows you to disable the ability to select and copy text from your front end." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:101 +msgid "When admin user is logged in, the feature is automatically disabled for his session." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:106 +msgid "Enable copy protection" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:109 +msgid "Check this if you want to disable the \"Right click\", \"Text selection\" and \"Copy\" option on the front end of your site." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:116 +msgid "Save copy protection settings" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:140 +msgid "Frame Display Prevention feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:145 +msgid "Prevent your site from being displayed in a frame" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:151 +msgid "This feature allows you to prevent other sites from displaying any of your content via a frame or iframe." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:152 +msgid "When enabled, this feature will set the \"X-Frame-Options\" parameter to \"sameorigin\" in the HTTP header." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:157 +msgid "Enable iFrame protection" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:160 +msgid "Check this if you want to stop other sites from displaying your content in a frame or iframe." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:191 +msgid "Users Enumeration Prevention feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:196 +msgid "Prevent users enumeration" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:202 +msgid "This feature allows you to prevent external users/bots from fetching the user info with urls like \"/?author=1\"." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:203 +msgid "When enabled, this feature will print a \"forbidden\" error rather than the user information." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:208 +msgid "Disable users enumeration" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:211 +msgid "Check this if you want to stop users enumeration." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:242 +msgid "WP REST API Security feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:253 +msgid "This feature allows you to block WordPress REST API access for unauthorized requests." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:254 +msgid "When enabled this feature will only allow REST requests to be processed if the user is logged in." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:260 +msgid "Beware that if you are using other plugins which have registered REST endpoints (eg, Contact Form 7), then this feature will also block REST requests used by these plugins if the user is not logged in. It is recommended that you leave this feature disabled if you want uninterrupted functionality for such plugins." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:268 +msgid "Disallow unauthorized REST requests" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:271 +msgid "Check this if you want to stop REST API access for non-logged in requests." +msgstr "" + +#: admin/wp-security-settings-menu.php:25 +msgid "General settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:29 +#: admin/wp-security-settings-menu.php:33 +msgid "file" +msgstr "" + +#: admin/wp-security-settings-menu.php:37 +msgid "Delete plugin settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:41 +msgid "WP version info" +msgstr "" + +#: admin/wp-security-settings-menu.php:45 +msgid "Import/Export" +msgstr "" + +#: admin/wp-security-settings-menu.php:52 +msgid "Advanced settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:128 +msgid "All the security features have been disabled successfully!" +msgstr "" + +#: admin/wp-security-settings-menu.php:132 +#: admin/wp-security-settings-menu.php:159 +msgid "Could not write to the .htaccess file. Please restore your .htaccess file manually using the restore functionality in the \".htaccess File\"." +msgstr "" + +#: admin/wp-security-settings-menu.php:137 +msgid "Could not write to the wp-config.php. Please restore your wp-config.php file manually using the restore functionality in the \"wp-config.php File\"." +msgstr "" + +#: admin/wp-security-settings-menu.php:155 +msgid "All firewall rules have been disabled successfully!" +msgstr "" + +#: admin/wp-security-settings-menu.php:177 +msgid "Deletion of aio_wp_security_configs option and .htaccess directives failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:179 +msgid "Reset of aio_wp_security_configs option failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:181 +msgid "Deletion of .htaccess directives failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:183 +msgid "All settings have been successfully reset." +msgstr "" + +#: admin/wp-security-settings-menu.php:203 +msgid "For information, updates and documentation, please visit the" +msgstr "" + +#: admin/wp-security-settings-menu.php:203 +msgid "Page" +msgstr "" + +#: admin/wp-security-settings-menu.php:204 +msgid "Follow us" +msgstr "" + +#: admin/wp-security-settings-menu.php:204 +msgid "on Twitter, Google+ or via Email to stay up to date about the new security features of this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:208 +msgid "WP Security plugin" +msgstr "" + +#: admin/wp-security-settings-menu.php:212 +msgid "Thank you for using the AIOS security plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:216 +msgid "There are a lot of security features in this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:221 +msgid "To start, go through each security option and enable the \"basic\" options." +msgstr "" + +#: admin/wp-security-settings-menu.php:225 +msgid "The more features you enable, the more security points you will achieve." +msgstr "" + +#: admin/wp-security-settings-menu.php:228 +msgid "Before doing anything we advise taking a backup of your .htaccess file, database and wp-config.php." +msgstr "" + +#: admin/wp-security-settings-menu.php:231 +msgid "Backup your database" +msgstr "" + +#: admin/wp-security-settings-menu.php:232 +#: admin/wp-security-settings-menu.php:433 +msgid "Backup .htaccess file" +msgstr "" + +#: admin/wp-security-settings-menu.php:233 +#: admin/wp-security-settings-menu.php:534 +msgid "Backup wp-config.php file" +msgstr "" + +#: admin/wp-security-settings-menu.php:240 +msgid "Disable security features" +msgstr "" + +#: admin/wp-security-settings-menu.php:246 +msgid "If you think that some plugin functionality on your site is broken due to a security feature you enabled in this plugin, then use the following option to turn off all the security features of this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:250 +msgid "Disable all security features" +msgstr "" + +#: admin/wp-security-settings-menu.php:257 +#: admin/wp-security-settings-menu.php:267 +msgid "Disable all firewall rules" +msgstr "" + +#: admin/wp-security-settings-menu.php:263 +msgid "This feature will disable all firewall rules which are currently active in this plugin and it will also delete these rules from your .htacess file. Use it if you think one of the firewall rules is causing an issue on your site." +msgstr "" + +#: admin/wp-security-settings-menu.php:274 +#: admin/wp-security-settings-menu.php:287 +msgid "Reset settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:279 +msgid "This button click will delete all of your settings related to the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:280 +msgid "This button click will reset/empty all the database tables of the security plugin also." +msgstr "" + +#: admin/wp-security-settings-menu.php:281 +msgid "Use this plugin if you were locked out by the All In One WP Security & Firewall Plugin and/or you are having issues logging in when that plugin is activated." +msgstr "" + +#: admin/wp-security-settings-menu.php:282 +msgid "In addition to the settings it will also delete any directives which were added to the .htaccess file by the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:283 +msgid "%1$sNOTE: %2$sAfter deleting the settings you will need to re-configure the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:295 +msgid "Debug settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:301 +msgid "This setting allows you to enable/disable debug for this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:307 +msgid "Enable debug" +msgstr "" + +#: admin/wp-security-settings-menu.php:310 +msgid "Check this if you want to enable debug. You should keep this option disabled after you have finished debugging the issue." +msgstr "" + +#: admin/wp-security-settings-menu.php:314 +msgid "Save debug settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:350 +msgid "Your .htaccess file was successfully backed up! Using an FTP program go to the \"/wp-content/aiowps_backups\" directory to save a copy of the file to your computer." +msgstr "" + +#: admin/wp-security-settings-menu.php:356 +msgid "htaccess file rename failed during backup. Please check your root directory for the backup file using FTP." +msgstr "" + +#: admin/wp-security-settings-menu.php:362 +msgid "htaccess backup failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:377 +msgid "Please choose a .htaccess to restore from." +msgstr "" + +#: admin/wp-security-settings-menu.php:392 +msgid "htaccess file restore failed. Please attempt to restore the .htaccess manually using FTP." +msgstr "" + +#: admin/wp-security-settings-menu.php:396 +msgid "Your .htaccess file has successfully been restored!" +msgstr "" + +#: admin/wp-security-settings-menu.php:402 +msgid "htaccess Restore operation failed! Please check the contents of the file you are trying to restore from." +msgstr "" + +#: admin/wp-security-settings-menu.php:408 +msgid ".htaccess file operations" +msgstr "" + +#: admin/wp-security-settings-menu.php:411 +msgid "Your \".htaccess\" file is a key component of your website's security and it can be modified to implement various levels of protection mechanisms." +msgstr "" + +#: admin/wp-security-settings-menu.php:412 +msgid "This feature allows you to backup and save your currently active .htaccess file should you need to re-use the the backed up file in the future." +msgstr "" + +#: admin/wp-security-settings-menu.php:413 +msgid "You can also restore your site's .htaccess settings using a backed up .htaccess file." +msgstr "" + +#: admin/wp-security-settings-menu.php:428 +msgid "Save the current .htaccess file" +msgstr "" + +#: admin/wp-security-settings-menu.php:432 +msgid "Click the button below to backup and save the currently active .htaccess file." +msgstr "" + +#: admin/wp-security-settings-menu.php:437 +msgid "Restore from a backed up .htaccess file" +msgstr "" + +#: admin/wp-security-settings-menu.php:443 +msgid ".htaccess file to restore from" +msgstr "" + +#: admin/wp-security-settings-menu.php:445 +msgid "Select Your htaccess File" +msgstr "" + +#: admin/wp-security-settings-menu.php:449 +msgid "After selecting your file, click the button below to restore your site using the backed up htaccess file (htaccess_backup.txt)." +msgstr "" + +#: admin/wp-security-settings-menu.php:455 +msgid "Restore .htaccess file" +msgstr "" + +#: admin/wp-security-settings-menu.php:477 +msgid "Please choose a wp-config.php file to restore from." +msgstr "" + +#: admin/wp-security-settings-menu.php:493 +msgid "wp-config.php file restore failed. Please attempt to restore this file manually using FTP." +msgstr "" + +#: admin/wp-security-settings-menu.php:497 +msgid "Your wp-config.php file has successfully been restored!" +msgstr "" + +#: admin/wp-security-settings-menu.php:503 +msgid "wp-config.php Restore operation failed! Please check the contents of the file you are trying to restore from." +msgstr "" + +#: admin/wp-security-settings-menu.php:509 +msgid "wp-config.php file operations" +msgstr "" + +#: admin/wp-security-settings-menu.php:512 +msgid "Your \"wp-config.php\" file is one of the most important in your WordPress installation. It is a primary configuration file and contains crucial things such as details of your database and other critical components." +msgstr "" + +#: admin/wp-security-settings-menu.php:513 +msgid "This feature allows you to backup and save your currently active wp-config.php file should you need to re-use the the backed up file in the future." +msgstr "" + +#: admin/wp-security-settings-menu.php:514 +msgid "You can also restore your site's wp-config.php settings using a backed up wp-config.php file." +msgstr "" + +#: admin/wp-security-settings-menu.php:529 +msgid "Save the current wp-config.php file" +msgstr "" + +#: admin/wp-security-settings-menu.php:533 +msgid "Click the button below to backup and download the contents of the currently active wp-config.php file." +msgstr "" + +#: admin/wp-security-settings-menu.php:539 +msgid "Restore from a backed up wp-config file" +msgstr "" + +#: admin/wp-security-settings-menu.php:545 +msgid "wp-config file to restore from" +msgstr "" + +#: admin/wp-security-settings-menu.php:547 +msgid "Select Your wp-config File" +msgstr "" + +#: admin/wp-security-settings-menu.php:551 +msgid "After selecting your file click the button below to restore your site using the backed up wp-config file (wp-config.php.backup.txt)." +msgstr "" + +#: admin/wp-security-settings-menu.php:557 +msgid "Restore wp-config file" +msgstr "" + +#: admin/wp-security-settings-menu.php:591 +msgid "Manage delete plugin settings saved." +msgstr "" + +#: admin/wp-security-settings-menu.php:596 +msgid "Manage delete plugin tasks" +msgstr "" + +#: admin/wp-security-settings-menu.php:603 +msgid "Delete database tables" +msgstr "" + +#: admin/wp-security-settings-menu.php:606 +msgid "Check this if you want to remove database tables when the plugin is uninstalled." +msgstr "" + +#: admin/wp-security-settings-menu.php:610 +msgid "Delete settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:613 +msgid "Check this if you want to remove all plugin settings when uninstalling the plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:613 +msgid "It will also remove all custom htaccess rules that were added by this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:647 +msgid "WP generator meta tag and version info" +msgstr "" + +#: admin/wp-security-settings-menu.php:650 +msgid "WordPress generator automatically adds some meta information inside the \"head\" tags of every page on your site's front end. Below is an example of this:" +msgstr "" + +#: admin/wp-security-settings-menu.php:652 +msgid "The above meta information shows which version of WordPress your site is currently running and thus can help hackers or crawlers scan your site to see if you have an older version of WordPress or one with a known exploit." +msgstr "" + +#: admin/wp-security-settings-menu.php:653 +msgid "There are also other ways wordpress reveals version info such as during style and script loading. An example of this is:" +msgstr "" + +#: admin/wp-security-settings-menu.php:655 +msgid "This feature will allow you to remove the WP generator meta info and other version info from your site's pages." +msgstr "" + +#: admin/wp-security-settings-menu.php:661 +msgid "WP generator meta info" +msgstr "" + +#: admin/wp-security-settings-menu.php:673 +msgid "Remove WP generator meta info" +msgstr "" + +#: admin/wp-security-settings-menu.php:676 +msgid "Check this if you want to remove the version and meta info produced by WP from all pages" +msgstr "" + +#: admin/wp-security-settings-menu.php:704 +msgid "Please choose a file to import your settings from." +msgstr "" + +#: admin/wp-security-settings-menu.php:736 +msgid "Import AIOS settings from " +msgstr "" + +#: admin/wp-security-settings-menu.php:742 +#: admin/wp-security-settings-menu.php:786 +msgid "The deletion of the import file failed. Please delete this file manually via the media menu for security purposes." +msgstr "" + +#: admin/wp-security-settings-menu.php:744 +#: admin/wp-security-settings-menu.php:788 +msgid "The file you uploaded was also deleted for security purposes because it contains security settings details." +msgstr "" + +#: admin/wp-security-settings-menu.php:759 +msgid "Your AIOS settings were successfully imported via file input." +msgstr "" + +#: admin/wp-security-settings-menu.php:760 +msgid "The deletion of the import file failed. Please delete this file manually via the media menu for security purposes because it contains security settings details." +msgstr "" + +#: admin/wp-security-settings-menu.php:762 +msgid "Your AIOS settings were successfully imported. The file you uploaded was also deleted for security purposes because it contains security settings details." +msgstr "" + +#: admin/wp-security-settings-menu.php:765 +msgid "Your AIOS settings were successfully imported via text entry." +msgstr "" + +#: admin/wp-security-settings-menu.php:780 +msgid "The contents of your settings file appear invalid. Please check the contents of the file you are trying to import settings from." +msgstr "" + +#: admin/wp-security-settings-menu.php:797 +msgid "Export or import your AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:800 +msgid "This section allows you to export or import your All In One WP Security & Firewall settings." +msgstr "" + +#: admin/wp-security-settings-menu.php:801 +msgid "This can be handy if you wanted to save time by applying the settings from one site to another site." +msgstr "" + +#: admin/wp-security-settings-menu.php:802 +msgid "NOTE: Before importing, it is your responsibility to know what settings you are trying to import. Importing settings blindly can cause you to be locked out of your site." +msgstr "" + +#: admin/wp-security-settings-menu.php:803 +msgid "For Example: If a settings item relies on the domain URL then it may not work correctly when imported into a site with a different domain." +msgstr "" + +#: admin/wp-security-settings-menu.php:809 +#: admin/wp-security-settings-menu.php:818 +msgid "Export AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:815 +msgid "To export your All In One WP Security & Firewall settings click the button below." +msgstr "" + +#: admin/wp-security-settings-menu.php:822 +#: admin/wp-security-settings-menu.php:851 +msgid "Import AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:828 +msgid "Use this section to import your All In One WP Security & Firewall settings from a file. Alternatively, copy/paste the contents of your import file into the textarea below." +msgstr "" + +#: admin/wp-security-settings-menu.php:830 +msgid "Import file" +msgstr "" + +#: admin/wp-security-settings-menu.php:833 +msgid "Select Your Import Settings File" +msgstr "" + +#: admin/wp-security-settings-menu.php:837 +msgid "After selecting your file, click the button below to apply the settings to your site." +msgstr "" + +#: admin/wp-security-settings-menu.php:844 +msgid "Copy/Paste import data" +msgstr "" + +#: admin/wp-security-settings-menu.php:893 +msgid "Default - if correct, then this is the best option" +msgstr "" + +#: admin/wp-security-settings-menu.php:894 +msgid "Only use if you're using Cloudflare." +msgstr "" + +#: admin/wp-security-settings-menu.php:902 +msgid "(current value: %s)" +msgstr "" + +#: admin/wp-security-settings-menu.php:905 +msgid "no value (i.e. empty) on your server" +msgstr "" + +#: admin/wp-security-spam-menu.php:28 +msgid "Comment spam" +msgstr "" + +#: admin/wp-security-spam-menu.php:29 +msgid "Comment spam IP monitoring" +msgstr "" + +#: admin/wp-security-spam-menu.php:30 +msgid "BuddyPress" +msgstr "" + +#: admin/wp-security-spam-menu.php:31 +msgid "bbPress" +msgstr "" + +#: admin/wp-security-spam-menu.php:57 +msgid "Spam prevention" +msgstr "" + +#: admin/wp-security-spam-menu.php:99 +msgid "You entered a non numeric value for the \"move spam comments to trash after number of days\" field." +msgstr "" + +#: admin/wp-security-spam-menu.php:99 +#: admin/wp-security-spam-menu.php:297 +#: admin/wp-security-user-login-menu.php:118 +#: admin/wp-security-user-login-menu.php:124 +#: admin/wp-security-user-login-menu.php:130 +#: admin/wp-security-user-login-menu.php:136 +msgid "It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:129 +msgid "Comment spam settings" +msgstr "" + +#: admin/wp-security-spam-menu.php:134 +msgid "Add CAPTCHA to comments form" +msgstr "" + +#: admin/wp-security-spam-menu.php:138 +msgid "This feature will add a CAPTCHA field in the WordPress comments form." +msgstr "" + +#: admin/wp-security-spam-menu.php:139 +msgid "Adding a CAPTCHA field in the comment form is a simple way of greatly reducing spam comments from bots without using .htaccess rules." +msgstr "" + +#: admin/wp-security-spam-menu.php:148 +msgid "Enable CAPTCHA on comment forms" +msgstr "" + +#: admin/wp-security-spam-menu.php:151 +msgid "Check this if you want to insert a CAPTCHA field on the comment forms." +msgstr "" + +#: admin/wp-security-spam-menu.php:158 +msgid "Block spambot comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:162 +msgid "A large portion of WordPress blog comment spam is mainly produced by automated bots and not necessarily by humans." +msgstr "" + +#: admin/wp-security-spam-menu.php:163 +msgid "This feature will greatly minimize the useless and unnecessary traffic and load on your server resulting from spam comments by blocking all comment requests which do not originate from your domain." +msgstr "" + +#: admin/wp-security-spam-menu.php:164 +msgid "In other words, if the comment was not submitted by a human who physically submitted the comment on your site, the request will be blocked." +msgstr "" + +#: admin/wp-security-spam-menu.php:182 +msgid "Block spambots from posting comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:185 +msgid "Check this if you want to apply a firewall rule which will block comments originating from spambots." +msgstr "" + +#: admin/wp-security-spam-menu.php:189 +msgid "This feature will implement a firewall rule to block all comment attempts which do not originate from your domain." +msgstr "" + +#: admin/wp-security-spam-menu.php:190 +msgid "A legitimate comment is one which is submitted by a human who physically fills out the comment form and clicks the submit button. For such events, the HTTP_REFERRER is always set to your own domain." +msgstr "" + +#: admin/wp-security-spam-menu.php:191 +msgid "A comment submitted by a spambot is done by directly calling the comments.php file, which usually means that the HTTP_REFERRER value is not your domain and often times empty." +msgstr "" + +#: admin/wp-security-spam-menu.php:192 +msgid "This feature will check and block comment requests which are not referred by your domain thus greatly reducing your overall blog spam and PHP requests done by the server to process these comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:202 +msgid "Comment processing" +msgstr "" + +#: admin/wp-security-spam-menu.php:207 +msgid "Trash spam comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:216 +msgid "Move spam comments to trash after %s days." +msgstr "" + +#: admin/wp-security-spam-menu.php:224 +msgid "Enable this feature in order to move the spam comments to trash after given number of days." +msgstr "" + +#: admin/wp-security-spam-menu.php:262 +msgid "You entered a non numeric value for the minimum number of spam comments field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:265 +msgid "You must enter an integer greater than zero for minimum number of spam comments field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:292 +msgid "Nonce check failed for list spam comment IPs." +msgstr "" + +#: admin/wp-security-spam-menu.php:297 +msgid "You entered a non numeric value for the minimum spam comments per IP field." +msgstr "" + +#: admin/wp-security-spam-menu.php:308 +msgid "Displaying results for IP addresses which have posted a minimum of %s spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:323 +msgid "Auto block spammer IPs" +msgstr "" + +#: admin/wp-security-spam-menu.php:328 +msgid "This feature has detected that %s is not active. It is highly recommended that you activate the Akismet plugin to make the most of this feature." +msgstr "" + +#: admin/wp-security-spam-menu.php:337 +msgid "This feature allows you to automatically and permanently block IP addresses which have exceeded a certain number of comments labelled as spam." +msgstr "" + +#: admin/wp-security-spam-menu.php:338 +msgid "Comments are usually labelled as spam either by the Akismet plugin or manually by the WP administrator when they mark a comment as \"spam\" from the WordPress Comments menu." +msgstr "" + +#: admin/wp-security-spam-menu.php:352 +msgid "You currently have no IP addresses permanently blocked due to spam." +msgstr "" + +#: admin/wp-security-spam-menu.php:365 +msgid "Spammer IPs added to permanent block list today: " +msgstr "" + +#: admin/wp-security-spam-menu.php:366 +msgid "All time total: " +msgstr "" + +#: admin/wp-security-spam-menu.php:367 +msgid "View blocked IPs" +msgstr "" + +#: admin/wp-security-spam-menu.php:380 +msgid "Enable auto block of spam comment IPs" +msgstr "" + +#: admin/wp-security-spam-menu.php:383 +msgid "Check this box if you want this plugin to automatically block IP addresses which submit spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:387 +msgid "Minimum number of spam comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:389 +msgid "Specify the minimum number of spam comments for an IP address before it is permanently blocked." +msgstr "" + +#: admin/wp-security-spam-menu.php:393 +msgid "Example 1: Setting this value to \"1\" will block ALL IP addresses which were used to submit at least one spam comment." +msgstr "" + +#: admin/wp-security-spam-menu.php:394 +msgid "Example 2: Setting this value to \"5\" will block only those IP addresses which were used to submit 5 spam comments or more on your site." +msgstr "" + +#: admin/wp-security-spam-menu.php:412 +msgid "List spammer IP addresses" +msgstr "" + +#: admin/wp-security-spam-menu.php:416 +msgid "This section displays a list of the IP addresses of the people or bots who have left spam comments on your site." +msgstr "" + +#: admin/wp-security-spam-menu.php:417 +msgid "This information can be handy for identifying the most persistent IP addresses or ranges used by spammers." +msgstr "" + +#: admin/wp-security-spam-menu.php:418 +msgid "By inspecting the IP address data coming from spammers you will be in a better position to determine which addresses or address ranges you should block by adding them to the permanent block list." +msgstr "" + +#: admin/wp-security-spam-menu.php:419 +msgid "To add one or more of the IP addresses displayed in the table below to your blacklist, simply click the \"Block\" link for the individual row or select more than one address using the checkboxes and then choose the \"block\" option from the Bulk Actions dropdown list and click the \"Apply\" button." +msgstr "" + +#: admin/wp-security-spam-menu.php:427 +msgid "Minimum number of spam comments per IP" +msgstr "" + +#: admin/wp-security-spam-menu.php:429 +msgid "This field allows you to list only those IP addresses which have been used to post X or more spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:433 +msgid "Example 1: Setting this value to \"0\" or \"1\" will list ALL IP addresses which were used to submit spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:434 +msgid "Example 2: Setting this value to \"5\" will list only those IP addresses which were used to submit 5 spam comments or more on your site." +msgstr "" + +#: admin/wp-security-spam-menu.php:441 +msgid "Find IP addresses" +msgstr "" + +#: admin/wp-security-spam-menu.php:445 +msgid "Spammer IP address results" +msgstr "" + +#: admin/wp-security-spam-menu.php:451 +#: classes/wp-security-utility.php:253 +msgid "The plugin has detected that you are using a Multi-Site WordPress installation." +msgstr "" + +#: admin/wp-security-spam-menu.php:452 +msgid "Only the \"superadmin\" can block IP addresses from the main site." +msgstr "" + +#: admin/wp-security-spam-menu.php:453 +msgid "Take note of the IP addresses you want blocked and ask the superadmin to add these to the blacklist using the \"Blacklist Manager\" on the main site." +msgstr "" + +#: admin/wp-security-spam-menu.php:498 +msgid "BuddyPress spam settings" +msgstr "" + +#: admin/wp-security-spam-menu.php:503 +msgid "Add CAPTCHA to BuddyPress registration form" +msgstr "" + +#: admin/wp-security-spam-menu.php:507 +msgid "This feature will add a simple math CAPTCHA field in the BuddyPress registration form." +msgstr "" + +#: admin/wp-security-spam-menu.php:508 +msgid "Adding a CAPTCHA field in the registration form is a simple way of greatly reducing spam signups from bots without using .htaccess rules." +msgstr "" + +#: admin/wp-security-spam-menu.php:518 +msgid "Enable CAPTCHA on BuddyPress registration form" +msgstr "" + +#: admin/wp-security-spam-menu.php:521 +msgid "Check this if you want to insert a CAPTCHA field on the BuddyPress registration forms." +msgstr "" + +#: admin/wp-security-spam-menu.php:530 +msgid "BuddyPress is not active! In order to use this feature you will need to have BuddyPress installed and activated." +msgstr "" + +#: admin/wp-security-spam-menu.php:560 +msgid "bbPress spam settings" +msgstr "" + +#: admin/wp-security-spam-menu.php:565 +msgid "Add CAPTCHA to bbPress new topic form" +msgstr "" + +#: admin/wp-security-spam-menu.php:569 +msgid "This feature will add a simple math CAPTCHA field in the bbPress new topic form." +msgstr "" + +#: admin/wp-security-spam-menu.php:570 +msgid "Adding a CAPTCHA field in this form is a simple way of greatly reducing spam submitted from bots." +msgstr "" + +#: admin/wp-security-spam-menu.php:580 +msgid "Enable CAPTCHA on bbPress new topic form" +msgstr "" + +#: admin/wp-security-spam-menu.php:583 +msgid "Check this if you want to insert a CAPTCHA field on the bbPress new topic forms." +msgstr "" + +#: admin/wp-security-spam-menu.php:592 +msgid "bbPress is not active. In order to use this feature you will need to have bbPress installed and activated." +msgstr "" + +#: admin/wp-security-tools-menu.php:34 +msgid "WHOIS lookup" +msgstr "" + +#: admin/wp-security-tools-menu.php:95 +#: admin/wp-security-tools-menu.php:136 +msgid "Querying %s: %s" +msgstr "" + +#: admin/wp-security-tools-menu.php:103 +#: admin/wp-security-tools-menu.php:112 +#: admin/wp-security-tools-menu.php:151 +msgid "Redirected to %s" +msgstr "" + +#: admin/wp-security-tools-menu.php:173 +msgid "The WHOIS lookup feature gives you a way to look up who owns an IP address or domain name." +msgstr "" + +#: admin/wp-security-tools-menu.php:173 +msgid "You can use this to investigate users engaging in malicious activity on your site." +msgstr "" + +#: admin/wp-security-tools-menu.php:176 +msgid "WHOIS lookup on IP or domain" +msgstr "" + +#: admin/wp-security-tools-menu.php:183 +msgid "IP address or domain name:" +msgstr "" + +#: admin/wp-security-tools-menu.php:190 +msgid "Look up IP or domain" +msgstr "" + +#: admin/wp-security-tools-menu.php:219 +msgid "Please enter a valid IP address or domain name to look up." +msgstr "" + +#: admin/wp-security-tools-menu.php:220 +#: admin/wp-security-tools-menu.php:226 +msgid "Nothing to show." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:32 +msgid "WP username" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:33 +msgid "Display name" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:34 +msgid "Password" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:60 +msgid "User accounts" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:82 +msgid "Admin user security" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:85 +msgid "By default, WordPress sets the administrator username to \"admin\" at installation time." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:86 +msgid "A lot of hackers try to take advantage of this information by attempting \"Brute force login attacks\" where they repeatedly try to guess the password by using \"admin\" for username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:87 +msgid "From a security perspective, changing the default \"admin\" user name is one of the first and smartest things you should do on your site." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:88 +msgid "This feature will allow you to change your default \"admin\" user name to a more secure name of your choosing." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:95 +msgid "List of administrator accounts" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:104 +#: classes/grade-system/wp-security-feature-item-manager.php:43 +msgid "Change admin username" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:112 +msgid "Your site currently has an account which uses the default \"admin\" username. It is highly recommended that you change this name to something else. Use the following field to change the admin username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:118 +msgid "New admin username" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:120 +msgid "Choose a new username for admin." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:124 +msgid "Change username" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:126 +msgid "NOTE: If you are currently logged in as \"admin\" you will be automatically logged out after changing your username and will be required to log back in." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:133 +msgid "No action required! " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:135 +msgid "Your site does not have any account which uses the default \"admin\" username. " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:136 +msgid "This is good security practice." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:148 +msgid "Display name security" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:151 +msgid "When you submit a post or answer a comment, WordPress will usually display your \"nickname\"." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:152 +msgid "By default the nickname is set to the login (or user) name of your account." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:153 +msgid "From a security perspective, leaving your nickname the same as your user name is bad practice because it gives a hacker at least half of your account's login credentials." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:154 +msgid "Therefore to further tighten your site's security you are advised to change your nickname and Display name to be different from your Username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:160 +msgid "Modify accounts with identical login name and display name" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:169 +msgid "Your site currently has the following accounts which have an identical login name and display name." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:170 +msgid "Follow the link to edit the user profile of that particular user account, change Nickname, choose a different Display name compared to Username, and press the \"Update User\" button.)" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:185 +msgid "No action required." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:186 +msgid "Your site does not have a user account where the display name is identical to the username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:197 +msgid "Password tool" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:200 +msgid "Poor password selection is one of the most common weak points of many sites and is usually the first thing a hacker will try to exploit when attempting to break into your site." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:201 +msgid "Many people fall into the trap of using a simple word or series of numbers as their password. Such a predictable and simple password would take a competent hacker merely minutes to guess your password by using a simple script which cycles through the easy and most common combinations." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:202 +msgid "The longer and more complex your password is the harder it is for hackers to \"crack\" because more complex passwords require much greater computing power and time." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:203 +msgid "This section contains a useful password strength tool which you can use to check whether your password is sufficiently strong enough." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:208 +msgid "Password strength tool" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:210 +msgid "This password tool uses an algorithm which calculates how long it would take for your password to be cracked using the computing power of an off-the-shelf current model desktop PC with high end processor, graphics card and appropriate password cracking software." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:213 +msgid "Start typing a password." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:216 +msgid "It would take a desktop PC approximately" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:217 +msgid "1 sec" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:217 +msgid "to crack your password!" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:222 +msgid "Password Strength" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:245 +msgid "Username " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:245 +msgid " already exists. Please enter another value. " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:262 +msgid "The database update operation of the user account failed!" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:291 +msgid "You entered an invalid username. Please enter another value. " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:295 +msgid "Please enter a value for your username. " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:302 +msgid "Username successfully changed." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:322 +msgid "Account login name" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:331 +msgid "Edit user" +msgstr "" + +#: admin/wp-security-user-login-menu.php:54 +#: admin/wp-security-user-login-menu.php:474 +msgid "Failed login records" +msgstr "" + +#: admin/wp-security-user-login-menu.php:55 +#: classes/grade-system/wp-security-feature-item-manager.php:51 +msgid "Force logout" +msgstr "" + +#: admin/wp-security-user-login-menu.php:56 +#: admin/wp-security-user-login-menu.php:632 +msgid "Account activity logs" +msgstr "" + +#: admin/wp-security-user-login-menu.php:58 +#: admin/wp-security-user-login-menu.php:769 +msgid "Additional settings" +msgstr "" + +#: admin/wp-security-user-login-menu.php:81 +msgid "User login" +msgstr "" + +#: admin/wp-security-user-login-menu.php:118 +msgid "You entered a non-numeric value for the max login attempts field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:124 +msgid "You entered a non numeric value for the login retry time period field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:130 +msgid "You entered a non numeric value for the lockout time length field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:136 +msgid "You entered a non numeric value for the maximum lockout time length field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:141 +msgid "You entered an invalid minimum lockout time length, it must be less than the maximum lockout time length value." +msgstr "" + +#: admin/wp-security-user-login-menu.php:141 +msgid "Both have been set to the default values." +msgstr "" + +#: admin/wp-security-user-login-menu.php:160 +msgid "Please fill in one or more email addresses to notify." +msgstr "" + +#: admin/wp-security-user-login-menu.php:162 +msgid "You have entered one or more invalid email addresses." +msgstr "" + +#: admin/wp-security-user-login-menu.php:165 +msgid "It has been set to your WordPress admin email as default." +msgstr "" + +#: admin/wp-security-user-login-menu.php:250 +msgid "Login lockout configuration" +msgstr "" + +#: admin/wp-security-user-login-menu.php:254 +msgid "One of the ways hackers try to compromise sites is via a " +msgstr "" + +#: admin/wp-security-user-login-menu.php:254 +msgid "Brute force login attack" +msgstr "" + +#: admin/wp-security-user-login-menu.php:254 +msgid "This is where attackers use repeated login attempts until they guess the password." +msgstr "" + +#: admin/wp-security-user-login-menu.php:255 +msgid "Apart from choosing strong passwords, monitoring and blocking IP addresses which are involved in repeated login failures in a short period of time is a very effective way to stop these types of attacks." +msgstr "" + +#: admin/wp-security-user-login-menu.php:256 +msgid "You may also want to checkout our %s feature for another secure way to protect against these types of attacks." +msgstr "" + +#: admin/wp-security-user-login-menu.php:261 +msgid "Login lockout options" +msgstr "" + +#: admin/wp-security-user-login-menu.php:272 +msgid "Enable login lockout feature" +msgstr "" + +#: admin/wp-security-user-login-menu.php:275 +msgid "Check this if you want to enable the login lockout feature and apply the settings below" +msgstr "" + +#: admin/wp-security-user-login-menu.php:279 +msgid "Allow unlock requests" +msgstr "" + +#: admin/wp-security-user-login-menu.php:282 +msgid "Check this if you want to allow users to generate an automated unlock request link which will unlock their account" +msgstr "" + +#: admin/wp-security-user-login-menu.php:286 +msgid "Max login attempts" +msgstr "" + +#: admin/wp-security-user-login-menu.php:288 +msgid "Set the value for the maximum login retries before IP address is locked out" +msgstr "" + +#: admin/wp-security-user-login-menu.php:292 +msgid "Login retry time period (min)" +msgstr "" + +#: admin/wp-security-user-login-menu.php:294 +msgid "If the maximum number of failed login attempts for a particular IP address occur within this time period the plugin will lock out that address" +msgstr "" + +#: admin/wp-security-user-login-menu.php:299 +msgid "Minimum lockout time length" +msgstr "" + +#: admin/wp-security-user-login-menu.php:305 +msgid "Set the minimum time period in minutes of lockout." +msgstr "" + +#: admin/wp-security-user-login-menu.php:306 +msgid "This failed login lockout time will be tripled on each failed login." +msgstr "" + +#: admin/wp-security-user-login-menu.php:313 +msgid "Maximum lockout time length" +msgstr "" + +#: admin/wp-security-user-login-menu.php:318 +msgid "Set the maximum time period in minutes of lockout." +msgstr "" + +#: admin/wp-security-user-login-menu.php:319 +msgid "No IP address will be blocked for more than this time period after making a failed login attempt." +msgstr "" + +#: admin/wp-security-user-login-menu.php:324 +msgid "Display generic error message" +msgstr "" + +#: admin/wp-security-user-login-menu.php:327 +msgid "Check this if you want to show a generic error message when a login attempt fails" +msgstr "" + +#: admin/wp-security-user-login-menu.php:331 +msgid "Instantly lockout invalid usernames" +msgstr "" + +#: admin/wp-security-user-login-menu.php:334 +msgid "Check this if you want to instantly lockout login attempts with usernames which do not exist on your system" +msgstr "" + +#: admin/wp-security-user-login-menu.php:339 +msgid "Instantly lockout specific usernames" +msgstr "" + +#: admin/wp-security-user-login-menu.php:349 +msgid "Insert one username per line. Existing usernames are not blocked even if present in the list." +msgstr "" + +#: admin/wp-security-user-login-menu.php:354 +msgid "Notify by email" +msgstr "" + +#: admin/wp-security-user-login-menu.php:358 +msgid "Check this if you want to receive an email when someone has been locked out due to maximum failed login attempts" +msgstr "" + +#: admin/wp-security-user-login-menu.php:361 +msgid "Fill in one email address per line." +msgstr "" + +#: admin/wp-security-user-login-menu.php:365 +msgid "Each email address must be on a new line." +msgstr "" + +#: admin/wp-security-user-login-menu.php:366 +msgid "If a valid email address has not been filled in, it will not be saved." +msgstr "" + +#: admin/wp-security-user-login-menu.php:367 +msgid "The valid email address format is userid@example.com" +msgstr "" + +#: admin/wp-security-user-login-menu.php:368 +msgid "Example: %s" +msgstr "" + +#: admin/wp-security-user-login-menu.php:375 +msgid "Enable PHP backtrace in email" +msgstr "" + +#: admin/wp-security-user-login-menu.php:379 +msgid "Check this if you want to include the PHP backtrace in notification emails." +msgstr "" + +#: admin/wp-security-user-login-menu.php:379 +msgid "This is internal coding information which makes it easier to investigate where an issued occurred." +msgstr "" + +#: admin/wp-security-user-login-menu.php:389 +msgid "Currently locked out IP address ranges" +msgstr "" + +#: admin/wp-security-user-login-menu.php:394 +msgid "To see a list of all locked IP addresses and ranges go to the %s tab in the dashboard menu." +msgstr "" + +#: admin/wp-security-user-login-menu.php:399 +msgid "Login lockout IP whitelist settings" +msgstr "" + +#: admin/wp-security-user-login-menu.php:405 +msgid "Enable login lockout IP whitelist" +msgstr "" + +#: admin/wp-security-user-login-menu.php:416 +msgid "The addresses specified here will never be blocked by the login lockout feature." +msgstr "" + +#: admin/wp-security-user-login-menu.php:450 +msgid "User login feature - Delete all failed login records operation failed." +msgstr "" + +#: admin/wp-security-user-login-menu.php:452 +msgid "All records from the failed logins table were deleted successfully." +msgstr "" + +#: admin/wp-security-user-login-menu.php:467 +msgid "This tab displays the failed login attempts for your site." +msgstr "" + +#: admin/wp-security-user-login-menu.php:468 +msgid "The information below can be handy if you need to do security investigations because it will show you the IP range, username and ID (if applicable) and the time/date of the failed login attempt." +msgstr "" + +#: admin/wp-security-user-login-menu.php:469 +msgid "Failed login records that are older than %1$d days are purged automatically." +msgstr "" + +#: admin/wp-security-user-login-menu.php:508 +#: admin/wp-security-user-login-menu.php:517 +msgid "Delete all failed login records" +msgstr "" + +#: admin/wp-security-user-login-menu.php:514 +msgid "Click this button if you wish to delete all failed login records in one go." +msgstr "" + +#: admin/wp-security-user-login-menu.php:544 +msgid "You entered a non numeric value for the logout time period field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-user-login-menu.php:569 +msgid "Setting an expiry period for your WP administration session is a simple way to protect against unauthorized access to your site from your computer." +msgstr "" + +#: admin/wp-security-user-login-menu.php:570 +msgid "This feature allows you to specify a time period in minutes after which the admin session will expire and the user will be forced to log back in." +msgstr "" + +#: admin/wp-security-user-login-menu.php:575 +msgid "Force user logout options" +msgstr "" + +#: admin/wp-security-user-login-menu.php:587 +msgid "Enable force WP user logout" +msgstr "" + +#: admin/wp-security-user-login-menu.php:590 +msgid "Check this if you want to force a wp user to be logged out after a configured amount of time" +msgstr "" + +#: admin/wp-security-user-login-menu.php:594 +msgid "Logout the WP user after XX minutes" +msgstr "" + +#: admin/wp-security-user-login-menu.php:596 +msgid "(Minutes) The user will be forced to log back in after this time period has elapased." +msgstr "" + +#: admin/wp-security-user-login-menu.php:625 +msgid "This tab displays the activity for accounts registered with your site that have logged in using the WordPress login form." +msgstr "" + +#: admin/wp-security-user-login-menu.php:626 +msgid "The information below can be handy if you need to do security investigations because it will show you the last 100 recent login events by username, IP address and time/date." +msgstr "" + +#: admin/wp-security-user-login-menu.php:627 +msgid "Account activity logs that are older than %1$d days are purged automatically." +msgstr "" + +#: admin/wp-security-user-login-menu.php:697 +msgid "Refresh logged in user data" +msgstr "" + +#: admin/wp-security-user-login-menu.php:701 +msgid "Refresh data" +msgstr "" + +#: admin/wp-security-user-login-menu.php:706 +msgid "This tab displays all users who are currently logged into your site." +msgstr "" + +#: admin/wp-security-user-login-menu.php:707 +msgid "If you suspect there is a user or users who are logged in which should not be, you can block them by inspecting the IP addresses from the data below and adding them to your blacklist." +msgstr "" + +#: admin/wp-security-user-login-menu.php:708 +msgid "You can also instantly log them out by clicking on the \"Force logout\" link when you hover over the row in the user id column." +msgstr "" + +#: admin/wp-security-user-login-menu.php:713 +msgid "Currently logged in users" +msgstr "" + +#: admin/wp-security-user-login-menu.php:761 +msgid "WordPress 5.6 introduced a new feature called \"Application passwords\"." +msgstr "" + +#: admin/wp-security-user-login-menu.php:762 +msgid "This allows you to create a token from the WordPress dashboard which then can be used in the authorization header." +msgstr "" + +#: admin/wp-security-user-login-menu.php:763 +msgid "This feature allows you to disable application passwords as they can leave your site vulnerable to social engineering and phishing scams." +msgstr "" + +#: admin/wp-security-user-login-menu.php:780 +#: classes/grade-system/wp-security-feature-item-manager.php:53 +msgid "Disable application password" +msgstr "" + +#: admin/wp-security-user-login-menu.php:783 +msgid "Check this if you want to disable the application password." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:27 +msgid "Manual approval" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:28 +#: classes/grade-system/wp-security-feature-item-manager.php:59 +msgid "Registration CAPTCHA" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:29 +msgid "Registration honeypot" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:55 +msgid "User registration" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:115 +msgid "User registration settings" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:119 +msgid "Manually approve new registrations" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:123 +msgid "If your site allows people to create their own accounts via the WordPress registration form, then you can minimize spam or bogus registrations by manually approving each registration." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:124 +msgid "This feature will automatically set a newly registered account to \"pending\" until the administrator activates it. Therefore undesirable registrants will be unable to log in without your express approval." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:125 +msgid "You can view all accounts which have been newly registered via the handy table below and you can also perform bulk activation/deactivation/deletion tasks on each account." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:142 +msgid "Enable manual approval of new registrations" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:145 +msgid "Check this if you want to automatically disable all newly registered accounts so that you can approve them manually." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:154 +msgid "Approve registered users" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:206 +msgid "This feature allows you to add a CAPTCHA form on the WordPress registration page." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:207 +msgid "Users who attempt to register will also need to enter the answer to a simple mathematical question - if they enter the wrong answer, the plugin will not allow them to register." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:208 +msgid "Therefore, adding a CAPTCHA form on the registration page is another effective yet simple spam registration prevention technique." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:212 +msgid "Registration page CAPTCHA settings" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:219 +msgid "The core default behaviour for WordPress Multi Site regarding user registration is that all users are registered via the main site." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:220 +msgid "Therefore, if you would like to add a CAPTCHA form to the registration page for a Multi Site, please go to \"Registration CAPTCHA\" settings on the main site." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:235 +msgid "Enable CAPTCHA on registration page" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:238 +msgid "Check this if you want to insert a CAPTCHA form on the WordPress user registration page (if you allow user registration)." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:276 +msgid "This feature allows you to add a special hidden \"honeypot\" field on the WordPress registration page. This will only be visible to robots and not humans." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:277 +msgid "Since robots usually fill in every input field from a registration form, they will also submit a value for the special hidden honeypot field." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:279 +msgid "Therefore, if the plugin detects that this field has a value when the registration form is submitted, then the robot which is attempting to register on your site will be redirected to its localhost address - http://127.0.0.1." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:285 +msgid "Registration form honeypot settings" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:296 +msgid "Enable honeypot on registration page" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:299 +msgid "Check this if you want to enable the honeypot feature for the registration page" +msgstr "" + +#: classes/aios-ajax.php:89 +msgid "Invalid IP retrieve method." +msgstr "" + +#: classes/aios-ajax.php:131 +#: wp-security-core.php:258 +msgid "The security check failed; try refreshing the page." +msgstr "" + +#: classes/aios-ajax.php:152 +#: wp-security-core.php:268 +msgid "You are not allowed to run this command." +msgstr "" + +#: classes/aios-ajax.php:173 +#: wp-security-core.php:282 +msgid "Options can only be saved by network admin" +msgstr "" + +#: classes/aios-ajax.php:202 +msgid "The command \"%s\" was not found" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:39 +msgid "Remove WP generator meta tag" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:45 +msgid "Change display name" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:57 +msgid "Registration approval" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:61 +msgid "Enable registration honeypot" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:73 +msgid "WordPress files access" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:77 +msgid "IP and user agent blacklisting" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:81 +msgid "Enable basic firewall" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:82 +msgid "Enable pingback vulnerability protection" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:83 +msgid "Block access to debug log file" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:87 +msgid "Forbid proxy comments" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:88 +msgid "Deny bad queries" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:91 +msgid "5G/6G blacklist" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:97 +msgid "Enable IP blocking for 404 detection" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:101 +msgid "Enable rename login page" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:106 +msgid "Lost password CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:107 +msgid "Custom login CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:108 +msgid "Woo login CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:109 +msgid "Woo lost password CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:110 +msgid "Woo register CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:112 +msgid "Login IP whitelisting" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:114 +msgid "Enable login honeypot" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:118 +msgid "Comment CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:119 +msgid "Block spambots" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:121 +msgid "BuddyPress registration CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:123 +msgid "bbPress new topic CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item.php:29 +msgid "Basic" +msgstr "" + +#: classes/grade-system/wp-security-feature-item.php:31 +msgid "Intermediate" +msgstr "" + +#: classes/grade-system/wp-security-feature-item.php:33 +msgid "Advanced" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:47 +#: classes/wp-security-general-init-tasks.php:407 +msgid "Please enter an answer in digits:" +msgstr "Podaj wynik (liczba):" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:127 +msgid "one" +msgstr "jeden" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:128 +msgid "two" +msgstr "dwa" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:129 +msgid "three" +msgstr "trzy" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:130 +msgid "four" +msgstr "cztery" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:131 +msgid "five" +msgstr "pięć" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:132 +msgid "six" +msgstr "sześć" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:133 +msgid "seven" +msgstr "siedem" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:134 +msgid "eight" +msgstr "osiem" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:135 +msgid "nine" +msgstr "dziewięć" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:136 +msgid "ten" +msgstr "dziesięć" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:137 +msgid "eleven" +msgstr "jedenaście" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:138 +msgid "twelve" +msgstr "dwanaście" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:139 +msgid "thirteen" +msgstr "trzynaście" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:140 +msgid "fourteen" +msgstr "czternaście" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:141 +msgid "fifteen" +msgstr "piętnaście" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:142 +msgid "sixteen" +msgstr "szesnaście" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:143 +msgid "seventeen" +msgstr "siedemnaście" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:144 +msgid "eighteen" +msgstr "osiemnaście" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:145 +msgid "nineteen" +msgstr "dziewiętnaście" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-captcha.php:146 +msgid "twenty" +msgstr "dwadzieścia" + +#: classes/wp-security-cronjob-handler.php:34 +msgid "Every 15 minutes" +msgstr "" + +#: classes/wp-security-debug-logger.php:46 +msgid "Unable to get the reason why" +msgstr "" + +#: classes/wp-security-debug-logger.php:47 +msgid "Unable to clear the logs" +msgstr "" + +#: classes/wp-security-file-scan.php:85 +msgid "All In One WP Security - File change detected!" +msgstr "" + +#: classes/wp-security-file-scan.php:87 +msgid "A file change was detected on your system for site URL" +msgstr "" + +#: classes/wp-security-file-scan.php:87 +msgid ". Scan was generated on" +msgstr "" + +#: classes/wp-security-file-scan.php:88 +msgid "A summary of the scan results is shown below:" +msgstr "" + +#: classes/wp-security-file-scan.php:91 +msgid "Login to your site to view the scan details." +msgstr "" + +#: classes/wp-security-file-scan.php:313 +msgid "The following files were added to your host" +msgstr "" + +#: classes/wp-security-file-scan.php:315 +#: classes/wp-security-file-scan.php:323 +#: classes/wp-security-file-scan.php:332 +msgid "modified on: " +msgstr "" + +#: classes/wp-security-file-scan.php:321 +msgid "The following files were removed from your host" +msgstr "" + +#: classes/wp-security-file-scan.php:330 +msgid "The following files were changed on your host" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:212 +#: classes/wp-security-general-init-tasks.php:481 +msgid "Application passwords have been disabled by All In One WP Security & Firewall plugin." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:428 +#: classes/wp-security-general-init-tasks.php:541 +#: classes/wp-security-general-init-tasks.php:574 +#: classes/wp-security-user-login.php:137 +#: classes/wp-security-user-registration.php:74 +msgid "ERROR: Your answer was incorrect - please try again." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:463 +msgid "Enter something special:" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:476 +msgid "Application passwords" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:485 +msgid "Change setting" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:487 +msgid "Site admin can only change this setting." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:516 +msgid "Error: You entered an incorrect CAPTCHA answer. Please go back and try again." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:558 +msgid "Your CAPTCHA answer was incorrect - please try again." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:567 +msgid "ERROR: Your IP address is currently locked please contact the administrator!" +msgstr "" + +#. translators: %s: Admin Dashboard > WP Security > Brute Force > Login CAPTCHA Tab Link +#: classes/wp-security-general-init-tasks.php:642 +msgid "Your Google reCAPTCHA site key is wrong. Please fill the correct reCAPTCHA keys %s to use the Google reCAPTCHA feature." +msgstr "" + +#. translators: %s: Admin Dashboard > WP Security > Brute Force > Login CAPTCHA Tab Link +#: classes/wp-security-general-init-tasks.php:642 +#: classes/wp-security-notices.php:99 +msgid "here" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +msgid "Would you like All In One WP Security & Firewall to re-insert the security rules in your .htaccess file which were cleared when you deactivated the plugin?" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +#: templates/may-also-like.php:40 +#: templates/may-also-like.php:43 +#: templates/may-also-like.php:54 +#: templates/may-also-like.php:57 +#: templates/may-also-like.php:68 +#: templates/may-also-like.php:71 +#: templates/may-also-like.php:91 +#: templates/may-also-like.php:103 +#: templates/may-also-like.php:115 +#: templates/may-also-like.php:127 +#: templates/may-also-like.php:139 +#: templates/may-also-like.php:151 +#: templates/may-also-like.php:168 +#: templates/may-also-like.php:171 +#: templates/may-also-like.php:183 +#: templates/may-also-like.php:195 +#: templates/may-also-like.php:207 +#: templates/may-also-like.php:219 +#: templates/may-also-like.php:231 +#: templates/may-also-like.php:243 +#: templates/may-also-like.php:252 +#: templates/may-also-like.php:255 +#: templates/may-also-like.php:264 +#: templates/may-also-like.php:267 +#: templates/may-also-like.php:279 +#: templates/may-also-like.php:297 +#: templates/may-also-like.php:309 +#: templates/may-also-like.php:327 +#: templates/may-also-like.php:339 +#: templates/may-also-like.php:351 +#: templates/may-also-like.php:368 +#: templates/may-also-like.php:380 +msgid "Yes" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +#: templates/may-also-like.php:88 +#: templates/may-also-like.php:100 +#: templates/may-also-like.php:112 +#: templates/may-also-like.php:124 +#: templates/may-also-like.php:136 +#: templates/may-also-like.php:148 +#: templates/may-also-like.php:180 +#: templates/may-also-like.php:192 +#: templates/may-also-like.php:204 +#: templates/may-also-like.php:216 +#: templates/may-also-like.php:228 +#: templates/may-also-like.php:240 +#: templates/may-also-like.php:276 +#: templates/may-also-like.php:294 +#: templates/may-also-like.php:306 +#: templates/may-also-like.php:324 +#: templates/may-also-like.php:336 +#: templates/may-also-like.php:348 +#: templates/may-also-like.php:365 +#: templates/may-also-like.php:377 +#: templates/notices/custom-notice.php:27 +msgid "No" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:674 +msgid "Your registration is pending approval." +msgstr "" + +#: classes/wp-security-notices.php:25 +msgid "The All in One Security plugin has disabled the login whitelist setting that you have enabled in the past." +msgstr "" + +#: classes/wp-security-notices.php:29 +msgid "Your website is running on an Apache webserver, the login whitelisting might not be functional until the recent update of AIOS (because it relied upon Apache-specific module features)." +msgstr "" + +#: classes/wp-security-notices.php:31 +msgid "Your website is running on a non-Apache webserver, so the login whitelisting was not functional until the recent update of AIOS (because it relied upon Apache-specific features)." +msgstr "" + +#: classes/wp-security-notices.php:33 +msgid "It began working with AIOS version 5.0.8." +msgstr "" + +#: classes/wp-security-notices.php:33 +msgid "We have disabled it so that your login page will not be blocked unexpectedly." +msgstr "" + +#: classes/wp-security-notices.php:42 +msgid "Would you like to re-enable login whitelisting?" +msgstr "" + +#: classes/wp-security-notices.php:48 +msgid "Removed database backup feature from the All In One WP Security & Firewall plugin" +msgstr "" + +#: classes/wp-security-notices.php:50 +msgid "Beginning with version 5.0.0, AIOS has replaced the AIOS backup method with the superior UpdraftPlus method." +msgstr "" + +#: classes/wp-security-notices.php:51 +msgid "It remains free and is fully supported by the UpdraftPlus team." +msgstr "" + +#: classes/wp-security-notices.php:54 +msgid "You are seeing this notice because you have previously set up automated database backups in AIOS." +msgstr "" + +#: classes/wp-security-notices.php:55 +msgid "Would you like to set up scheduled backups with UpdraftPlus?" +msgstr "" + +#: classes/wp-security-notices.php:61 +msgid "Setup UpdraftPlus backup plugin" +msgstr "" + +#: classes/wp-security-notices.php:67 +msgid "Important: set up your IP address detection settings" +msgstr "" + +#: classes/wp-security-notices.php:69 +msgid "The All in One Security plugin couldn't be certain about the correct method to detect the IP address for your site visitors with your currently-configured IP address detection settings." +msgstr "" + +#: classes/wp-security-notices.php:70 +msgid "It is important for your security to set the IP address detection settings properly." +msgstr "" + +#: classes/wp-security-notices.php:73 +msgid "Please go to the settings and set them now." +msgstr "" + +#: classes/wp-security-notices.php:79 +msgid "Setup IP address detection settings" +msgstr "" + +#: classes/wp-security-notices.php:85 +msgid "Important: Disabled login whitelist setting" +msgstr "" + +#: classes/wp-security-notices.php:91 +msgid "Turn it back on" +msgstr "" + +#: classes/wp-security-notices.php:92 +msgid "Edit the settings" +msgstr "" + +#: classes/wp-security-notices.php:95 +msgid "Keep it off" +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Hey - We noticed All In One WP Security & Firewall has kept your site safe for a while. If you like us, please consider leaving a positive review to spread the word. Or if you have any issues or questions please leave us a support message %s." +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Thank you so much!" +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Team All In One WP Security & Firewall" +msgstr "" + +#: classes/wp-security-notices.php:109 +msgid "Enhance your security even more by backing up your site" +msgstr "" + +#: classes/wp-security-notices.php:110 +msgid "UpdraftPlus is the world's most trusted backup plugin from the owners of All In One WP Security & Firewall" +msgstr "" + +#: classes/wp-security-notices.php:121 +msgid "After you've secured your site, we recommend you install our WP-Optimize plugin to streamline it for better website performance." +msgstr "" + +#: classes/wp-security-process-renamed-login-page.php:152 +msgid "Not available." +msgstr "" + +#: classes/wp-security-two-factor-login.php:34 +msgid "Two factor authentication - Admin settings" +msgstr "" + +#: classes/wp-security-two-factor-login.php:97 +msgid "Two Factor Auth" +msgstr "" + +#: classes/wp-security-two-factor-login.php:153 +msgid "PHP OpenSSL or mcrypt module required" +msgstr "" + +#: classes/wp-security-two-factor-login.php:153 +msgid "The All In One WP Security plugin's Two Factor Authentication module requires either the PHP openssl (preferred) or mcrypt module to be installed. Please ask your web hosting company to install one of them." +msgstr "" + +#: classes/wp-security-user-login.php:71 +msgid "You have disabled login lockout by defining the AIOS_DISABLE_LOGIN_LOCKOUT constant value as true, and the login lockout setting has enabled it." +msgstr "" + +#. translators: 1: Locked IP Addresses admin page link +#: classes/wp-security-user-login.php:73 +msgid "Delete your login lockout IP from %s and define the AIOS_DISABLE_LOGIN_LOCKOUT constant value as false." +msgstr "" + +#: classes/wp-security-user-login.php:100 +msgid "ERROR: Access from your IP address has been blocked for security reasons. Please contact the administrator." +msgstr "" + +#: classes/wp-security-user-login.php:108 +msgid "Service temporarily unavailable" +msgstr "" + +#: classes/wp-security-user-login.php:163 +msgid "ACCOUNT PENDING: Your account is currently not active. An administrator needs to activate your account before you can login." +msgstr "" + +#: classes/wp-security-user-login.php:242 +msgid "ERROR: Invalid login credentials." +msgstr "" + +#: classes/wp-security-user-login.php:392 +msgid "Site Lockout Notification" +msgstr "" + +#: classes/wp-security-user-login.php:393 +msgid "User login lockout events had occurred due to too many failed login attempts or invalid username:" +msgstr "" + +#: classes/wp-security-user-login.php:396 +msgid "Username:" +msgstr "" + +#: classes/wp-security-user-login.php:397 +msgid "IP address:" +msgstr "" + +#: classes/wp-security-user-login.php:399 +msgid "IP range:" +msgstr "" + +#: classes/wp-security-user-login.php:404 +msgid "Log into your site WordPress administration panel to see the duration of the lockout or to unlock the user." +msgstr "" + +#: classes/wp-security-user-login.php:515 +msgid "Unlock request notification" +msgstr "" + +#: classes/wp-security-user-login.php:516 +msgid "You have requested for the account with email address %s to be unlocked. Please click the link below to unlock your account:" +msgstr "" + +#: classes/wp-security-user-login.php:516 +msgid "Unlock link: %s" +msgstr "" + +#: classes/wp-security-user-login.php:516 +msgid "After clicking the above link you will be able to login to the WordPress administration panel." +msgstr "" + +#: classes/wp-security-user-login.php:739 +msgid "Your session has expired because it has been over %d minutes since your last login." +msgstr "" + +#: classes/wp-security-user-login.php:740 +#: classes/wp-security-user-login.php:744 +msgid "Please log back in to continue." +msgstr "" + +#: classes/wp-security-user-login.php:743 +msgid "You were logged out because you just changed the \"admin\" username." +msgstr "" + +#: classes/wp-security-user-login.php:773 +msgid "Request unlock" +msgstr "" + +#: classes/wp-security-user-registration.php:68 +msgid "ERROR: You are not allowed to register because your IP address is currently locked!" +msgstr "" + +#: classes/wp-security-utility-ip-address.php:217 +#: classes/wp-security-utility-ip-address.php:231 +#: classes/wp-security-utility-ip-address.php:245 +#: classes/wp-security-utility-ip-address.php:257 +#: classes/wp-security-utility-ip-address.php:269 +msgid " is not a valid ip address format." +msgstr "" + +#: classes/wp-security-utility-ip-address.php:274 +msgid "You cannot ban your own IP address: " +msgstr "" + +#: classes/wp-security-utility.php:254 +msgid "This feature can only be configured by the \"superadmin\" on the main site." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:32 +msgid "ERROR: Unable to process your request!" +msgstr "" + +#: other-includes/wp-security-unlock-request.php:45 +msgid "Please enter a valid email address" +msgstr "" + +#: other-includes/wp-security-unlock-request.php:57 +msgid "User account not found!" +msgstr "" + +#: other-includes/wp-security-unlock-request.php:71 +msgid "Error: No locked entry was found in the database with your IP address range." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:76 +msgid "An email has been sent to you with the unlock instructions." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:93 +msgid "You are here because you have been locked out due to too many incorrect login attempts." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:94 +msgid "Please enter your email address and you will receive an email with instructions on how to unlock yourself." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:104 +msgid "Email Address" +msgstr "" + +#: other-includes/wp-security-unlock-request.php:108 +msgid "Send unlock request" +msgstr "" + +#: templates/admin/incompatible-plugin.php:6 +msgid "Two Factor Authentication" +msgstr "" + +#: templates/admin/incompatible-plugin.php:10 +msgid "Two Factor Authentication currently disabled" +msgstr "" + +#: templates/admin/incompatible-plugin.php:12 +#: templates/admin/incompatible-plugin.php:16 +msgid "Two factor authentication in All In One WP Security is currently disabled because the incompatible plugin %s is active." +msgstr "" + +#: templates/automated-database-backup.php:4 +msgid "Automated scheduled backups" +msgstr "" + +#: templates/automated-database-backup.php:9 +msgid "Automate backup in the UpdraftPlus plugin" +msgstr "" + +#: templates/automated-database-backup.php:19 +msgid "The AIOS 5.0.0 version release has removed the automated backup feature." +msgstr "" + +#: templates/automated-database-backup.php:20 +msgid "The AIOS automated backup had issues that made it less robust than we could be happy with." +msgstr "" + +#: templates/automated-database-backup.php:21 +msgid "Follow this link to automate backups in the superior UpdraftPlus backup plugin." +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:5 +msgid "Each IP address must be on a new line." +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:6 +msgid "To specify an IPv4 range use a wildcard \"*\" character. Acceptable ways to use wildcards is shown in the examples below:" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:7 +msgid "Example 1: 195.47.89.*" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:8 +msgid "Example 2: 195.47.*.*" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:9 +msgid "Example 3: 195.*.*.*" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:10 +msgid "To specify an IPv6 range use CIDR format as shown in the examples below:" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:11 +msgid "Example 4: 2401:4900:54c3:af15:2:2:5dc0:0/112" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:12 +msgid "Example 5: 2001:db8:1263::/48" +msgstr "" + +#: templates/may-also-like.php:5 +msgid "All-In-One Security (AIOS) Free vs Premium Comparison Chart" +msgstr "" + +#: templates/may-also-like.php:7 +msgid "FAQs" +msgstr "" + +#: templates/may-also-like.php:9 +msgid "Ask a pre-sales question" +msgstr "" + +#: templates/may-also-like.php:17 +msgid "All In One WP Security & Firewall Free" +msgstr "" + +#: templates/may-also-like.php:26 +#: templates/may-also-like.php:386 +msgid "Installed" +msgstr "" + +#: templates/may-also-like.php:29 +#: templates/may-also-like.php:389 +msgid "Upgrade now" +msgstr "" + +#: templates/may-also-like.php:34 +msgid "Login security feature suite" +msgstr "" + +#: templates/may-also-like.php:35 +msgid "Protect against brute-force attacks and keep bots at bay." +msgstr "" + +#: templates/may-also-like.php:35 +msgid "AIOS takes WordPress' default login security features to a whole new level." +msgstr "" + +#: templates/may-also-like.php:37 +msgid "To see all login security features, visit %s" +msgstr "" + +#: templates/may-also-like.php:48 +msgid "Firewall and file protection feature suite" +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Protection from the latest exploits." +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Activate firewall settings ranging from basic, intermediate and advanced." +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Get comprehensive, instant protection with All-in-One Security." +msgstr "" + +#: templates/may-also-like.php:51 +msgid "To see all firewall and file protection features, visit %s" +msgstr "" + +#: templates/may-also-like.php:62 +msgid "Content protection feature suite" +msgstr "" + +#: templates/may-also-like.php:63 +msgid "Eliminate spam and protect your content to dramatically improve your website's interactions with search engines." +msgstr "" + +#: templates/may-also-like.php:65 +msgid "To see all content protection features, visit %s" +msgstr "" + +#: templates/may-also-like.php:76 +msgid "Malware scanning" +msgstr "" + +#: templates/may-also-like.php:77 +msgid "Finding out by accident that your site has been infected with malware is too late." +msgstr "" + +#: templates/may-also-like.php:79 +msgid "Malware can have a dramatic effect on your site's search rankings and you may not even know about it." +msgstr "" + +#: templates/may-also-like.php:79 +msgid "It can slow your website down, access customer data, send unsolicited emails, change your content or prevent users from accessing it." +msgstr "" + +#: templates/may-also-like.php:84 +msgid "Automatic malware scanning" +msgstr "" + +#: templates/may-also-like.php:85 +msgid "Best-in-class scanning for the latest malware, trojans and spyware 24/7." +msgstr "" + +#: templates/may-also-like.php:96 +msgid "Response time monitoring" +msgstr "" + +#: templates/may-also-like.php:97 +msgid "You'll know immediately if your website's response time is negatively affected." +msgstr "" + +#: templates/may-also-like.php:108 +msgid "Up-time monitoring" +msgstr "" + +#: templates/may-also-like.php:109 +msgid "AIOS checks your website's uptime every 5 minutes." +msgstr "" + +#: templates/may-also-like.php:109 +msgid "We'll notify you straight away if your site/server goes down." +msgstr "" + +#: templates/may-also-like.php:120 +msgid "Prevents blacklisting by search engines" +msgstr "" + +#: templates/may-also-like.php:121 +msgid "AIOS monitors your site's blacklist status daily." +msgstr "" + +#: templates/may-also-like.php:121 +msgid "We'll notify you within 24 hours if something's amiss so you can take action, before it's too late." +msgstr "" + +#: templates/may-also-like.php:132 +msgid "Flexible assignment" +msgstr "" + +#: templates/may-also-like.php:133 +msgid "Register and remove websites from the scanning service at any time." +msgstr "" + +#: templates/may-also-like.php:144 +msgid "Malware reports" +msgstr "" + +#: templates/may-also-like.php:145 +msgid "Reports are available via the 'My Account' page and directly via email." +msgstr "" + +#: templates/may-also-like.php:156 +msgid "Flexible two-factor authentication" +msgstr "" + +#: templates/may-also-like.php:157 +msgid "With Two-Factor Authentication (TFA) users enter their username and password and a one-time code sent to a device to login." +msgstr "" + +#: templates/may-also-like.php:159 +msgid "TFA is a feature in both our free and premium packages, but AIOS Premium affords whole new levels of control over how TFA is implemented." +msgstr "" + +#: templates/may-also-like.php:164 +msgid "Authenticator apps" +msgstr "" + +#: templates/may-also-like.php:165 +msgid "Supports TOTP and HOTP protocols." +msgstr "" + +#: templates/may-also-like.php:165 +msgid "TFA Can be used with Google Authenticator, Microsoft Authenticator, Authy and many more." +msgstr "" + +#: templates/may-also-like.php:176 +msgid "Role specific configuration" +msgstr "" + +#: templates/may-also-like.php:177 +msgid "Make it compulsory for certain roles e.g. for admin and editor roles." +msgstr "" + +#: templates/may-also-like.php:188 +msgid "Require TFA after a set time period" +msgstr "" + +#: templates/may-also-like.php:189 +msgid "For example you could require all admins to have TFA once their accounts are a week old." +msgstr "" + +#: templates/may-also-like.php:200 +msgid "Trusted devices - control how often TFA is required" +msgstr "" + +#: templates/may-also-like.php:201 +msgid "Ask for TFA after a chosen number of days for trusted devices instead of on every login." +msgstr "" + +#: templates/may-also-like.php:212 +msgid "Anti-bot protection" +msgstr "" + +#: templates/may-also-like.php:213 +msgid "Option to hide the existence of forms on WooCommerce login pages unless JavaScript is active." +msgstr "" + +#: templates/may-also-like.php:224 +msgid "Customise TFA design layout" +msgstr "" + +#: templates/may-also-like.php:225 +msgid "Customise the design of TFA so it aligns with your existing web design." +msgstr "" + +#: templates/may-also-like.php:236 +msgid "TFA emergency codes" +msgstr "" + +#: templates/may-also-like.php:237 +msgid "Generate a one-time use emergency code to allow access if your device is lost." +msgstr "" + +#: templates/may-also-like.php:248 +msgid "TFA multisite compatibility" +msgstr "" + +#: templates/may-also-like.php:249 +msgid "TFA is Compatible with multisite networks and sub-sites." +msgstr "" + +#: templates/may-also-like.php:260 +msgid "TFA support for common login forms" +msgstr "" + +#: templates/may-also-like.php:261 +msgid "Supports WooCommerce, Affiliates-WP and Theme my Login login forms." +msgstr "" + +#: templates/may-also-like.php:272 +msgid "TFA support for other login forms" +msgstr "" + +#: templates/may-also-like.php:273 +msgid "Supports Elementor Pro, bbPress and all third-party login forms without any further coding needed." +msgstr "" + +#: templates/may-also-like.php:284 +msgid "Smart 404 blocking" +msgstr "" + +#: templates/may-also-like.php:285 +msgid "404 errors can occur when someone legitimately mistypes a URL, but they're also generated by hackers searching for weaknesses in your site." +msgstr "" + +#: templates/may-also-like.php:290 +msgid "Automatically and permanently blocks bots producing 404s" +msgstr "" + +#: templates/may-also-like.php:291 +msgid "AIOS Premium provides more protection than the competition by automatically and permanently blocking IP addresses of bots and hackers based on how many 404 errors they generate." +msgstr "" + +#: templates/may-also-like.php:302 +msgid "404 error charts" +msgstr "" + +#: templates/may-also-like.php:303 +msgid "Handy charts keep you informed of how many 404s have occurred and which IP address or country is producing them." +msgstr "" + +#: templates/may-also-like.php:314 +msgid "Country blocking" +msgstr "" + +#: templates/may-also-like.php:315 +msgid "Most malicious attacks come from a handful of countries and so it's possible to prevent most attacks with our country blocking tool." +msgstr "" + +#: templates/may-also-like.php:320 +msgid "Block traffic based on country of origin" +msgstr "" + +#: templates/may-also-like.php:321 +msgid "AIOS Premium utilises an IP database that promises 99.5% accuracy." +msgstr "" + +#: templates/may-also-like.php:332 +msgid "Block traffic to specific pages based on country of origin" +msgstr "" + +#: templates/may-also-like.php:333 +msgid "Block access to your whole site or on a page-by-page basis." +msgstr "" + +#: templates/may-also-like.php:344 +msgid "Whitelist some users from blocked countries" +msgstr "" + +#: templates/may-also-like.php:345 +msgid "Whitelist IP addresses or IP ranges even if they are part of a blocked country." +msgstr "" + +#: templates/may-also-like.php:356 +msgid "Premium support" +msgstr "" + +#: templates/may-also-like.php:361 +msgid "Unlimited support" +msgstr "" + +#: templates/may-also-like.php:362 +msgid "Personalised, email support from our team of Security experts, as and when you need it." +msgstr "" + +#: templates/may-also-like.php:373 +msgid "Guaranteed response time" +msgstr "" + +#: templates/may-also-like.php:374 +msgid "We offer a guaranteed response time of three days." +msgstr "" + +#: templates/may-also-like.php:374 +msgid "99% of our Premium customers receive a response to their enquiry within 24 hours during the working week." +msgstr "" + +#: templates/may-also-like.php:397 +msgid "Our other plugins" +msgstr "" + +#: templates/may-also-like.php:411 +msgid "UpdraftPlus – the ultimate protection for your site, hard work and business" +msgstr "" + +#: templates/may-also-like.php:412 +msgid "Simplifies backups and restoration." +msgstr "" + +#: templates/may-also-like.php:412 +msgid "It is the world's highest ranking and most popular scheduled backup plugin, with over three million currently-active installs." +msgstr "" + +#: templates/may-also-like.php:413 +#: templates/may-also-like.php:419 +#: templates/may-also-like.php:425 +#: templates/may-also-like.php:431 +msgid "Try for free" +msgstr "" + +#: templates/may-also-like.php:417 +msgid "WP-Optimize – keep your database fast and efficient" +msgstr "" + +#: templates/may-also-like.php:418 +msgid "Makes your site fast and efficient." +msgstr "" + +#: templates/may-also-like.php:418 +msgid "It cleans the database, compresses images and caches pages for ultimate speed." +msgstr "" + +#: templates/may-also-like.php:423 +msgid "UpdraftCentral – save hours managing multiple WP sites from one place" +msgstr "" + +#: templates/may-also-like.php:424 +msgid "Highly efficient way to manage, optimize, update and backup multiple websites from one place." +msgstr "" + +#: templates/may-also-like.php:429 +msgid "Easy Updates Manager" +msgstr "" + +#: templates/may-also-like.php:430 +msgid "Keeps your WordPress site up to date and bug free." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:2 +msgid "IP address detection settings" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:6 +msgid "The IP address detection settings allow you to specify how visitors' IP addresses are made known to PHP (and hence to WordPress and its plugins)." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:7 +msgid "Usually, this is automatic and there is only one choice." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:8 +msgid "However in some setups, such as those using proxies (including load-balancers and security firewalls like Cloudflare), it may be necessary to set this manually." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "Attention" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "It is important to set this correctly - otherwise you may make it possible for a hacker to ban all your visitors (e.g. via banning Cloudflare from connecting to you) instead of being banned himself." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "The default is to use the REMOTE_ADDR PHP server variable. If this variable does not contain the visitor's IP address, then whilst you can make a different selection below, it is better to ask your web hosting company to have it correctly set." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:10 +msgid "This is the most secure setup, because when set correctly it is immune from being spoofed by an attacker." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:16 +msgid "You have no available IP address detection method(s); you must contact your web hosting company." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:22 +#: templates/menus/settings/advanced-settings.php:27 +#: templates/menus/settings/advanced-settings.php:32 +msgid "Your detected IP address according to %s:" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:38 +msgid "If your site is setup on localhost, you won't see your external IP address using your server's IP detection setting; but on a localhost-served site (not available to the outside world), the setting is irrelevant and can be ignored." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:61 +msgid "Choose a $_SERVER variable you would like to detect visitors' IP address using." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:67 +msgid "If your chosen server variable fails the plugin will automatically fall back to retrieving the IP address from $_SERVER[\"REMOTE_ADDR\"]" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:73 +msgid "Your IP address if using this setting:" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:75 +msgid "fetching..." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:81 +#: templates/menus/settings/advanced-settings.php:190 +msgid "getting..." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:89 +msgid "look-up possibly blocked by an ad-blocker or similar tool" +msgstr "" + +#: templates/notices/cookie-based-brute-force-prevention-disabled.php:4 +msgid "Cookie based brute force login prevention currently disabled" +msgstr "" + +#: templates/notices/cookie-based-brute-force-prevention-disabled.php:6 +msgid "Cookie based brute force login prevention is currently disabled via the AIOS_DISABLE_COOKIE_BRUTE_FORCE_PREVENTION constant (which is mostly likely to be defined in your wp-config.php)" +msgstr "" + +#: templates/notices/disable-login-whitelist.php:4 +msgid "Login whitelisting currently disabled" +msgstr "" + +#: templates/notices/disable-login-whitelist.php:6 +msgid "Login whitelisting is currently disabled via the AIOS_DISABLE_LOGIN_WHITELIST constant (which is mostly likely to be defined in your wp-config.php)" +msgstr "" + +#: templates/notices/horizontal-notice.php:8 +#: templates/notices/horizontal-notice.php:40 +msgid "notice image" +msgstr "" + +#: templates/notices/horizontal-notice.php:18 +msgid "Ok, you deserve it" +msgstr "" + +#: templates/notices/horizontal-notice.php:22 +msgid "Maybe later" +msgstr "" + +#: templates/notices/horizontal-notice.php:26 +msgid "Never" +msgstr "" + +#: templates/notices/horizontal-notice.php:66 +msgid "Get UpdraftCentral" +msgstr "" + +#: templates/notices/horizontal-notice.php:68 +msgid "Get UpdraftPlus" +msgstr "" + +#: templates/notices/horizontal-notice.php:70 +msgid "Get WP-Optimize" +msgstr "" + +#: templates/notices/horizontal-notice.php:72 +msgid "Find out more." +msgstr "" + +#: templates/notices/horizontal-notice.php:74 +msgid "Sign up" +msgstr "" + +#: templates/notices/horizontal-notice.php:76 +msgid "Go there" +msgstr "" + +#: templates/notices/horizontal-notice.php:78 +msgid "Read more" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:4 +msgid "Dismiss (for %s months)" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:6 +msgid "Thank you for installing All In One WP Security & Firewall!" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:13 +msgid "Super-charge and secure your WordPress site even more with our other top plugins:" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:17 +msgid "%s makes your site fast and efficient. It cleans the database, compresses images and caches pages for ultimate speed." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:21 +msgid "%s simplifies backups and restoration. It is the world's highest ranking and most popular scheduled backup plugin, with over three million currently-active installs." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:25 +msgid "%s is a highly efficient way to manage, optimize, update and backup multiple websites from one place." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:29 +msgid "%s is a WordPress subscription extension for WooCommerce store owners." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:33 +msgid "More quality plugins" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:33 +msgid "Premium WooCommerce plugins" +msgstr "" + +#: templates/partials/non-apache-feature-notice.php:9 +msgid "This feature works only on the Apache server." +msgstr "" + +#: templates/partials/non-apache-feature-notice.php:10 +msgid "You are using the non-apache server %s, so this feature won't work on your site." +msgstr "" + +#: wp-security-core.php:236 +#: wp-security.php:45 +msgid "This plugin requires PHP version %s." +msgstr "" + +#: wp-security-core.php:237 +msgid "Current site PHP version is %s." +msgstr "" + +#: wp-security-core.php:238 +#: wp-security.php:47 +msgid "You will need to ask your web hosting company to upgrade." +msgstr "" + +#: wp-security-core.php:397 +msgid "Error:" +msgstr "" + +#: wp-security-core.php:397 +msgid "template not found" +msgstr "" + +#: wp-security.php:44 +msgid "All In One WP Security and Firewall plugin has been deactivated." +msgstr "" + +#: wp-security.php:46 +msgid "Your current PHP version is %s." +msgstr "" diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-pt_BR.mo b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-pt_BR.mo new file mode 100755 index 0000000000000000000000000000000000000000..2e549237de447ec85ff88c05b0774601d3cce364 GIT binary patch literal 136583 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 B+{gd` literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-pt_BR.po b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-pt_BR.po new file mode 100755 index 00000000..f9f7fb83 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-pt_BR.po @@ -0,0 +1,5994 @@ +msgid "" +msgstr "" +"Project-Id-Version: All In One WP Security v4.0.7\n" +"POT-Creation-Date: 2016-04-14 11:14-0300\n" +"PO-Revision-Date: 2016-04-18 13:26-0300\n" +"Last-Translator: Gilvanilson Santos \n" +"Language-Team: GVSANTOS Group \n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Poedit 1.8.7\n" +"X-Poedit-Basepath: .\n" +"X-Poedit-KeywordsList: _:1;gettext:1;dgettext:2;ngettext:1,2;dngettext:2,3;__:1;_e:1;_c:1;_n:1,2;_n_noop:1,2;_nc:1,2;__ngettext:1,2;__ngettext_noop:1,2;_x:1,2c;_ex:1,2c;_nx:1,2,4c;_nx_noop:1,2,3c;_n_js:1,2;_nx_js:1,2,3c;esc_attr__:1;esc_html__:1;esc_attr_e:1;esc_html_e:1;esc_attr_x:1,2c;esc_html_x:1,2c;comments_number_link:2,3;t:1;st:1;trans:1;transChoice:1,2\n" +"X-Poedit-SearchPath-0: ../../plugins/all-in-one-wp-security-and-firewall\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Textdomain-Support: yes\n" + +#. Plugin Name of the plugin +msgid "All In One WP Security" +msgstr "" + +#. Plugin URI of the plugin +msgid "https://wordpress.org/plugins/all-in-one-wp-security-and-firewall/" +msgstr "" + +#. Description of the plugin +# @ all-in-one-wp-security-and-firewall +msgid "All round best WordPress security plugin!" +msgstr "Em todas as partes o melhor plugin de segurança WordPress!" + +#. Author of the plugin +msgid "All In One WP Security & Firewall Team" +msgstr "" + +#. Author URI of the plugin +msgid "https://teamupdraft.com/" +msgstr "" + +#: admin/general/wp-security-list-table.php:483 +msgid "Are you sure you want to perform this bulk action?" +msgstr "" + +#: admin/wp-security-admin-init.php:259 +msgid "Unexpected response:" +msgstr "" + +#: admin/wp-security-admin-init.php:290 +msgid "Enjoyed %1$s? Please leave us a %2$s rating. We really appreciate your support!" +msgstr "" + +#: admin/wp-security-admin-init.php:414 +#: classes/wp-security-two-factor-login.php:95 +msgid "WP Security" +msgstr "Segurança WP" + +#: admin/wp-security-admin-init.php:415 +#: admin/wp-security-dashboard-menu.php:26 +#: admin/wp-security-dashboard-menu.php:76 +msgid "Dashboard" +msgstr "Painel" + +#: admin/wp-security-admin-init.php:416 +#: admin/wp-security-settings-menu.php:95 +msgid "Settings" +msgstr "Configurações" + +#: admin/wp-security-admin-init.php:417 +msgid "User Accounts" +msgstr "Contas de usuários" + +#: admin/wp-security-admin-init.php:418 +msgid "User Login" +msgstr "Login de usuário" + +#: admin/wp-security-admin-init.php:419 +msgid "User Registration" +msgstr "Registro de usuário" + +#: admin/wp-security-admin-init.php:420 +msgid "Database Security" +msgstr "Segurança do DB" + +#: admin/wp-security-admin-init.php:424 +msgid "Filesystem Security" +msgstr "Segurança de arquivos" + +#: admin/wp-security-admin-init.php:429 +msgid "Blacklist Manager" +msgstr "Gerenciar lista negra" + +#: admin/wp-security-admin-init.php:434 +#: admin/wp-security-firewall-menu.php:60 +msgid "Firewall" +msgstr "Firewall" + +#: admin/wp-security-admin-init.php:436 +msgid "Brute Force" +msgstr "Força bruta" + +#: admin/wp-security-admin-init.php:437 +msgid "Spam Prevention" +msgstr "Prevenção SPAM" + +#: admin/wp-security-admin-init.php:441 +#: admin/wp-security-filescan-menu.php:53 +msgid "Scanner" +msgstr "Verificador" + +#: admin/wp-security-admin-init.php:443 +#: admin/wp-security-maintenance-menu.php:51 +msgid "Maintenance" +msgstr "Manutenção" + +#: admin/wp-security-admin-init.php:444 +#: admin/wp-security-misc-options-menu.php:57 +msgid "Miscellaneous" +msgstr "Diversos" + +#: admin/wp-security-admin-init.php:445 +#: admin/wp-security-tools-menu.php:64 +msgid "Tools" +msgstr "" + +#: admin/wp-security-admin-init.php:457 +msgid "Premium Upgrade" +msgstr "" + +#: admin/wp-security-admin-menu.php:67 +msgid "Settings successfully updated." +msgstr "Configurações autalizadas com sucesso." + +#: admin/wp-security-admin-menu.php:77 +msgid "Successfully deleted the selected record(s)." +msgstr "" + +#: admin/wp-security-admin-menu.php:86 +msgid "Failed to delete the selected record(s)." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:25 +msgid "Ban users" +msgstr "Usuários banidos" + +#: admin/wp-security-blacklist-menu.php:51 +msgid "Blacklist manager" +msgstr "Gerenciar lista negra" + +#: admin/wp-security-blacklist-menu.php:132 +#: admin/wp-security-firewall-menu.php:1233 +#: admin/wp-security-list-404.php:234 +#: admin/wp-security-list-comment-spammer-ip.php:205 +msgid "The plugin was unable to write to the .htaccess file. Please edit file manually." +msgstr "O plugin não foi capaz de gravar no arquivo .htaccess. Por favor, edite o arquivo manualmente." + +#: admin/wp-security-blacklist-menu.php:139 +msgid "Ban IPs or user agents" +msgstr "Banir IPs ou agentes de usuário" + +#: admin/wp-security-blacklist-menu.php:142 +msgid "The All In One WP Security Blacklist feature gives you the option of banning certain host IP addresses or ranges and also user agents." +msgstr "O recurso de lista negra do All In One WP Security lhe dá a opção de proibir determinados endereços IP de host ou intervalos e também agentes de usuário." + +#: admin/wp-security-blacklist-menu.php:143 +msgid "This feature will deny total site access for users which have IP addresses or user agents matching those which you have configured in the settings below." +msgstr "Este recurso irá negar o acesso total do local para os usuários que têm endereços IP ou os agentes de usuário correspondentes aos que você configurou nas configurações abaixo." + +#: admin/wp-security-blacklist-menu.php:144 +msgid "The plugin achieves this by making appropriate modifications to your .htaccess file." +msgstr "O plugin consegue isso fazendo modificações apropriadas ao seu arquivo .htaccess." + +#: admin/wp-security-blacklist-menu.php:145 +msgid "By blocking people, you are using the most secure first line of defence, which denies all access to blacklisted visitors as soon as they hit your hosting server." +msgstr "Ao bloquear as pessoas através do arquivo .htaccess você está usando a primeira linha mais seguro de defesa que nega todo o acesso a visitantes na lista negra, assim que atingirem o seu servidor de hospedagem." + +#: admin/wp-security-blacklist-menu.php:154 +#: admin/wp-security-firewall-menu.php:1055 +#: templates/may-also-like.php:20 +msgid "All In One WP Security & Firewall Premium" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:155 +#: admin/wp-security-firewall-menu.php:1056 +msgid "You may also be interested in %s." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "This plugin adds a number of extra features including %s and %s." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "smart 404 blocking" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "country IP blocking" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:170 +msgid "IP hosts and user agent blacklist settings" +msgstr "Hosts IP e configurações de lista negra de agente do usuário" + +#: admin/wp-security-blacklist-menu.php:182 +#: admin/wp-security-brute-force-menu.php:193 +#: admin/wp-security-brute-force-menu.php:331 +msgid "must read this message" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:183 +#: admin/wp-security-brute-force-menu.php:194 +msgid "This feature can lock you out of admin if it doesn't work correctly on your site. You %s before activating this feature." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:189 +msgid "Enable IP or user agent blacklisting" +msgstr "Habilitar IP ou agente de usuário obstrução na lista negra" + +#: admin/wp-security-blacklist-menu.php:192 +msgid "Check this if you want to enable the banning (or blacklisting) of selected IP addresses and/or user agents specified in the settings below" +msgstr "Marque esta opção se você deseja ativar a proibição (ou obstrução da lista negra) de endereços IP selecionados e / ou agentes de usuário especificados nas configurações abaixo" + +#: admin/wp-security-blacklist-menu.php:196 +msgid "Enter IP addresses:" +msgstr "Digite o endereço IP:" + +#: admin/wp-security-blacklist-menu.php:200 +msgid "Enter one or more IP addresses or IP ranges." +msgstr "Digite um ou mais endereços IP ou intervalos de IP." + +#: admin/wp-security-blacklist-menu.php:205 +msgid "Enter user agents:" +msgstr "Digite os agentes do usuário:" + +#: admin/wp-security-blacklist-menu.php:210 +msgid "Enter one or more user agent strings." +msgstr "Digite uma ou mais sequências de caracteres de agente de usuário." + +#: admin/wp-security-blacklist-menu.php:211 +#: admin/wp-security-brute-force-menu.php:374 +#: admin/wp-security-brute-force-menu.php:408 +#: admin/wp-security-brute-force-menu.php:431 +#: admin/wp-security-brute-force-menu.php:452 +#: admin/wp-security-filescan-menu.php:309 +#: admin/wp-security-filescan-menu.php:326 +#: admin/wp-security-firewall-menu.php:175 +#: admin/wp-security-firewall-menu.php:212 +#: admin/wp-security-firewall-menu.php:232 +#: admin/wp-security-firewall-menu.php:258 +#: admin/wp-security-firewall-menu.php:385 +#: admin/wp-security-firewall-menu.php:415 +#: admin/wp-security-firewall-menu.php:446 +#: admin/wp-security-firewall-menu.php:474 +#: admin/wp-security-firewall-menu.php:503 +#: admin/wp-security-firewall-menu.php:681 +#: admin/wp-security-firewall-menu.php:699 +#: admin/wp-security-firewall-menu.php:737 +#: admin/wp-security-firewall-menu.php:868 +#: admin/wp-security-firewall-menu.php:1087 +#: admin/wp-security-firewall-menu.php:1110 +#: admin/wp-security-spam-menu.php:186 +#: admin/wp-security-spam-menu.php:221 +#: admin/wp-security-spam-menu.php:390 +#: admin/wp-security-spam-menu.php:430 +#: admin/wp-security-user-login-menu.php:362 +#: templates/info/ip-address-ip-range-info.php:2 +#: templates/menus/settings/advanced-settings.php:63 +msgid "More info" +msgstr "Mais informação" + +#: admin/wp-security-blacklist-menu.php:214 +msgid "Each user agent string must be on a new line." +msgstr "Cada sequência do agente de usuário deve estar em uma nova linha." + +#: admin/wp-security-blacklist-menu.php:215 +msgid "Example 1 - A single user agent string to block:" +msgstr "Exemplo 1 - Uma sequência de caracteres de agente de usuário único para bloquear:" + +#: admin/wp-security-blacklist-menu.php:217 +msgid "Example 2 - A list of more than 1 user agent strings to block" +msgstr "Exemplo 2 - Uma lista de mais de 1 sequências de agente de usuário para bloquear" + +#: admin/wp-security-blacklist-menu.php:225 +#: admin/wp-security-brute-force-menu.php:213 +#: admin/wp-security-brute-force-menu.php:686 +#: admin/wp-security-brute-force-menu.php:806 +#: admin/wp-security-brute-force-menu.php:868 +#: admin/wp-security-filescan-menu.php:351 +#: admin/wp-security-filesystem-menu.php:242 +#: admin/wp-security-firewall-menu.php:945 +#: admin/wp-security-firewall-menu.php:1129 +#: admin/wp-security-misc-options-menu.php:167 +#: admin/wp-security-misc-options-menu.php:218 +#: admin/wp-security-misc-options-menu.php:278 +#: admin/wp-security-settings-menu.php:619 +#: admin/wp-security-settings-menu.php:680 +#: admin/wp-security-spam-menu.php:233 +#: admin/wp-security-spam-menu.php:407 +#: admin/wp-security-spam-menu.php:526 +#: admin/wp-security-spam-menu.php:588 +#: admin/wp-security-user-login-menu.php:384 +#: admin/wp-security-user-login-menu.php:422 +#: admin/wp-security-user-login-menu.php:601 +#: admin/wp-security-user-login-menu.php:788 +#: admin/wp-security-user-registration-menu.php:150 +#: admin/wp-security-user-registration-menu.php:242 +#: admin/wp-security-user-registration-menu.php:305 +#: templates/menus/settings/advanced-settings.php:217 +msgid "Save settings" +msgstr "Salvar configurações" + +#: admin/wp-security-brute-force-menu.php:33 +#: admin/wp-security-brute-force-menu.php:759 +#: admin/wp-security-dashboard-menu.php:651 +msgid "Rename login page" +msgstr "Renomeação da página de login" + +#: admin/wp-security-brute-force-menu.php:34 +#: admin/wp-security-brute-force-menu.php:154 +msgid "Cookie based brute force prevention" +msgstr "Prevenção baseadas em cookies de força bruta" + +#: admin/wp-security-brute-force-menu.php:35 +#: classes/grade-system/wp-security-feature-item-manager.php:105 +msgid "Login CAPTCHA" +msgstr "Captcha login" + +#: admin/wp-security-brute-force-menu.php:36 +#: admin/wp-security-brute-force-menu.php:746 +msgid "Login whitelist" +msgstr "Lista branca de login" + +#: admin/wp-security-brute-force-menu.php:37 +msgid "Honeypot" +msgstr "Pote de mel" + +#: admin/wp-security-brute-force-menu.php:67 +msgid "Brute force" +msgstr "Força bruta" + +#: admin/wp-security-brute-force-menu.php:105 +msgid "Please enter a value for your login page slug." +msgstr "Por favor, insira um valor para sua lesma/apelido da página de login." + +#: admin/wp-security-brute-force-menu.php:109 +msgid "You cannot use the value \"wp-admin\" for your login page slug." +msgstr "Você não pode usar o valor \"wp-admin\" para sua lesma/apelido da página de login." + +#: admin/wp-security-brute-force-menu.php:111 +msgid "You must use alpha numeric characters for your login page slug." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:116 +#: admin/wp-security-filescan-menu.php:174 +#: admin/wp-security-firewall-menu.php:151 +#: admin/wp-security-firewall-menu.php:1011 +#: admin/wp-security-spam-menu.php:101 +#: admin/wp-security-spam-menu.php:270 +#: admin/wp-security-spam-menu.php:302 +#: admin/wp-security-user-login-menu.php:184 +#: admin/wp-security-user-login-menu.php:553 +#: templates/partials/non-apache-feature-notice.php:9 +msgid "Attention:" +msgstr "Atenção:" + +#: admin/wp-security-brute-force-menu.php:133 +msgid "Could not delete the Cookie-based directives from the .htaccess file. Please check the file permissions." +msgstr "Não foi possível excluir as diretrizes baseadas em cookie do arquivo .htaccess. Por favor, verifique as permissões do arquivo." + +#: admin/wp-security-brute-force-menu.php:155 +msgid "Login page white list" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:156 +msgid "An effective Brute Force prevention technique is to change the default WordPress login page URL." +msgstr "Uma técnica eficaz para a prevenção de força bruta é alterar a URL padrão da página de login do WordPress." + +#: admin/wp-security-brute-force-menu.php:157 +msgid "Normally if you wanted to login to WordPress you would type your site's home URL followed by wp-login.php." +msgstr "Normalmente, se você deseja fazer login para WordPress você deve digitar uma URL home do seu site, seguido de wp-login.php." + +#: admin/wp-security-brute-force-menu.php:158 +msgid "This feature allows you to change the login URL by setting your own slug and renaming the last portion of the login URL which contains the wp-login.php to any string that you like." +msgstr "Esse recurso permite você alterar a URL de login definindo sua própria lesma/apelido e renomeando a última parte da URL de login que contém o wp-login.php para qualquer sequência de caracteres que você gosta." + +#: admin/wp-security-brute-force-menu.php:159 +msgid "By doing this, malicious bots and hackers will not be able to access your login page because they will not know the correct login page URL." +msgstr "Ao fazer isso, os hackers e robôs maliciosos não serão capazes de acessar a página de login, porque eles não vão saber a URL da página de login correta." + +#: admin/wp-security-brute-force-menu.php:161 +msgid "You may also be interested in the following alternative brute force prevention features:" +msgstr "Você pode também estar interessado nos seguintes recursos alternativos de prevenção de força bruta:" + +#: admin/wp-security-brute-force-menu.php:172 +msgid "Your WordPress login page URL has been renamed." +msgstr "Seu URL da página de login do WordPress foi renomeada." + +#: admin/wp-security-brute-force-menu.php:173 +msgid "Your current login URL is:" +msgstr "Seu URL de login atual é:" + +#: admin/wp-security-brute-force-menu.php:181 +msgid "Rename login page settings" +msgstr "Configurações de renomeação da página de login" + +#: admin/wp-security-brute-force-menu.php:195 +msgid "NOTE: If you are hosting your site on WPEngine or a provider which performs server caching, you will need to ask the host support people to NOT cache your renamed login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:200 +msgid "Enable rename login page feature" +msgstr "Habilitar recurso de renomeação da página de login" + +#: admin/wp-security-brute-force-menu.php:203 +msgid "Check this if you want to enable the rename login page feature" +msgstr "Marque esta opção se você deseja ativar o recurso de renomeação da página de login" + +#: admin/wp-security-brute-force-menu.php:207 +msgid "Login page URL" +msgstr "URL da página de login" + +#: admin/wp-security-brute-force-menu.php:209 +msgid "Enter a string which will represent your secure login page slug. You are encouraged to choose something which is hard to guess and only you will remember." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:243 +msgid "Settings have not been saved - your secret word must consist only of alphanumeric characters, ie, letters and/or numbers only." +msgstr "Configurações não foram salvas - sua palavra secreta deve consistir apenas de caracteres alfanuméricos, ou seja, letras e/ou números apenas." + +#: admin/wp-security-brute-force-menu.php:257 +msgid "You have successfully enabled the cookie based brute force prevention feature" +msgstr "Você ativou com sucesso o recurso de prevenção de força bruta baseada em cookie" + +#: admin/wp-security-brute-force-menu.php:258 +msgid "From now on you will need to log into your WP Admin using the following URL:" +msgstr "De agora em diante, você precisará fazer login em sua administração WP usando a seguinte URL:" + +#: admin/wp-security-brute-force-menu.php:260 +msgid "It is important that you save this URL value somewhere in case you forget it, OR," +msgstr "É importante que você salve esse valor de URL em algum lugar caso você esqueça, OU," + +#: admin/wp-security-brute-force-menu.php:261 +msgid "simply remember to add a \"?%s=1\" to your current site URL address." +msgstr "simplesmente lembre-se de adicionar um \"?%s=1\" para o seu endereço de URL do site atual." + +#: admin/wp-security-brute-force-menu.php:265 +msgid "You have successfully saved cookie based brute force prevention feature settings." +msgstr "Você salvou com sucesso as configurações de recursos de prevenção de força bruta baseadas em cookies." + +#: admin/wp-security-brute-force-menu.php:295 +msgid "Brute force prevention firewall settings" +msgstr "Configurações de firewall de prevenção de força bruta" + +#: admin/wp-security-brute-force-menu.php:300 +msgid "A Brute Force Attack is when a hacker tries many combinations of usernames and passwords until they succeed in guessing the right combination." +msgstr "Um ataque de força bruta é quando um hacker tenta muitas combinações de nomes de usuário e senhas até que eles conseguem adivinhar a combinação certa." + +#: admin/wp-security-brute-force-menu.php:301 +msgid "Due to the fact that at any one time there may be many concurrent login attempts occurring on your site via malicious automated robots, this also has a negative impact on your server's memory and performance." +msgstr "Devido ao fato de que a qualquer momento, pode haver muitas tentativas de login simultâneas ocorrendo no seu site através de robôs automatizados maliciosos, este também tem um impacto negativo sobre a memória e o desempenho do seu servidor." + +#: admin/wp-security-brute-force-menu.php:302 +msgid "The features in this tab will stop the majority of brute force login attacks thus providing even better protection for your WP login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:307 +#: admin/wp-security-firewall-menu.php:654 +msgid "backup" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:308 +msgid "video tutorial" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:309 +msgid "To learn more about how to use this feature, please watch the following %s." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:310 +#: admin/wp-security-brute-force-menu.php:758 +msgid "Cookie-Based Brute Force Login Prevention" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:320 +#: admin/wp-security-user-login-menu.php:253 +msgid "Cookie based brute force login prevention" +msgstr "Prevenção de acesso baseadas em cookies de força bruta" + +#: admin/wp-security-brute-force-menu.php:331 +msgid "This feature can lock you out of admin if it doesn't work correctly on your site. You " +msgstr "" + +#: admin/wp-security-brute-force-menu.php:342 +msgid "The cookie test was successful. You can now enable this feature." +msgstr "O teste de cookie foi bem sucedido. Agora, você pode ativar esse recurso." + +#: admin/wp-security-brute-force-menu.php:350 +msgid "The cookie test failed on this server. Consequently, this feature cannot be used on this site." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:357 +msgid "Before using this feature, you must perform a cookie test first." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:359 +msgid "This ensures that your browser cookie is working correctly and that you won't lock yourself out." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:364 +msgid "Perform cookie test" +msgstr "Executar teste de cookies" + +#: admin/wp-security-brute-force-menu.php:370 +#: classes/grade-system/wp-security-feature-item-manager.php:103 +msgid "Enable brute force attack prevention" +msgstr "Habilitar prevenção contra ataque de força bruta" + +#: admin/wp-security-brute-force-menu.php:373 +msgid "Check this if you want to protect your login page from Brute Force Attack." +msgstr "Marque esta opção se você deseja proteger sua página de login de ataque de força bruta." + +#: admin/wp-security-brute-force-menu.php:378 +msgid "This feature will deny access to your WordPress login page for all people except those who have a special cookie in their browser." +msgstr "Esse recurso irá negar o acesso à sua página de login do WordPress para todas as pessoas, exceto aqueles que têm um cookie especial em seu navegador." + +#: admin/wp-security-brute-force-menu.php:380 +msgid "To use this feature do the following:" +msgstr "Para usar este recurso faça o seguinte:" + +#: admin/wp-security-brute-force-menu.php:382 +msgid "1) Enable the checkbox." +msgstr "1) Habilite a caixa de seleção." + +#: admin/wp-security-brute-force-menu.php:384 +msgid "2) Enter a secret word consisting of alphanumeric characters which will be difficult to guess. This secret word will be useful whenever you need to know the special URL which you will use to access the login page (see point below)." +msgstr "2) Digite uma palavra secreta, constituída por caracteres alfanuméricos, que será difícil de adivinhar. Esta palavra secreta será útil sempre que você precisa saber a URL especial que você usará para acessar a página de login (ver ponto abaixo)." + +#: admin/wp-security-brute-force-menu.php:386 +msgid "3) You will then be provided with a special login URL. You will need to use this URL to login to your WordPress site instead of the usual login URL. NOTE: The system will deposit a special cookie in your browser which will allow you access to the WordPress administration login page." +msgstr "3) Em seguida, será fornecido com uma URL de login especial. Você precisará usar esta URL para acessar o seu site WordPress em vez da URL de login habitual. NOTA: O sistema irá depositar um cookie especial em seu navegador, que lhe permitirá aceder à página de login de administração do WordPress." + +#: admin/wp-security-brute-force-menu.php:388 +msgid "Any person trying to access your login page who does not have the special cookie in their browser will be automatically blocked." +msgstr "Qualquer pessoa que tentar acessar a página de login que não tem o cookie especial em seu navegador será bloqueado automaticamente." + +#: admin/wp-security-brute-force-menu.php:395 +msgid "Secret word" +msgstr "Palavra secreta" + +#: admin/wp-security-brute-force-menu.php:397 +msgid "Choose a secret word consisting of alphanumeric characters which you can use to access your special URL. Your are highly encouraged to choose a word which will be difficult to guess." +msgstr "Escolha uma palavra secreta composta de caracteres alfanuméricos, que você pode usar para acessar sua URL especial. Você estar altamente incentivados a escolher uma palavra que será difícil de adivinhar." + +#: admin/wp-security-brute-force-menu.php:401 +msgid "Re-direct URL" +msgstr "Redirecionar URL" + +#: admin/wp-security-brute-force-menu.php:405 +msgid "Specify a URL to redirect a hacker to when they try to access your WordPress login page." +msgstr "Especifique uma URL para redirecionar um hacker para quando eles tentam acessar a página de login do WordPress." + +#: admin/wp-security-brute-force-menu.php:412 +msgid "The URL specified here can be any site's URL and does not have to be your own. For example you can be as creative as you like and send hackers to the CIA or NSA home page." +msgstr "A URL especificada aqui pode ser URL de qualquer site e não tem que ser o seu próprio. Por exemplo, você pode ser tão criativo como você gosta e enviar os hackers para a página inicial da CIA ou NSA." + +#: admin/wp-security-brute-force-menu.php:414 +msgid "This field will default to: http://127.0.0.1 if you do not enter a value." +msgstr "Este campo será o padrão para: http://127.0.0.1 se você não digitar um valor." + +#: admin/wp-security-brute-force-menu.php:416 +msgid "Useful Tip:" +msgstr "Dica útil:" + +#: admin/wp-security-brute-force-menu.php:418 +msgid "It's a good idea to not redirect attempted brute force login attempts to your site because it increases the load on your server." +msgstr "É uma boa ideia não redirecionar tentativas de login de tentativa de força bruta para seu site, porque aumenta a carga no seu servidor." + +#: admin/wp-security-brute-force-menu.php:420 +msgid "Redirecting a hacker or malicious bot back to \"http://127.0.0.1\" is ideal because it deflects them back to their own local host and puts the load on their server instead of yours." +msgstr "Redirecionando um hacker ou robô malicioso de volta para \"http://127.0.0.1\" é ideal, pois desvia-los de volta ao seu próprio host local e coloca a carga em seu servidor ao invés do seu." + +#: admin/wp-security-brute-force-menu.php:427 +msgid "My site has posts or pages which are password protected" +msgstr "Meu site tem posts ou páginas que são protegidos por senha" + +#: admin/wp-security-brute-force-menu.php:430 +msgid "Check this if you are using the native WordPress password protection feature for some or all of your blog posts or pages." +msgstr "Marque esta opção se você estiver usando o recurso de proteção de senha nativo do WordPress para alguns ou todos os seus posts no blog ou páginas." + +#: admin/wp-security-brute-force-menu.php:435 +msgid "In the cases where you are protecting some of your posts or pages using the in-built WordPress password protection feature, a few extra lines of directives and exceptions need to be added so that people trying to access pages are not automatically blocked." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:437 +msgid "By enabling this checkbox, the plugin will add the necessary rules and exceptions so that people trying to access these pages are not automatically blocked." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:439 +msgid "Helpful Tip:" +msgstr "Dica útil:" + +#: admin/wp-security-brute-force-menu.php:441 +msgid "If you do not use the WordPress password protection feature for your posts or pages then it is highly recommended that you leave this checkbox disabled." +msgstr "Se você não usar o recurso de proteção de senha do WordPress para seus posts ou páginas, então é altamente recomendado que você deixe essa caixa de seleção desativada." + +#: admin/wp-security-brute-force-menu.php:448 +msgid "My site has a theme or plugins which use AJAX" +msgstr "Meu site tem um tema ou plugins que usam AJAX" + +#: admin/wp-security-brute-force-menu.php:451 +msgid "Check this if your site uses AJAX functionality." +msgstr "Marque esta opção se o seu site usa a funcionalidade AJAX." + +#: admin/wp-security-brute-force-menu.php:456 +msgid "In the cases where your WordPress installation has a theme or plugin that uses AJAX, a few extra lines of directives and exceptions need to be added to prevent AJAX requests from being automatically blocked by the brute force prevention feature." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:458 +msgid "By enabling this checkbox, the plugin will add the necessary rules and exceptions so that AJAX operations will work as expected." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:467 +msgid "Save feature settings" +msgstr "Salvar configurações de recurso" + +#: admin/wp-security-brute-force-menu.php:525 +msgid "This feature allows you to add a CAPTCHA form on various WordPress login pages and forms." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:526 +msgid "Adding a CAPTCHA form on a login page or form is another effective yet simple \"Brute Force\" prevention technique." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:527 +msgid "You have the option of using either %s or a plain maths CAPTCHA form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:528 +msgid "If you enable Google reCAPTCHA the reCAPTCHA widget will be displayed for all forms the CAPTCHA settings below." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:529 +msgid "If Google reCAPTCHA is disabled the simple maths CAPTCHA form will apply and users will need to enter the answer to a simple mathematical question." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:535 +msgid "Google reCAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:540 +msgid "By enabling these settings the Google reCAPTCHA v2 widget will be applied by default for all forms with CAPTCHA enabled." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:549 +msgid "reCAPTCHA will not work because you have disabled login lockout by activating the AIOS_DISABLE_LOGIN_LOCKOUT constant value in a configuration file." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:550 +msgid "To enable it, define AIOS_DISABLE_LOGIN_LOCKOUT constant value as false, or remove it." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:558 +msgid "Use Google reCAPTCHA as default" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:561 +msgid "Check this if you want to default to Google reCAPTCHA for all settings below. (If this is left unchecked, all CAPTCHA forms will revert to the plain maths CAPTCHA)" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:565 +msgid "Site key" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:571 +msgid "Secret key" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:580 +msgid "Login form CAPTCHA settings" +msgstr "Configurações do formulário captcha de login" + +#: admin/wp-security-brute-force-menu.php:589 +msgid "Enable CAPTCHA on login page" +msgstr "Habilitar captcha na página de login" + +#: admin/wp-security-brute-force-menu.php:592 +msgid "Check this if you want to insert a CAPTCHA form on the login page." +msgstr "Marque esta opção se você deseja inserir um formulário captcha na página de login" + +#: admin/wp-security-brute-force-menu.php:598 +msgid "Lost password form CAPTCHA settings" +msgstr "Configurações do formulário captcha de senha perdida" + +#: admin/wp-security-brute-force-menu.php:608 +msgid "Enable CAPTCHA on lost password page" +msgstr "Habilitar captcha na página senha perdida" + +#: admin/wp-security-brute-force-menu.php:611 +msgid "Check this if you want to insert a CAPTCHA form on the lost password page." +msgstr "Marque esta opção se você deseja inserir um formulário captcha na página de senha perdida" + +#: admin/wp-security-brute-force-menu.php:617 +msgid "Custom login form CAPTCHA settings" +msgstr "Configurações personalizadas do formulário captcha de login" + +#: admin/wp-security-brute-force-menu.php:626 +msgid "Enable CAPTCHA on custom login form" +msgstr "Habilitar captcha no formulário de login personalizado" + +#: admin/wp-security-brute-force-menu.php:629 +msgid "Check this if you want to insert CAPTCHA on a custom login form generated by the following WP function: wp_login_form()" +msgstr "Marque esta opção se você deseja inserir o captcha em um formulário de login personalizado gerado pela seguinte função WP: wp_login_form()" + +#: admin/wp-security-brute-force-menu.php:639 +msgid "WooCommerce forms CAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:648 +msgid "Enable CAPTCHA on WooCommerce login form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:651 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce login form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:661 +msgid "Enable CAPTCHA on WooCommerce lost password form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:664 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce lost password form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:674 +msgid "Enable CAPTCHA on WooCommerce registration form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:677 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce registration form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:749 +msgid "The All In One WP Security Whitelist feature gives you the option of only allowing certain IP addresses or ranges to have access to your WordPress login page." +msgstr "O recurso de lista branca de All In One WP Security lhe dá a opção de permitir apenas determinados endereços IP ou intervalos para ter acesso à sua página de login do WordPress." + +#: admin/wp-security-brute-force-menu.php:750 +msgid "This feature will deny login access for all IP addresses which are not in your whitelist as configured in the settings below." +msgstr "Este recurso irá negar o acesso de login para todos os endereços IP que não estão em sua lista branca conforme configurado nas configurações abaixo." + +#: admin/wp-security-brute-force-menu.php:751 +msgid "The plugin achieves this by writing the appropriate directives to your .htaccess file." +msgstr "O plugin consegue isso por escrito as diretivas apropriadas para o seu arquivo .htaccess." + +#: admin/wp-security-brute-force-menu.php:752 +msgid "By allowing/blocking IP addresses, you are using the most secure first line of defence because login access will only be granted to whitelisted IP addresses and other addresses will be blocked as soon as they try to access your login page." +msgstr "Ao permitir / bloquear endereços IP via arquivo .htaccess você está usando a primeira linha mais seguro de defesa porque o acesso de login será concedido somente a endereços IP autorizados na lista branca e outros endereços serão bloqueadas assim que eles tentam acessar a página de login." + +#: admin/wp-security-brute-force-menu.php:760 +msgid "Attention: If in addition to enabling the white list feature, you also have one of the %s or %s features enabled, you will still need to use your secret word or special slug in the URL when trying to access your WordPress login page." +msgstr "Atenção: Se além de habilitar o recurso de lista branca, você também tem um dos %s ou %s recursos habilitados, você ainda precisará usar sua palavra secreta ou lesma/apelido especial na URL quando você tentar acessar a página de login do WordPress." + +#: admin/wp-security-brute-force-menu.php:761 +msgid "These features are NOT functionally related. Having both of them enabled on your site means you are creating 2 layers of security." +msgstr "Esses recursos não estão funcionalmente relacionados. Tendo ambos habilitado em seu site significa que você está criando 2 camadas de segurança." + +#: admin/wp-security-brute-force-menu.php:772 +msgid "Login IP whitelist settings" +msgstr "Configurações de login de lista branca IP" + +#: admin/wp-security-brute-force-menu.php:783 +msgid "Enable IP whitelisting" +msgstr "Habilitar lista branca de IP" + +#: admin/wp-security-brute-force-menu.php:786 +#: admin/wp-security-user-login-menu.php:408 +msgid "Check this if you want to enable the whitelisting of selected IP addresses specified in the settings below" +msgstr "Marque esta opção se você deseja ativar o lista branca de endereços IP selecionados especificados nas configurações abaixo" + +#: admin/wp-security-brute-force-menu.php:790 +msgid "Your current IP address" +msgstr "Seu endereço IP atual" + +#: admin/wp-security-brute-force-menu.php:793 +msgid "You can copy and paste this address in the text box below if you want to include it in your login whitelist." +msgstr "Você pode copiar e colar esse endereço na caixa de texto abaixo, se você deseja incluí-lo em sua lista branca de login." + +#: admin/wp-security-brute-force-menu.php:797 +#: admin/wp-security-user-login-menu.php:412 +msgid "Enter whitelisted IP addresses:" +msgstr "Digite endereços IP na lista branca:" + +#: admin/wp-security-brute-force-menu.php:801 +#: admin/wp-security-user-login-menu.php:416 +msgid "Enter one or more IP addresses or IP ranges you wish to include in your whitelist." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:801 +msgid "Only the addresses specified here will have access to the WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:839 +msgid "This feature allows you to add a special hidden \"honeypot\" field on the WordPress login page. This will only be visible to robots and not humans." +msgstr "Esse recurso permite que você adicione um campo oculto especial \"pote de mel\" na página de login do WordPress. Isso só será visível para os robôs e não seres humanos." + +#: admin/wp-security-brute-force-menu.php:840 +msgid "Since robots usually fill in every input field from a login form, they will also submit a value for the special hidden honeypot field." +msgstr "Desde que os robôs geralmente preencher cada campo de entrada de um formulário de login, eles também apresentará um valor para o campo de pote de mel oculto especial." + +#: admin/wp-security-brute-force-menu.php:841 +#: admin/wp-security-user-registration-menu.php:278 +msgid "The way honeypots work is that a hidden field is placed somewhere inside a form which only robots will submit. If that field contains a value when the form is submitted then a robot has most likely submitted the form and it is consequently dealt with." +msgstr "A maneira de trabalho de potes de mel é que um campo oculto é colocado em algum lugar dentro de uma forma que apenas os robôs irão apresentar. Se esse campo contém um valor quando o formulário é enviado, em seguida, um robô muito provavelmente apresentou a forma e isso consequentemente é tratado com." + +#: admin/wp-security-brute-force-menu.php:842 +msgid "Therefore, if the plugin detects that this field has a value when the login form is submitted, then the robot which is attempting to login to your site will be redirected to its localhost address - http://127.0.0.1." +msgstr "Portanto, se o plugin detecta que este campo tem um valor quando o formulário de login é enviado, então o robô que está tentando fazer o login para o seu site será redirecionado para seu endereço localhost - http://127.0.0.1." + +#: admin/wp-security-brute-force-menu.php:848 +msgid "Login form honeypot settings" +msgstr "Configurações do formulário de login pote de mel" + +#: admin/wp-security-brute-force-menu.php:859 +msgid "Enable honeypot on login page" +msgstr "Habilitar pote de mel na página de login" + +#: admin/wp-security-brute-force-menu.php:862 +msgid "Check this if you want to enable the honeypot feature for the login page" +msgstr "Marque esta opção se você deseja ativar o recurso pote de mel para a página de login" + +#: admin/wp-security-dashboard-menu.php:27 +#: admin/wp-security-dashboard-menu.php:374 +#: classes/wp-security-user-login.php:74 +msgid "Locked IP addresses" +msgstr "Endereços IP bloqueados" + +#: admin/wp-security-dashboard-menu.php:28 +msgid "Permanent block list" +msgstr "Lista de bloqueio permanente" + +#: admin/wp-security-dashboard-menu.php:29 +msgid "Logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:33 +msgid "Premium upgrade" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:131 +#: admin/wp-security-dashboard-menu.php:518 +#: admin/wp-security-user-login-menu.php:53 +#: classes/grade-system/wp-security-feature-item-manager.php:49 +msgid "Login lockout" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:132 +msgid "This tab displays the list of all IP addresses which are currently temporarily locked out due to the login lockout feature:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:138 +msgid "Currently locked out IP addresses and ranges" +msgstr "Endereços IP e intervalos atualmente bloqueado" + +#: admin/wp-security-dashboard-menu.php:183 +msgid "This tab displays the list of all permanently blocked IP addresses." +msgstr "Esta guia exibe a lista de todos os endereços IP bloqueados permanentemente." + +#: admin/wp-security-dashboard-menu.php:184 +#: admin/wp-security-spam-menu.php:339 +msgid "NOTE: This feature does NOT use the .htaccess file to permanently block the IP addresses so it should be compatible with all web servers running WordPress." +msgstr "Nota: Esse recurso não usa o arquivo .htaccess para bloquear permanentemente os endereços IP, por isso deve ser compatível com todos os servidores web executando o WordPress." + +#: admin/wp-security-dashboard-menu.php:189 +msgid "Permanently blocked IP addresses" +msgstr "Endereços IP bloqueados permanentemente" + +#: admin/wp-security-dashboard-menu.php:200 +#: admin/wp-security-firewall-menu.php:1151 +#: admin/wp-security-user-login-menu.php:485 +#: admin/wp-security-user-login-menu.php:643 +#: admin/wp-security-user-registration-menu.php:164 +msgid "Search" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:238 +#: admin/wp-security-dashboard-menu.php:249 +#: admin/wp-security-dashboard-menu.php:260 +msgid "All In One WP Security & Firewall" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:250 +msgid "Debug logs have been cleared." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:261 +msgid "Unable to clear the logs; an invalid nonce was provided" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:274 +msgid "Debug log options" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:281 +msgid "Clear logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:289 +msgid "Debug logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:362 +msgid "Security strength meter" +msgstr "Medidor de força de segurança" + +#: admin/wp-security-dashboard-menu.php:363 +msgid "Security points breakdown" +msgstr "Segurança aponta esgotamento" + +#: admin/wp-security-dashboard-menu.php:364 +msgid "Spread the word" +msgstr "Estenda a palavra" + +#: admin/wp-security-dashboard-menu.php:365 +msgid "Get to know the developers" +msgstr "Conheça os desenvolvedores" + +#: admin/wp-security-dashboard-menu.php:366 +msgid "Critical feature status" +msgstr "Status de característica crítica" + +#: admin/wp-security-dashboard-menu.php:367 +msgid "Last 5 logins" +msgstr "Últimos 5 logins" + +#: admin/wp-security-dashboard-menu.php:368 +msgid "Maintenance mode status" +msgstr "Status do modo de manutenção" + +#: admin/wp-security-dashboard-menu.php:373 +#: admin/wp-security-dashboard-menu.php:664 +#: admin/wp-security-user-login-menu.php:57 +msgid "Logged in users" +msgstr "Usuários conectados" + +#: admin/wp-security-dashboard-menu.php:417 +msgid "Total Achievable Points: " +msgstr "Total de pontos alcançáveis: " + +#: admin/wp-security-dashboard-menu.php:419 +msgid "Current Score of Your Site: " +msgstr "Avaliação atual do seu site: " + +#: admin/wp-security-dashboard-menu.php:472 +msgid "We are working hard to make your WordPress site more secure. Please support us, here is how:" +msgstr "Estamos trabalhando duro para tornar seu site WordPress mais seguro. Por favor, apoiem-nos, aqui está como:" + +#: admin/wp-security-dashboard-menu.php:473 +msgid "Follow us on" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:477 +msgid "Post to Twitter" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:481 +msgid "Give us a good rating" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:488 +msgid "Wanna know more about the developers behind this plugin?" +msgstr "Quer saber mais sobre os desenvolvedores por trás deste plugin?" + +#: admin/wp-security-dashboard-menu.php:499 +msgid "Below is the current status of the critical features that you should activate on your site to achieve a minimum level of recommended security" +msgstr "Abaixo está o estado atual dos recursos críticos que você deve ativar em seu site para atingir um nível mínimo de segurança recomendado" + +#: admin/wp-security-dashboard-menu.php:503 +msgid "Admin username" +msgstr "Nome de usuário admin" + +#: admin/wp-security-dashboard-menu.php:533 +msgid "File permission" +msgstr "Permissão de arquivo" + +#: admin/wp-security-dashboard-menu.php:548 +msgid "Basic firewall" +msgstr "Firewall básico" + +#: admin/wp-security-dashboard-menu.php:577 +msgid "No data found." +msgstr "Nenhum dado encontrado!" + +#: admin/wp-security-dashboard-menu.php:581 +msgid "Last 5 logins summary:" +msgstr "Últimos 5 logins resumidos:" + +#: admin/wp-security-dashboard-menu.php:585 +msgid "User" +msgstr "Usuário" + +#: admin/wp-security-dashboard-menu.php:586 +#: admin/wp-security-list-404.php:95 +#: admin/wp-security-list-login-fails.php:56 +#: admin/wp-security-list-permanent-blocked-ip.php:68 +msgid "Date" +msgstr "Data" + +#: admin/wp-security-dashboard-menu.php:587 +msgid "IP" +msgstr "IP" + +#: admin/wp-security-dashboard-menu.php:608 +msgid "Maintenance mode is currently enabled. Remember to turn it off when you are done" +msgstr "Modo de manutenção está habilitado no momento. Lembre-se de desabilita-lo quando você terminar" + +#: admin/wp-security-dashboard-menu.php:610 +msgid "Maintenance mode is currently off." +msgstr "Modo de manutenção atualmente está desligado." + +#: admin/wp-security-dashboard-menu.php:614 +msgid "Maintenance mode" +msgstr "Modo de manutenção" + +#: admin/wp-security-dashboard-menu.php:632 +msgid "Cookie based brute force" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:636 +#: admin/wp-security-dashboard-menu.php:654 +msgid "The %s feature is currently active." +msgstr "O recurso %s está atualmente ativo." + +#: admin/wp-security-dashboard-menu.php:637 +#: admin/wp-security-dashboard-menu.php:655 +msgid "Your new WordPress login URL is now:" +msgstr "Sua nova URL de login WordPress agora é:" + +#: admin/wp-security-dashboard-menu.php:666 +msgid "Number of users currently logged into your site (including you) is:" +msgstr "Número de usuários atualmente conectados a seu site (incluindo você) é:" + +#: admin/wp-security-dashboard-menu.php:667 +msgid "There are no other users currently logged in." +msgstr "Não há nenhum outros usuários atualmente conectado." + +#: admin/wp-security-dashboard-menu.php:680 +msgid "Number of users currently logged in site-wide (including you) is:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:681 +msgid "There are no other site-wide users currently logged in." +msgstr "Não há nenhum outro usuário por todo o sítio atualmente conectado." + +#: admin/wp-security-dashboard-menu.php:694 +#: admin/wp-security-dashboard-menu.php:711 +msgid "Go to the %s menu to see more details" +msgstr "Vá para o %s menu para ver mais detalhes" + +#: admin/wp-security-dashboard-menu.php:707 +msgid "There are no IP addresses currently locked out." +msgstr "Não há nenhum endereço IP atualmente bloqueado." + +#: admin/wp-security-dashboard-menu.php:710 +msgid "Number of temporarily locked out IP addresses: " +msgstr "Número de endereços IP temporariamente bloqueado: " + +#: admin/wp-security-database-menu.php:52 +msgid "UpdraftPlus is installed but currently not active." +msgstr "" + +#: admin/wp-security-database-menu.php:52 +msgid "Follow this link to activate UpdraftPlus, to take a backup." +msgstr "" + +#: admin/wp-security-database-menu.php:57 +msgid "Follow this link to install UpdraftPlus, to take a database backup." +msgstr "" + +#: admin/wp-security-database-menu.php:87 +#: admin/wp-security-database-menu.php:92 +msgid "Database backup" +msgstr "Backup do BD" + +#: admin/wp-security-database-menu.php:91 +#: classes/grade-system/wp-security-feature-item-manager.php:65 +msgid "Database prefix" +msgstr "Prefixo de BD" + +#: admin/wp-security-database-menu.php:119 +msgid "Database security" +msgstr "Segurança do DB" + +#: admin/wp-security-database-menu.php:147 +msgid "Nonce check failed for DB prefix change operation!" +msgstr "Verificação núncio falhou para operação de alteração de prefixo do banco de dados!" + +#: admin/wp-security-database-menu.php:155 +msgid "The plugin has detected that it cannot write to the wp-config.php file. This feature can only be used if the plugin can successfully write to the wp-config.php file." +msgstr "O plugin detectou que não é possível gravar o arquivo wp-config.php. Este recurso só pode ser usado se o plugin com sucesso pode gravar o arquivo wp-config.php." + +#: admin/wp-security-database-menu.php:168 +msgid "Please enter a value for the DB prefix." +msgstr "Por favor, insira um valor para o prefixo do banco de dados." + +#: admin/wp-security-database-menu.php:177 +msgid "ERROR: The table prefix can only contain numbers, letters, and underscores." +msgstr "ERRO: O prefixo da tabela pode conter apenas números, letras e sublinhados." + +#: admin/wp-security-database-menu.php:186 +#: admin/wp-security-database-menu.php:245 +msgid "Change database prefix" +msgstr "Alterar prefixo do banco de dados" + +#: admin/wp-security-database-menu.php:189 +msgid "Your WordPress database is the most important asset of your website because it contains a lot of your site's precious information." +msgstr "Seu banco de dados WordPress é o ativo mais importante de seu site, porque ele contém muitas informações preciosas do seu site." + +#: admin/wp-security-database-menu.php:190 +msgid "The database is also a target for hackers via methods such as SQL injections and malicious and automated code which targets certain tables." +msgstr "O banco de dados também é um alvo para hackers através de métodos tais como injeções de SQL e código malicioso e automatizado que tem como alvo determinadas tabelas." + +#: admin/wp-security-database-menu.php:191 +msgid "One way to add a layer of protection for your DB is to change the default WordPress table prefix from \"wp_\" to something else which will be difficult for hackers to guess." +msgstr "Uma maneira de adicionar uma camada de proteção para seu Banco de Dados é alterar o prefixo da tabela padrão WordPress \"wp_\" para outra coisa que será difícil para os hackers de adivinhar." + +#: admin/wp-security-database-menu.php:192 +msgid "This feature allows you to easily change the prefix to a value of your choice or to a random value set by this plugin." +msgstr "Esse recurso permite que você altere facilmente o prefixo para um valor de sua escolha ou para um valor aleatório definido por este plugin." + +#: admin/wp-security-database-menu.php:198 +msgid "Database prefix options" +msgstr "Opções de prefixo do banco de dados" + +#: admin/wp-security-database-menu.php:210 +msgid "database backup" +msgstr "Backup do BD" + +#: admin/wp-security-database-menu.php:211 +msgid "It is recommended that you perform a %s before using this feature" +msgstr "É recomendável que você execute um %s antes de usar este recurso" + +#: admin/wp-security-database-menu.php:221 +msgid "Current database table prefix" +msgstr "Atual prefixo da tabela BD" + +#: admin/wp-security-database-menu.php:227 +msgid "Your site is currently using the default WordPress database prefix value of \"wp_\"." +msgstr "" + +#: admin/wp-security-database-menu.php:227 +msgid "To increase your site's security you should consider changing the database prefix value to another value." +msgstr "" + +#: admin/wp-security-database-menu.php:234 +msgid "Generate new database table prefix" +msgstr "Gerar novo prefixo da tabela BD" + +#: admin/wp-security-database-menu.php:238 +msgid "Check this if you want the plugin to generate a random 6 character string for the table prefix" +msgstr "Marque esta opção se você deseja que o plugin para gerar uma sequência de 6 caracteres aleatórios para o prefixo da tabela" + +#: admin/wp-security-database-menu.php:239 +msgid "OR" +msgstr "OU" + +#: admin/wp-security-database-menu.php:241 +msgid "Choose your own database prefix by specifying a string which contains letters and/or numbers and/or underscores. Example: xyz_" +msgstr "" + +#: admin/wp-security-database-menu.php:265 +msgid "Take a database backup using UpdraftPlus" +msgstr "" + +#: admin/wp-security-database-menu.php:270 +msgid "Manual backup" +msgstr "Backup manual" + +#: admin/wp-security-database-menu.php:274 +msgid "UpdraftPlus Backup/Restore" +msgstr "" + +#: admin/wp-security-database-menu.php:274 +msgid "Your backups are on the UpdraftPlus Backup/Restore admin page." +msgstr "" + +#: admin/wp-security-database-menu.php:276 +msgid "Create database backup now" +msgstr "" + +#: admin/wp-security-database-menu.php:308 +msgid "Error - Could not get tables or no tables found!" +msgstr "Erro - Não foi possível obter tabelas ou sem tabelas encontradas!" + +#: admin/wp-security-database-menu.php:312 +msgid "Starting DB prefix change operations....." +msgstr "Iniciando operações de alteração do prefixo do banco de dados....." + +#: admin/wp-security-database-menu.php:314 +msgid "Your WordPress system has a total of %s tables and your new DB prefix will be: %s" +msgstr "Seu sistema WordPress tem um total de %s tabelas e seu novo prefixo DB será: %s" + +#: admin/wp-security-database-menu.php:320 +#: classes/wp-security-utility.php:306 +msgid "Failed to make a backup of the wp-config.php file. This operation will not go ahead." +msgstr "Falha ao fazer um backup do arquivo wp-config.php. Esta operação não irá em frente." + +#: admin/wp-security-database-menu.php:324 +msgid "A backup copy of your wp-config.php file was created successfully!" +msgstr "Uma cópia de backup de seu arquivo wp-config.php foi criada com sucesso!" + +#: admin/wp-security-database-menu.php:351 +msgid "%s table name update failed" +msgstr "Falha na atualização do nome da tabela %s" + +#: admin/wp-security-database-menu.php:363 +msgid "Please change the prefix manually for the above tables to: %s" +msgstr "Por favor, altere o prefixo manualmente para as tabelas acima para: %s" + +#: admin/wp-security-database-menu.php:366 +msgid "%s tables had their prefix updated successfully!" +msgstr "O prefixo da tabela %s foi atualizado com sucesso!" + +#: admin/wp-security-database-menu.php:387 +msgid "wp-config.php file was updated successfully!" +msgstr "O arquivo wp-config.php foi atualizado com sucesso!" + +#: admin/wp-security-database-menu.php:390 +msgid "The \"wp-config.php\" file was not able to be modified." +msgstr "" + +#: admin/wp-security-database-menu.php:390 +msgid "Please modify this file manually using your favourite editor and search for variable \"$table_prefix\" and assign the following value to that variable: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:401 +#: admin/wp-security-database-menu.php:420 +msgid "Update of table %s failed: unable to change %s to %s" +msgstr "Falha na atualização da tabela de %s: Não é possível alterar %s para %s" + +#: admin/wp-security-database-menu.php:405 +msgid "The options table records which had references to the old DB prefix were updated successfully!" +msgstr "Os registros da tabela de opções que tinham referências ao antigo prefixo DB foram atualizados com sucesso!" + +#: admin/wp-security-database-menu.php:424 +msgid "The %s table records which had references to the old DB prefix were updated successfully!" +msgstr "Os registros da tabela %s que tinham referências ao antigo prefixo DB foram atualizados com sucesso!" + +#: admin/wp-security-database-menu.php:452 +msgid "Error updating user_meta table where new meta_key = %s, old meta_key = %s and user_id = %s." +msgstr "Erro ao atualizar a tabela de user_meta onde novo meta_key = %s, velho meta_key = %s e user_id = %s." + +#: admin/wp-security-database-menu.php:457 +msgid "The usermeta table records which had references to the old DB prefix were updated successfully!" +msgstr "Os registros da tabela usermeta que tinham referências ao antigo prefixo DB foram atualizados com sucesso!" + +#: admin/wp-security-database-menu.php:459 +msgid "The database prefix change tasks have been completed." +msgstr "As tarefas de mudança de prefixo do banco de dados foram concluídas." + +#: admin/wp-security-database-menu.php:503 +msgid "Checking for MySQL tables of type \"view\"....." +msgstr "" + +#: admin/wp-security-database-menu.php:520 +msgid "Update of the following MySQL view definition failed: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:527 +msgid "%s view definitions were updated successfully!" +msgstr "" + +#: admin/wp-security-filescan-menu.php:26 +#: classes/grade-system/wp-security-feature-item-manager.php:127 +msgid "File change detection" +msgstr "Detecção de alteração de arquivo" + +#: admin/wp-security-filescan-menu.php:27 +msgid "Malware scan" +msgstr "Examinar malware" + +#: admin/wp-security-filescan-menu.php:88 +msgid "There have been no file changes since the last scan." +msgstr "Não houve nenhuma alteração de arquivo desde a última verificação." + +#: admin/wp-security-filescan-menu.php:98 +msgid "Nonce check failed for manual file change detection scan operation!" +msgstr "Verificação núncio falhou para operação de verificação de detecção de alteração de arquivo manual!" + +#: admin/wp-security-filescan-menu.php:104 +msgid "There was an error during the file change detection scan. Please check the AIOS logs." +msgstr "" + +#: admin/wp-security-filescan-menu.php:110 +msgid "The plugin has detected that this is your first file change detection scan. The file details from this scan will be used to detect file changes for future scans." +msgstr "O plugin detectou que este é a sua primeira verificação de detecção de alteração de arquivo. Os detalhes do arquivo desta verificação serão usados para detectar alterações de arquivo para futuras verificações!" + +#: admin/wp-security-filescan-menu.php:112 +msgid "Scan complete - There were no file changes detected!" +msgstr "Verificação completa - não houve nenhuma alteração de arquivo detectado!" + +#: admin/wp-security-filescan-menu.php:133 +msgid "You entered a non numeric value for the \"backup time interval\" field. It has been set to the default value." +msgstr "Você digitou um valor não numérico para o campo \"intervalo de tempo de backup\". Foi definido como o valor padrão." + +#: admin/wp-security-filescan-menu.php:167 +msgid "The following address was removed because it is not a valid email address: " +msgstr "" + +#: admin/wp-security-filescan-menu.php:206 +msgid "NEW SCAN COMPLETED: The plugin has detected that you have made changes to the \"File Types To Ignore\" or \"Files To Ignore\" fields." +msgstr "" + +#: admin/wp-security-filescan-menu.php:206 +msgid "In order to ensure that future scan results are accurate, the old scan data has been refreshed." +msgstr "" + +#: admin/wp-security-filescan-menu.php:215 +msgid "All In One WP Security & Firewall has detected that there was a change in your host's files." +msgstr "All In One WP Security e Firewall detectou que houve uma mudança nos arquivos do seu hospedeiro." + +#: admin/wp-security-filescan-menu.php:217 +msgid "View scan details and clear this message" +msgstr "" + +#: admin/wp-security-filescan-menu.php:226 +msgid "If given an opportunity hackers can insert their code or files into your system which they can then use to carry out malicious acts on your site." +msgstr "Se lhe for dada uma oportunidade os hackers podem inserir o seu código ou arquivos em seu sistema que eles podem usar para realizar atos maliciosos em seu site." + +#: admin/wp-security-filescan-menu.php:227 +msgid "Being informed of any changes in your files can be a good way to quickly prevent a hacker from causing damage to your website." +msgstr "Sendo informado de quaisquer alterações em seus arquivos pode ser uma boa maneira de evitar rapidamente um hacker de causar danos ao seu site." + +#: admin/wp-security-filescan-menu.php:228 +msgid "In general, WordPress core and plugin files and file types such as \".php\" or \".js\" should not change often and when they do, it is important that you are made aware when a change occurs and which file was affected." +msgstr "Em geral, arquivos de núcleo e plugin do WordPress e tipos de arquivo como \".php\" ou \".js\" não devem mudar frequentemente e quando o fazem, é importante que você esteja ciente quando uma alteração ocorre e qual arquivo foi afetado." + +#: admin/wp-security-filescan-menu.php:229 +msgid "The \"File Change Detection Feature\" will notify you of any file change which occurs on your system, including the addition and deletion of files by performing a regular automated or manual scan of your system's files." +msgstr "O \"recurso de detecção de alteração de arquivo\" irá notificá-lo de qualquer alteração de arquivo que ocorre em seu sistema, incluindo a adição e exclusão de arquivos através da realização de uma verificação regular, automatizado ou manual de arquivos do seu sistema." + +#: admin/wp-security-filescan-menu.php:230 +msgid "This feature also allows you to exclude certain files or folders from the scan in cases where you know that they change often as part of their normal operation. (For example log files and certain caching plugin files may change often and hence you may choose to exclude such files from the file change detection scan)" +msgstr "Este recurso também permite excluir determinados arquivos ou pastas da verificação nos casos em que você sabe que eles mudam frequentemente como parte de sua operação normal. (Por exemplo arquivos de log e determinados arquivos de plugin de cache podem mudar muitas vezes e, portanto, você pode optar por excluir esses arquivos da verificação de detecção de alteração de arquivo)" + +#: admin/wp-security-filescan-menu.php:241 +msgid "It appears that your server is using an old PHP version which is missing the %s. The file scanner feature needs this class in order to work. If you would like to use this feature please upgrade your server PHP version to 5.3 or greater." +msgstr "" + +#: admin/wp-security-filescan-menu.php:249 +msgid "Manual file change detection scan" +msgstr "Verificação de detecção de alteração manual de arquivo" + +#: admin/wp-security-filescan-menu.php:255 +msgid "To perform a manual file change detection scan click on the button below." +msgstr "Para realizar uma verificação de detecção de alteração manual de arquivo clique no botão abaixo." + +#: admin/wp-security-filescan-menu.php:258 +msgid "Perform scan now" +msgstr "Efetuar uma verificação agora" + +#: admin/wp-security-filescan-menu.php:262 +msgid "View last saved file change results" +msgstr "Exibir últimos resultados salvos de alteração de arquivo" + +#: admin/wp-security-filescan-menu.php:268 +msgid "Click the button below to view the saved file change results from the last scan." +msgstr "Clique no botão abaixo para visualizar os resultados de alteração de arquivos salvos da última verificação." + +#: admin/wp-security-filescan-menu.php:271 +msgid "View last file change" +msgstr "Visualizar últimas alterações de arquivo" + +#: admin/wp-security-filescan-menu.php:275 +msgid "File change detection settings" +msgstr "Configuração de detecção de alteração de arquivo" + +#: admin/wp-security-filescan-menu.php:287 +msgid "Enable automated file change detection scan" +msgstr "Habilitar a verificação de detecção automatizada de alteração de arquivos" + +#: admin/wp-security-filescan-menu.php:290 +msgid "Check this if you want the system to automatically/periodically scan your files to check for file changes based on the settings below" +msgstr "Marque isso, se você deseja que o sistema automaticamente/periodicamente digitalizar seus arquivos para verificar se há alterações de arquivo com base nas configurações abaixo" + +#: admin/wp-security-filescan-menu.php:294 +msgid "Scan time interval" +msgstr "Intervalo de tempo para verificação" + +#: admin/wp-security-filescan-menu.php:297 +msgid "Hours" +msgstr "Horas" + +#: admin/wp-security-filescan-menu.php:298 +msgid "Days" +msgstr "Dias" + +#: admin/wp-security-filescan-menu.php:299 +msgid "Weeks" +msgstr "Semanas" + +#: admin/wp-security-filescan-menu.php:301 +msgid "Set the value for how often you would like a scan to occur" +msgstr "Defina o valor para quantas vezes você gostaria de ter uma verificação para ocorrer" + +#: admin/wp-security-filescan-menu.php:305 +msgid "File types to ignore" +msgstr "Tipos de arquivo para ignorar" + +#: admin/wp-security-filescan-menu.php:308 +msgid "Enter each file type or extension on a new line which you wish to exclude from the file change detection scan." +msgstr "Digite cada tipo de arquivo ou extensão em uma nova linha que você deseja excluir da análise de detecção de alteração de arquivo." + +#: admin/wp-security-filescan-menu.php:312 +msgid "You can exclude file types from the scan which would not normally pose any security threat if they were changed. These can include things such as image files." +msgstr "Você pode excluir tipos de arquivo da verificação que normalmente não representa qualquer ameaça de segurança se eles foram alterados. Estes podem incluir coisas tais como arquivos de imagem." + +#: admin/wp-security-filescan-menu.php:313 +msgid "Example: If you want the scanner to ignore files of type jpg, png, and bmp, then you would enter the following:" +msgstr "Exemplo: Se você deseja que a verificação ignore arquivos do tipo jpg, png e bmp, em seguida, você deve digitar o seguinte:" + +#: admin/wp-security-filescan-menu.php:314 +msgid "jpg" +msgstr "jpg" + +#: admin/wp-security-filescan-menu.php:315 +msgid "png" +msgstr "png" + +#: admin/wp-security-filescan-menu.php:316 +msgid "bmp" +msgstr "bmp" + +#: admin/wp-security-filescan-menu.php:322 +msgid "Files/Directories to ignore" +msgstr "Arquivos/Diretórios para ignorar" + +#: admin/wp-security-filescan-menu.php:325 +msgid "Enter each file or directory on a new line which you wish to exclude from the file change detection scan." +msgstr "Digite cada arquivo ou diretório em uma nova linha que você deseja excluir da análise de detecção de alteração de arquivo." + +#: admin/wp-security-filescan-menu.php:329 +msgid "You can exclude specific files/directories from the scan which would not normally pose any security threat if they were changed. These can include things such as log files." +msgstr "Você pode excluir arquivos/diretórios específicos da verificação que normalmente não representem qualquer ameaça à segurança se eles foram alterados. Estes podem incluir coisas tais como arquivos de log." + +#: admin/wp-security-filescan-menu.php:330 +msgid "Example: If you want the scanner to ignore certain files in different directories or whole directories, then you would enter the following:" +msgstr "Exemplo: Se você deseja que a verificação ignore determinados arquivos em diferentes pastas ou diretórios inteiros, então você deve digitar o seguinte:" + +#: admin/wp-security-filescan-menu.php:331 +msgid "cache/config/master.php" +msgstr "cache/config/master.php" + +#: admin/wp-security-filescan-menu.php:332 +msgid "somedirectory" +msgstr "somedirectory" + +#: admin/wp-security-filescan-menu.php:339 +msgid "Send email when change detected" +msgstr "Enviar e-mail quando detectada alteração" + +#: admin/wp-security-filescan-menu.php:343 +msgid "Check this if you want the system to email you if a file change was detected" +msgstr "Marque esta opção se você deseja que o sistema envie um e-mail, se foi detectada uma alteração no arquivo" + +#: admin/wp-security-filescan-menu.php:347 +msgid "Enter one or more email addresses on a new line." +msgstr "Digite um ou mais endereços de e-mail em uma nova linha." + +#: admin/wp-security-filescan-menu.php:364 +msgid "What is malware?" +msgstr "O que é Malware?" + +#: admin/wp-security-filescan-menu.php:365 +msgid "The word malware stands for Malicious Software. It can consist of things like trojan horses, adware, worms, spyware and any other undesirable code which a hacker will try to inject into your website." +msgstr "A palavra Malware significa software malicioso. Ele pode consistir de coisas como cavalos de tróia, adware, worms, spyware e qualquer outro código indesejável que um hacker irá tentar injetar em seu site." + +#: admin/wp-security-filescan-menu.php:366 +msgid "Often when malware code has been inserted into your site you will normally not notice anything out of the ordinary based on appearances, but it can have a dramatic effect on your site's search ranking." +msgstr "Muitas vezes, quando código de malware foi inserido em seu site você normalmente não vai notar nada fora do comum, com base em aparências, mas pode ter um efeito dramático no ranking de busca do seu site." + +#: admin/wp-security-filescan-menu.php:367 +msgid "This is because the bots and spiders from search engines such as Google have the capability to detect malware when they are indexing the pages on your site, and consequently they can blacklist your website which will in turn affect your search rankings." +msgstr "Isso ocorre porque os robôs e aranhas dos motores de busca como o Google tem a capacidade de detectar malware quando eles estão indexando as páginas do seu site, e, consequentemente, pode barrar seu site, que por sua vez irá afetar seus rankings de busca." + +#: admin/wp-security-filescan-menu.php:369 +msgid "CLICK HERE" +msgstr "" + +#: admin/wp-security-filescan-menu.php:371 +msgid "Scanning for malware" +msgstr "Verificação de Malware" + +#: admin/wp-security-filescan-menu.php:372 +msgid "Due to the constantly changing and complex nature of Malware, scanning for such things using a standalone plugin will not work reliably. This is something best done via an external scan of your site regularly." +msgstr "Devido à natureza de constante mudança e complexo de Malware, verificação para tais coisas usando um plugin autônomo não vai funcionar de forma confiável. Isso é algo melhor feito através de uma verificação externa de seu site regularmente." + +#: admin/wp-security-filescan-menu.php:373 +msgid "This is why we have created an easy-to-use scanning service which is hosted off our own server which will scan your site for malware once every day and notify you if it finds anything." +msgstr "É por isso que criamos um serviço de verificação de fácil utilização que está hospedado fora de nosso próprio servidor, que irá analisar o seu site em busca de malware, uma vez por dia e notificá-lo se ele encontrar qualquer coisa." + +#: admin/wp-security-filescan-menu.php:374 +msgid "When you sign up for this service you will get the following:" +msgstr "Quando você se inscrever para este serviço, você receberá o seguinte:" + +#: admin/wp-security-filescan-menu.php:376 +msgid "Automatic daily scan of 1 website" +msgstr "Verificação automática diária de 1 site" + +#: admin/wp-security-filescan-menu.php:377 +msgid "Automatic malware and blacklist monitoring" +msgstr "" + +#: admin/wp-security-filescan-menu.php:378 +msgid "Automatic email alerting" +msgstr "Alerta automático por e-mail" + +#: admin/wp-security-filescan-menu.php:379 +msgid "Site uptime monitoring" +msgstr "Monitoramento do tempo de atividade do site" + +#: admin/wp-security-filescan-menu.php:380 +msgid "Site response time monitoring" +msgstr "Monitoramento do tempo de resposta do site" + +#: admin/wp-security-filescan-menu.php:381 +msgid "We provide advice for malware cleanup" +msgstr "" + +#: admin/wp-security-filescan-menu.php:382 +msgid "Blacklist removal" +msgstr "Remoção da lista negra" + +#: admin/wp-security-filescan-menu.php:383 +msgid "No contract (cancel anytime)" +msgstr "Não há contrato (cancelar a qualquer momento)" + +#: admin/wp-security-filescan-menu.php:385 +msgid "To learn more please %s." +msgstr "Para saber mais, por favor %s." + +#: admin/wp-security-filescan-menu.php:406 +msgid "Latest file change scan results" +msgstr "Últimos resultados de verificação de alteração de arquivo" + +#: admin/wp-security-filescan-menu.php:416 +msgid "The following files were added to your host." +msgstr "Os seguintes arquivos foram adicionados ao seu host" + +#: admin/wp-security-filescan-menu.php:419 +#: admin/wp-security-filescan-menu.php:440 +#: admin/wp-security-filescan-menu.php:464 +msgid "File" +msgstr "Arquivo" + +#: admin/wp-security-filescan-menu.php:420 +#: admin/wp-security-filescan-menu.php:441 +#: admin/wp-security-filescan-menu.php:465 +msgid "File size" +msgstr "Tamanho do arquivo" + +#: admin/wp-security-filescan-menu.php:421 +#: admin/wp-security-filescan-menu.php:442 +#: admin/wp-security-filescan-menu.php:466 +msgid "File modified" +msgstr "Arquivo modificado" + +#: admin/wp-security-filescan-menu.php:437 +msgid "The following files were removed from your host." +msgstr "Os seguintes arquivos foram removidos do seu hospedeiro" + +#: admin/wp-security-filescan-menu.php:461 +msgid "The following files were changed on your host." +msgstr "Os seguintes arquivos foram alterados em seu hospedeiro" + +#: admin/wp-security-filesystem-menu.php:26 +#: classes/grade-system/wp-security-feature-item-manager.php:69 +msgid "File permissions" +msgstr "Permissões de arquivos" + +#: admin/wp-security-filesystem-menu.php:27 +msgid "PHP file editing" +msgstr "Edição de arquivo PHP" + +#: admin/wp-security-filesystem-menu.php:28 +msgid "WP file access" +msgstr "Acesso ao arquivo WP" + +#: admin/wp-security-filesystem-menu.php:29 +msgid "Host system logs" +msgstr "Logs do sistema hospedeiro" + +#: admin/wp-security-filesystem-menu.php:55 +msgid "Filesystem security" +msgstr "Segurança de arquivos" + +#: admin/wp-security-filesystem-menu.php:80 +msgid "Nonce check failed for manual DB backup operation!" +msgstr "Verificação núncio falhou para operação de backup manual do banco de dados!" + +#: admin/wp-security-filesystem-menu.php:90 +msgid "The permissions for %s were succesfully changed to %s" +msgstr "As permissões de %s foram alteradas com sucesso para %s" + +#: admin/wp-security-filesystem-menu.php:94 +msgid "Unable to change permissions for %s!" +msgstr "Não foi possível alterar as permissões de %s!" + +#: admin/wp-security-filesystem-menu.php:100 +msgid "File permissions scan" +msgstr "Verificação de permissão de arquivos" + +#: admin/wp-security-filesystem-menu.php:103 +msgid "Your WordPress file and folder permission settings govern the accessability and read/write privileges of the files and folders which make up your WP installation." +msgstr "Suas configurações de permissão de arquivo e pasta WordPress governam os privilégios de acessibilidades e leitura/gravação de arquivos e pastas que compõem sua instalação do WP." + +#: admin/wp-security-filesystem-menu.php:104 +msgid "Your WP installation already comes with reasonably secure file permission settings for the filesystem." +msgstr "Sua instalação WP já vem com configurações de permissão de arquivo razoavelmente segura para o sistema de arquivos." + +#: admin/wp-security-filesystem-menu.php:105 +msgid "However, sometimes people or other plugins modify the various permission settings of certain core WP folders or files such that they end up making their site less secure because they chose the wrong permission values." +msgstr "No entanto, às vezes as pessoas ou outros plugins modificar as várias configurações de permissão de determinados arquivos ou pastas do núcleo WP tal que eles acabam fazendo com que seu site menos seguro porque eles escolheram os valores de permissão errados." + +#: admin/wp-security-filesystem-menu.php:106 +msgid "This feature will scan the critical WP core folders and files and will highlight any permission settings which are insecure." +msgstr "Esta recurso irá verificar as pastas e arquivos críticos do núcleo WP e irá destacar quaisquer configurações de permissão que são inseguros." + +#: admin/wp-security-filesystem-menu.php:114 +msgid "This plugin has detected that your site is running on a Windows server." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:115 +msgid "This feature is not applicable for Windows server installations." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:121 +msgid "WP directory and file permissions scan results" +msgstr "Resultados de pesquisa de permissões de arquivo e diretório WP" + +#: admin/wp-security-filesystem-menu.php:133 +#: admin/wp-security-filesystem-menu.php:152 +msgid "Name" +msgstr "Nome" + +#: admin/wp-security-filesystem-menu.php:134 +#: admin/wp-security-filesystem-menu.php:153 +msgid "File/Folder" +msgstr "Arquivo / Pasta" + +#: admin/wp-security-filesystem-menu.php:135 +#: admin/wp-security-filesystem-menu.php:154 +msgid "Current permissions" +msgstr "Permissões atuais" + +#: admin/wp-security-filesystem-menu.php:136 +#: admin/wp-security-filesystem-menu.php:155 +msgid "Recommended permissions" +msgstr "Permissões recomendadas" + +#: admin/wp-security-filesystem-menu.php:137 +#: admin/wp-security-filesystem-menu.php:156 +msgid "Recommended action" +msgstr "Ação recomendada" + +#: admin/wp-security-filesystem-menu.php:195 +msgid "Your PHP file editing settings were saved successfully." +msgstr "Suas configurações de edição de arquivos PHP foram salvas com sucesso." + +#: admin/wp-security-filesystem-menu.php:199 +msgid "Operation failed! Unable to modify or make a backup of wp-config.php file!" +msgstr "Operação falhou! Não é possível modificar ou fazer um backup do arquivo wp-config.php!" + +#: admin/wp-security-filesystem-menu.php:212 +#: classes/grade-system/wp-security-feature-item-manager.php:71 +msgid "File editing" +msgstr "Edição de arquivo" + +#: admin/wp-security-filesystem-menu.php:215 +msgid "The WordPress Dashboard by default allows administrators to edit PHP files, such as plugin and theme files." +msgstr "O painel do Wordpress por padrão permite que os administradores editar arquivos PHP, tais como arquivos de plugin e tema." + +#: admin/wp-security-filesystem-menu.php:216 +msgid "This is often the first tool an attacker will use if able to login, since it allows code execution." +msgstr "Isso é muitas vezes a primeira ferramenta que um invasor irá usar se for capaz de fazer o login, uma vez que permite a execução de código." + +#: admin/wp-security-filesystem-menu.php:217 +msgid "This feature will disable the ability for people to edit PHP files via the dashboard." +msgstr "Este recurso irá desativar a capacidade para as pessoas editar arquivos PHP através do painel de controle." + +#: admin/wp-security-filesystem-menu.php:223 +msgid "Disable PHP file editing" +msgstr "Desativar edição de arquivo PHP" + +#: admin/wp-security-filesystem-menu.php:235 +msgid "Disable ability to edit PHP files" +msgstr "Desativar a capacidade para editar arquivos PHP" + +#: admin/wp-security-filesystem-menu.php:238 +msgid "Check this if you want to remove the ability for people to edit PHP files via the WP dashboard" +msgstr "Marque esta opção se você deseja remover a capacidade de pessoas para editar arquivos PHP através do painel WP" + +#: admin/wp-security-filesystem-menu.php:282 +msgid "You have successfully saved the Prevent Access to Default WP Files configuration." +msgstr "Você salvou com sucesso a impedir acesso à configuração de arquivos padrão do WP." + +#: admin/wp-security-filesystem-menu.php:286 +#: admin/wp-security-firewall-menu.php:126 +#: admin/wp-security-firewall-menu.php:346 +#: admin/wp-security-firewall-menu.php:613 +#: admin/wp-security-firewall-menu.php:912 +#: admin/wp-security-settings-menu.php:772 +#: admin/wp-security-spam-menu.php:124 +msgid "Could not write to the .htaccess file. Please check the file permissions." +msgstr "Não foi possível gravar no arquivo .htaccess. Por favor, verifique as permissões do arquivo." + +#: admin/wp-security-filesystem-menu.php:291 +msgid "WordPress files" +msgstr "Arquivos WordPress" + +#: admin/wp-security-filesystem-menu.php:294 +msgid "This feature allows you to prevent access to files such as %s, %s and %s which are delivered with all WP installations." +msgstr "Esse recurso permite-lhe impedir o acesso a arquivos, como %s, %s e %s, que são entregues com todas as instalações WP." + +#: admin/wp-security-filesystem-menu.php:295 +msgid "By preventing access to these files you are hiding some key pieces of information (such as WordPress version info) from potential hackers." +msgstr "Ao impedir o acesso a esses arquivos que você está escondendo algumas peças-chave de informação (por exemplo, informações de versão do WordPress) dos potenciais hackers." + +#: admin/wp-security-filesystem-menu.php:300 +msgid "Prevent access to default WP files" +msgstr "Impedir o acesso a arquivos padrão do WP" + +#: admin/wp-security-filesystem-menu.php:311 +msgid "Prevent access to WP default install files" +msgstr "Impedir o acesso a arquivos de instalação padrão do WP" + +#: admin/wp-security-filesystem-menu.php:314 +msgid "Check this if you want to prevent access to readme.html, license.txt and wp-config-sample.php." +msgstr "Marque esta opção se você deseja impedir o acesso a readme.html, license.txt and wp-config-sample.php." + +#: admin/wp-security-filesystem-menu.php:318 +msgid "Save setting" +msgstr "Salvar configuração" + +#: admin/wp-security-filesystem-menu.php:342 +msgid "System logs" +msgstr "Logs do sistema" + +#: admin/wp-security-filesystem-menu.php:345 +msgid "Sometimes your hosting platform will produce error or warning logs in a file called \"error_log\"." +msgstr "Às vezes sua plataforma de hospedagem irá produzir erro ou logs de aviso em um arquivo chamado \"error_log\"." + +#: admin/wp-security-filesystem-menu.php:346 +msgid "Depending on the nature and cause of the error or warning, your hosting server can create multiple instances of this file in numerous directory locations of your WordPress installation." +msgstr "Dependendo da natureza e da causa do erro ou aviso, seu servidor de hospedagem pode criar várias instâncias deste arquivo em vários locais do diretório de sua instalação do WordPress." + +#: admin/wp-security-filesystem-menu.php:347 +msgid "By occassionally viewing the contents of these logs files you can keep informed of any underlying problems on your system which you might need to address." +msgstr "Por ocasionalmente exibindo o conteúdo desses arquivos de logs que pode manter-se informado de quaisquer problemas subjacentes em seu sistema que você pode precisar do endereço para resolver." + +#: admin/wp-security-filesystem-menu.php:353 +msgid "View system logs" +msgstr "Ver logs do sistema" + +#: admin/wp-security-filesystem-menu.php:355 +msgid "Please click the button below to view the latest system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:358 +msgid "Enter System Log File Name" +msgstr "Digite o nome do arquivo de log do sistema" + +#: admin/wp-security-filesystem-menu.php:360 +msgid "Enter your system log file name. (Defaults to error_log)" +msgstr "Digite seu nome de arquivo de log do sistema. (Padrões para error_log)" + +#: admin/wp-security-filesystem-menu.php:363 +msgid "View latest system logs" +msgstr "Ver logs mais recentes do sistema" + +#: admin/wp-security-filesystem-menu.php:365 +msgid "Loading..." +msgstr "Carregando..." + +#: admin/wp-security-filesystem-menu.php:382 +msgid "No system logs were found." +msgstr "Nenhum registro de logs do sistema foram encontrados!" + +#: admin/wp-security-filesystem-menu.php:435 +msgid "Set recommended permissions" +msgstr "Conjunto recomendado de permissões" + +#: admin/wp-security-filesystem-menu.php:441 +msgid "No action required" +msgstr "Nenhuma ação necessária." + +#: admin/wp-security-filesystem-menu.php:481 +msgid "Showing latest entries of error_log file: %s" +msgstr "Mostrando as últimas entradas de arquivo error_log: %s" + +#: admin/wp-security-firewall-menu.php:28 +msgid "Basic firewall rules" +msgstr "Regras básicas do firewall" + +#: admin/wp-security-firewall-menu.php:29 +msgid "Additional firewall rules" +msgstr "Regras adicionais do firewall" + +#: admin/wp-security-firewall-menu.php:30 +msgid "6G Blacklist firewall rules" +msgstr "Regras do firewall de lista negra 6G" + +#: admin/wp-security-firewall-menu.php:31 +msgid "Internet bots" +msgstr "Robôs da internet" + +#: admin/wp-security-firewall-menu.php:32 +msgid "Prevent hotlinks" +msgstr "Impedir hotlinks" + +#: admin/wp-security-firewall-menu.php:33 +msgid "404 detection" +msgstr "Detecção 404" + +#: admin/wp-security-firewall-menu.php:34 +msgid "Custom rules" +msgstr "Regras personalizadas" + +#: admin/wp-security-firewall-menu.php:122 +#: admin/wp-security-firewall-menu.php:908 +#: admin/wp-security-spam-menu.php:120 +#: admin/wp-security-spam-menu.php:494 +#: admin/wp-security-spam-menu.php:556 +#: admin/wp-security-user-registration-menu.php:95 +msgid "Settings were successfully saved" +msgstr "Configurações foram salvas com sucesso" + +#: admin/wp-security-firewall-menu.php:131 +#: admin/wp-security-firewall-menu.php:651 +msgid "Firewall settings" +msgstr "Configurações do firewall" + +#: admin/wp-security-firewall-menu.php:138 +msgid "This should not have any impact on your site's general functionality but if you wish you can take a %s of your .htaccess file before proceeding." +msgstr "Isto não deve ter nenhum impacto sobre a funcionalidade geral do seu site, mas se você quiser, você pode tomar um %s do seu arquivo .htaccess antes de prosseguir." + +#: admin/wp-security-firewall-menu.php:139 +msgid "The features in this tab allow you to activate some basic firewall security protection rules for your site." +msgstr "Os recursos neste guia permitem que você ative algumas regras básicas de proteção de segurança de firewall para o seu site." + +#: admin/wp-security-firewall-menu.php:140 +msgid "The firewall functionality is achieved via the insertion of special code into your currently active .htaccess file." +msgstr "A funcionalidade de firewall é conseguida através da inserção de código especial em seu arquivo .htaccess atualmente ativo." + +#: admin/wp-security-firewall-menu.php:151 +msgid "You have enabled the \"Completely Block Access To XMLRPC\" checkbox which means all XMLRPC functionality will be blocked." +msgstr "" + +#: admin/wp-security-firewall-menu.php:152 +msgid "By leaving this feature enabled you will prevent Jetpack or Wordpress iOS or other apps which need XMLRPC from working correctly on your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:153 +msgid "If you still need XMLRPC then uncheck the \"Completely Block Access To XMLRPC\" checkbox and enable only the \"Disable Pingback Functionality From XMLRPC\" checkbox." +msgstr "" + +#: admin/wp-security-firewall-menu.php:163 +msgid "Basic firewall settings" +msgstr "Configurações de firewall básico" + +#: admin/wp-security-firewall-menu.php:171 +msgid "Enable basic firewall protection" +msgstr "Habilitar proteção de firewall básico" + +#: admin/wp-security-firewall-menu.php:174 +msgid "Check this if you want to apply basic firewall protection to your site." +msgstr "Marque esta opção se você deseja aplicar a proteção de firewall básico para o seu site." + +#: admin/wp-security-firewall-menu.php:178 +msgid "This setting will implement the following basic firewall protection mechanisms on your site:" +msgstr "Esta configuração irá implementar os seguintes mecanismos de proteção básica do firewall no seu site:" + +#: admin/wp-security-firewall-menu.php:179 +msgid "1) Protect your htaccess file by denying access to it." +msgstr "1) Proteja o seu arquivo .htaccess, negando o acesso a ele." + +#: admin/wp-security-firewall-menu.php:180 +msgid "2) Disable the server signature." +msgstr "2) Desativa a assinatura do servidor." + +#: admin/wp-security-firewall-menu.php:181 +msgid "3) Limit file upload size (%sMB)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:182 +msgid "4) Protect your wp-config.php file by denying access to it." +msgstr "4) Protege seu arquivo wp-config.php, negando o acesso a ele." + +#: admin/wp-security-firewall-menu.php:183 +msgid "The above firewall features will be applied via your .htaccess file and should not affect your site's overall functionality." +msgstr "Os recursos de firewall acima serão aplicados através de seu arquivo .htaccess e não devem afetar a funcionalidade geral do seu site." + +#: admin/wp-security-firewall-menu.php:184 +msgid "You are still advised to take a backup of your active .htaccess file just in case." +msgstr "Ainda é aconselhável fazer um backup de seu arquivo .htaccess ativo apenas no caso." + +#: admin/wp-security-firewall-menu.php:190 +msgid "Max file upload size (MB)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:192 +msgid "The value for the maximum file upload size used in the .htaccess file. (Defaults to %sMB if left blank)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:200 +msgid "WordPress XMLRPC and pingback vulnerability protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:208 +msgid "Completely block access to XMLRPC" +msgstr "" + +#: admin/wp-security-firewall-menu.php:211 +msgid "Check this if you are not using the WP XML-RPC functionality and you want to completely block external access to XMLRPC." +msgstr "" + +#: admin/wp-security-firewall-menu.php:215 +msgid "This setting will add a directive in your .htaccess to disable access to the WordPress xmlrpc.php file which is responsible for the XML-RPC functionality in WordPress." +msgstr "" + +#: admin/wp-security-firewall-menu.php:216 +msgid "Hackers can exploit various vulnerabilities in the WordPress XML-RPC API in a number of ways such as:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:217 +msgid "1) Denial of Service (DoS) attacks" +msgstr "1) Ataques de negação de serviço (DoS)" + +#: admin/wp-security-firewall-menu.php:218 +msgid "2) Hacking internal routers." +msgstr "2) Roteadores internos pirata." + +#: admin/wp-security-firewall-menu.php:219 +msgid "3) Scanning ports in internal networks to get info from various hosts." +msgstr "3) Varredura de portas em redes internas para obter informações de vários hosts." + +#: admin/wp-security-firewall-menu.php:220 +msgid "Apart from the security protection benefit, this feature may also help reduce load on your server, particularly if your site currently has a lot of unwanted traffic hitting the XML-RPC API on your installation." +msgstr "Além do benefício de proteção de segurança, esse recurso também pode ajudar a reduzir a carga no seu servidor, especialmente quando o site tem atualmente uma grande quantidade de tráfego indesejado, batendo o XML-RPC API em sua instalação." + +#: admin/wp-security-firewall-menu.php:221 +msgid "NOTE: You should only enable this feature if you are not currently using the XML-RPC functionality on your WordPress installation." +msgstr "NOTA: Você só deve ativar esse recurso se você não estiver usando atualmente a funcionalidade XML-RPC em sua instalação do WordPress." + +#: admin/wp-security-firewall-menu.php:222 +msgid "Leave this feature disabled and use the feature below if you want pingback protection but you still need XMLRPC." +msgstr "" + +#: admin/wp-security-firewall-menu.php:228 +msgid "Disable pingback functionality from XMLRPC" +msgstr "" + +#: admin/wp-security-firewall-menu.php:231 +msgid "If you use Jetpack or WP iOS or other apps which need WP XML-RPC functionality then check this. This will enable protection against WordPress pingback vulnerabilities." +msgstr "" + +#: admin/wp-security-firewall-menu.php:235 +msgid "NOTE: If you use Jetpack or the Wordpress iOS or other apps then you should enable this feature but leave the \"Completely Block Access To XMLRPC\" checkbox unchecked." +msgstr "" + +#: admin/wp-security-firewall-menu.php:236 +msgid "The feature will still allow XMLRPC functionality on your site but will disable the pingback methods." +msgstr "" + +#: admin/wp-security-firewall-menu.php:237 +msgid "This feature will also remove the \"X-Pingback\" header if it is present." +msgstr "" + +#: admin/wp-security-firewall-menu.php:246 +msgid "Block access to debug log file" +msgstr "" + +#: admin/wp-security-firewall-menu.php:254 +msgid "Block access to debug.log file" +msgstr "Bloquear o acesso ao arquivo debug.log" + +#: admin/wp-security-firewall-menu.php:257 +msgid "Check this if you want to block access to the debug.log file that WordPress creates when debug logging is enabled." +msgstr "Marque esta opção se você deseja bloquear o acesso ao arquivo debug.log que o WordPress cria quando o registo de depuração está habilitado." + +#: admin/wp-security-firewall-menu.php:261 +msgid "WordPress has an option to turn on the debug logging to a file located in wp-content/debug.log. This file may contain sensitive information." +msgstr "WordPress tem uma opção para ativar o registro de depuração para um arquivo localizado em wp-content/debug.log. Este arquivo pode conter informações confidenciais." + +#: admin/wp-security-firewall-menu.php:262 +msgid "Using this option will block external access to this file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:262 +msgid "You can still access this file by logging into your site via FTP." +msgstr "" + +#: admin/wp-security-firewall-menu.php:270 +msgid "Save basic firewall settings" +msgstr "Salvar configurações de firewall básico" + +#: admin/wp-security-firewall-menu.php:342 +msgid "You have successfully saved the Additional Firewall Protection configuration" +msgstr "Você salvou com sucesso a configuração adicional de proteção por firewall" + +#: admin/wp-security-firewall-menu.php:356 +msgid "Additional firewall protection" +msgstr "Proteção de firewall adicional" + +#: admin/wp-security-firewall-menu.php:360 +msgid "Due to the nature of the code being inserted to the .htaccess file, this feature may break some functionality for certain plugins and you are therefore advised to take a %s of .htaccess before applying this configuration." +msgstr "Devido à natureza do código que está sendo inserido no arquivo .htaccess, esse recurso pode quebrar algumas funcionalidades para certos plugins e, portanto, você é aconselhado a tomar um %s do .htaccess antes de aplicar essa configuração." + +#: admin/wp-security-firewall-menu.php:362 +msgid "This feature allows you to activate more advanced firewall settings to your site." +msgstr "Este recurso permite que você ative as configurações de firewall mais avançadas para o seu site." + +#: admin/wp-security-firewall-menu.php:363 +msgid "The advanced firewall rules are applied via the insertion of special code to your currently active .htaccess file." +msgstr "As regras de firewall avançado são aplicadas através da inserção de código especial para seu arquivo .htaccess atualmente ativo." + +#: admin/wp-security-firewall-menu.php:372 +msgid "Listing of directory contents" +msgstr "Listagem do conteúdo do diretório" + +#: admin/wp-security-firewall-menu.php:381 +#: classes/grade-system/wp-security-feature-item-manager.php:85 +msgid "Disable index views" +msgstr "Desabilitar visualizações de índice" + +#: admin/wp-security-firewall-menu.php:384 +msgid "Check this if you want to disable directory and file listing." +msgstr "Marque esta opção se você deseja desativar o diretório e lista de arquivos." + +#: admin/wp-security-firewall-menu.php:389 +msgid "By default, an Apache server will allow the listing of the contents of a directory if it doesn't contain an index.php file." +msgstr "Por padrão, um servidor Apache permitirá a listagem do conteúdo de um diretório, se ele não contém um arquivo index.php." + +#: admin/wp-security-firewall-menu.php:391 +msgid "This feature will prevent the listing of contents for all directories." +msgstr "Este recurso impedirá a listagem de conteúdos para todos os diretórios." + +#: admin/wp-security-firewall-menu.php:393 +msgid "NOTE: In order for this feature to work \"AllowOverride\" of the Indexes directive must be enabled in your httpd.conf file. Ask your hosting provider to check this if you don't have access to httpd.conf" +msgstr "NOTA: Para que este recurso funcione \"AllowOverride\" da directiva índices deve estar habilitada no seu arquivo httpd.conf. Pergunte ao seu provedor de hospedagem para verificar isso, se você não tem acesso ao httpd.conf " + +#: admin/wp-security-firewall-menu.php:402 +msgid "Trace and track" +msgstr "Rastrear e acompanhar" + +#: admin/wp-security-firewall-menu.php:411 +#: classes/grade-system/wp-security-feature-item-manager.php:86 +msgid "Disable trace and track" +msgstr "Desabilitar o rastreamento e acompanhamento" + +#: admin/wp-security-firewall-menu.php:414 +msgid "Check this if you want to disable trace and track." +msgstr "Marque esta opção se você deseja desativar o rastreamento e acompanhamento." + +#: admin/wp-security-firewall-menu.php:419 +msgid "HTTP Trace attack (XST) can be used to return header requests and grab cookies and other information." +msgstr "Ataque de rastreamento HTTP (XST) pode ser usado para retornar solicitações de cabeçalho e cookies de apoio e outras informações." + +#: admin/wp-security-firewall-menu.php:421 +msgid "This hacking technique is usually used together with cross site scripting attacks (XSS)." +msgstr "Esta técnica de hacking é geralmente usado em conjunto com ataques de script entre sites (XSS)." + +#: admin/wp-security-firewall-menu.php:423 +msgid "Disabling trace and track on your site will help prevent HTTP Trace attacks." +msgstr "Desabilitação de rastreamento e acompanhamento em seu site irá ajudar a evitar ataques de rastreamento HTTP." + +#: admin/wp-security-firewall-menu.php:432 +msgid "Proxy comment posting" +msgstr "Postagem de comentário proxy" + +#: admin/wp-security-firewall-menu.php:442 +msgid "Forbid proxy comment posting" +msgstr "Proibir postagem de comentários de proxy" + +#: admin/wp-security-firewall-menu.php:445 +msgid "Check this if you want to forbid proxy comment posting." +msgstr "Marque esta opção se você deseja proibir postagem de comentários de proxy." + +#: admin/wp-security-firewall-menu.php:450 +msgid "This setting will deny any requests that use a proxy server when posting comments." +msgstr "Essa configuração negará quaisquer solicitações que usam um servidor proxy ao postar comentários." + +#: admin/wp-security-firewall-menu.php:451 +msgid "By forbidding proxy comments you are in effect eliminating some spam and other proxy requests." +msgstr "Proibindo comentários de proxy, você está em efeito, eliminando alguns SPAM e outras solicitações de proxy." + +#: admin/wp-security-firewall-menu.php:460 +msgid "Bad query strings" +msgstr "Sequências de caracteres de consulta ruim" + +#: admin/wp-security-firewall-menu.php:470 +msgid "Deny bad query strings" +msgstr "Negar sequências de caracteres de consulta ruim" + +#: admin/wp-security-firewall-menu.php:473 +msgid "This will help protect you against malicious queries via XSS." +msgstr "Isso ajudará a protegê-lo contra consultas maliciosas via XSS." + +#: admin/wp-security-firewall-menu.php:478 +msgid "This feature will write rules in your .htaccess file to prevent malicious string attacks on your site using XSS." +msgstr "Esse recurso irá escrever regras em seu arquivo .htaccess para impedir ataques maliciosos de sequência de caracteres no seu site usando XSS." + +#: admin/wp-security-firewall-menu.php:479 +msgid "NOTE: Some of these strings might be used for plugins or themes and hence this might break some functionality." +msgstr "NOTA: Algumas destas sequências de caracteres podem ser usadas para plugins ou temas e, portanto, isso pode quebrar algumas funcionalidades." + +#: admin/wp-security-firewall-menu.php:480 +#: admin/wp-security-firewall-menu.php:510 +msgid "You are therefore strongly advised to take a backup of your active .htaccess file before applying this feature." +msgstr "É, portanto, fortemente aconselhável fazer um backup de seu arquivo .htaccess ativo antes de aplicar esse recurso." + +#: admin/wp-security-firewall-menu.php:489 +#: classes/grade-system/wp-security-feature-item-manager.php:89 +msgid "Advanced character string filter" +msgstr "Filtro de sequência de caráter avançado" + +#: admin/wp-security-firewall-menu.php:499 +msgid "Enable advanced character string filter" +msgstr "Habilitar filtro de sequência de caráter avançado" + +#: admin/wp-security-firewall-menu.php:502 +msgid "This will block bad character matches from XSS." +msgstr "Isto irá bloquear mau caráter corresponde de XSS." + +#: admin/wp-security-firewall-menu.php:507 +msgid "This is an advanced character string filter to prevent malicious string attacks on your site coming from Cross Site Scripting (XSS)." +msgstr "Este é um filtro de sequência de caracteres de caráter avançado para impedir ataques maliciosos de sequência de caracteres em seu site vindo de Cross Site Scripting (XSS)." + +#: admin/wp-security-firewall-menu.php:508 +msgid "This setting matches for common malicious string patterns and exploits and will produce a 403 error for the hacker attempting the query." +msgstr "Essa configuração corresponde para exploits e padrões comuns de sequência malicioso e produzirá um erro 403 para o hacker tentar a consulta." + +#: admin/wp-security-firewall-menu.php:509 +msgid "NOTE: Some strings for this setting might break some functionality." +msgstr "NOTA: Algumas sequências de caracteres para esta configuração podem quebrar algumas funcionalidades." + +#: admin/wp-security-firewall-menu.php:518 +msgid "Save additional firewall settings" +msgstr "Salvar configurações de firewall adicional" + +#: admin/wp-security-firewall-menu.php:609 +msgid "You have successfully saved the 5G/6G Firewall Protection configuration" +msgstr "Você salvou com sucesso a configuração de proteção de firewall 5G/6G" + +#: admin/wp-security-firewall-menu.php:633 +msgid "All in One WP Security and Firewall" +msgstr "" + +#: admin/wp-security-firewall-menu.php:634 +msgid "We were unable to access the firewall's configuration file:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:636 +msgid "As a result, the firewall will be unavailable." +msgstr "" + +#: admin/wp-security-firewall-menu.php:637 +msgid "Please check your PHP error log for further information." +msgstr "" + +#: admin/wp-security-firewall-menu.php:638 +msgid "If you're unable to locate your PHP log file, please contact your web hosting company to ask them where it can be found on their setup." +msgstr "" + +#: admin/wp-security-firewall-menu.php:655 +msgid "This feature allows you to activate the %s (or legacy %s) firewall security protection rules designed and produced by %s." +msgstr "Esse recurso permite que você ative o %s (ou %s legado) regras de proteção de segurança de firewall projetado e produzido por %s." + +#: admin/wp-security-firewall-menu.php:656 +msgid "The 6G Blacklist is updated and improved version of 5G Blacklist. If you have 5G Blacklist active, you might consider activating 6G Blacklist instead." +msgstr "A lista negra 6G é atualizada e melhorada da versão da lista negra 5G. Se você tem lista negra 5G ativa, você pode considerar ativando a lista negra 6G em vez disso." + +#: admin/wp-security-firewall-menu.php:657 +msgid "The 6G Blacklist is a simple, flexible blacklist that helps reduce the number of malicious URL requests that hit your website." +msgstr "Lista negra 6G é uma lista negra simples, flexível, que ajuda a reduzir o número de solicitações de URL maliciosas que atingem seu site." + +#: admin/wp-security-firewall-menu.php:658 +msgid "The added advantage of applying the 6G firewall to your site is that it has been tested and confirmed by the people at PerishablePress.com to be an optimal and least disruptive set of .htaccess security rules for general WP sites running on an Apache server or similar." +msgstr "A vantagem de aplicar o firewall 6G para o seu site é que ele foi testado e confirmado pelas pessoas em PerishablePress.com ser um conjunto ideal e menos perturbadora de regras de segurança de .htaccess para sites gerais WP, executando em um servidor Apache ou similar." + +#: admin/wp-security-firewall-menu.php:659 +msgid "Therefore the 6G firewall rules should not have any impact on your site's general functionality but if you wish you can take a %s of your .htaccess file before proceeding." +msgstr "Portanto, as regras de firewall 6G não devem ter qualquer impacto na funcionalidade geral do seu site, mas se quiser você pode tomar um %s de seu arquivo .htaccess antes de prosseguir." + +#: admin/wp-security-firewall-menu.php:665 +msgid "6G blacklist/firewall settings" +msgstr "Configurações de firewall / lista negra 6G" + +#: admin/wp-security-firewall-menu.php:677 +msgid "Enable 6G firewall protection" +msgstr "Habilitar proteção de firewall 6G" + +#: admin/wp-security-firewall-menu.php:680 +msgid "Check this if you want to apply the 6G Blacklist firewall protection from perishablepress.com to your site." +msgstr "Marque esta opção se você deseja aplicar a proteção de firewall de lista negra 6G de perishablepress.com para o seu site." + +#: admin/wp-security-firewall-menu.php:684 +msgid "This setting will implement the 6G security firewall protection mechanisms on your site which include the following things:" +msgstr "Esta configuração irá implementar os mecanismos de proteção de firewall de segurança 6G em seu site que incluem as seguintes coisas:" + +#: admin/wp-security-firewall-menu.php:685 +#: admin/wp-security-firewall-menu.php:703 +msgid "1) Block forbidden characters commonly used in exploitative attacks." +msgstr "1) Caracteres em bloco proibido comumente usado em ataques de exploração." + +#: admin/wp-security-firewall-menu.php:686 +#: admin/wp-security-firewall-menu.php:704 +msgid "2) Block malicious encoded URL characters such as the \".css(\" string." +msgstr "2) Bloquear caracteres codificados de URL maliciosos, tais como o \".css(\" sequências." + +#: admin/wp-security-firewall-menu.php:687 +#: admin/wp-security-firewall-menu.php:705 +msgid "3) Guard against the common patterns and specific exploits in the root portion of targeted URLs." +msgstr "3) Proteja-se contra os padrões comuns e exploração específicas na parte de raiz de URLs de destino." + +#: admin/wp-security-firewall-menu.php:688 +#: admin/wp-security-firewall-menu.php:706 +msgid "4) Stop attackers from manipulating query strings by disallowing illicit characters." +msgstr "4) Pare atacantes de manipular sequências de consulta por não permitir caracteres ilícitos." + +#: admin/wp-security-firewall-menu.php:689 +#: admin/wp-security-firewall-menu.php:707 +msgid "....and much more." +msgstr "....e muito mais." + +#: admin/wp-security-firewall-menu.php:695 +msgid "Enable legacy 5G firewall protection" +msgstr "Habilitar proteção de firewall 5G legado" + +#: admin/wp-security-firewall-menu.php:698 +msgid "Check this if you want to apply the 5G Blacklist firewall protection from perishablepress.com to your site." +msgstr "Marque esta opção se você deseja aplicar a proteção de firewall de lista negra 5G de perishablepress.com para o seu site." + +#: admin/wp-security-firewall-menu.php:702 +msgid "This setting will implement the 5G security firewall protection mechanisms on your site which include the following things:" +msgstr "Esta configuração irá implementar os mecanismos de proteção de firewall de segurança 5G em seu site que incluem as seguintes coisas:" + +#: admin/wp-security-firewall-menu.php:713 +msgid "Save 5G/6G firewall settings" +msgstr "Salvar configurações de firewall 5G/6G" + +#: admin/wp-security-firewall-menu.php:721 +msgid "6G block request methods" +msgstr "" + +#: admin/wp-security-firewall-menu.php:725 +msgid "HTTP Request methods are used by browsers and clients to communicate with servers to get responses." +msgstr "" + +#: admin/wp-security-firewall-menu.php:726 +msgid "GET and POST are the most commonly used methods to request and submit data for specified resources of the server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:732 +msgid "Block %s method" +msgstr "" + +#: admin/wp-security-firewall-menu.php:735 +msgid "Check this to block the %s request method" +msgstr "" + +#: admin/wp-security-firewall-menu.php:740 +msgid "Some WooCommerce extensions use the PUT request method in addition to GET and POST." +msgstr "" + +#: admin/wp-security-firewall-menu.php:740 +msgid "This means WooCommerce users shouldn't block the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:741 +msgid "A few REST requests use the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:741 +msgid "If your site is communicated by the WP REST API, you should not block the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:749 +msgid "Save request methods settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:757 +msgid "6G other settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:761 +msgid "Block query strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:764 +msgid "Check this to block all query strings recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:768 +msgid "Block request strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:771 +msgid "Check this to block all request strings recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:775 +msgid "Block referrers" +msgstr "" + +#: admin/wp-security-firewall-menu.php:778 +msgid "Check this to block all referrers recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:782 +msgid "Block user-agents" +msgstr "" + +#: admin/wp-security-firewall-menu.php:785 +msgid "Check this to block all user-agents recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:789 +msgid "Save other settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:823 +msgid "The Internet bot settings were successfully saved" +msgstr "As configurações de robôs da internet foram salvas com sucesso" + +#: admin/wp-security-firewall-menu.php:827 +msgid "Internet bot settings" +msgstr "Configurações de robôs da internet" + +#: admin/wp-security-firewall-menu.php:833 +msgid "What is an Internet Bot" +msgstr "" + +#: admin/wp-security-firewall-menu.php:834 +msgid "%s?" +msgstr "%s?" + +#: admin/wp-security-firewall-menu.php:836 +msgid "A bot is a piece of software which runs on the Internet and performs automatic tasks. For example when Google indexes your pages it uses automatic bots to achieve this task." +msgstr "Um robô é um pedaço de software que é executado na internet e executa tarefas automáticas. Por exemplo, quando o Google indexa suas páginas ele usa robôs automáticos para realizar esta tarefa." + +#: admin/wp-security-firewall-menu.php:837 +msgid "A lot of bots are legitimate and non-malicous but not all bots are good and often you will find some which try to impersonate legitimate bots such as \"Googlebot\" but in reality they have nohing to do with Google at all." +msgstr "Um monte de robôs são legítimos e não malicioso mas não todos os robôs são bons e muitas vezes você vai encontrar alguns que tentam representar legítimo robôs como \"Googlebot\" mas na realidade eles não têm nada a ver com o Google em tudo." + +#: admin/wp-security-firewall-menu.php:838 +msgid "Although most of the bots out there are relatively harmless sometimes website owners want to have more control over which bots they allow into their site." +msgstr "Embora a maioria dos robôs lá fora, são relativamente inofensivos, às vezes proprietários de site querem ter mais controle sobre quais robôs permitem em seu site." + +#: admin/wp-security-firewall-menu.php:839 +msgid "This feature allows you to block bots which are impersonating as a Googlebot but actually aren't. (In other words they are fake Google bots)" +msgstr "Esse recurso permite você bloquear robôs que estão representando como um Googlebot, mas na verdade não são. (Em outras palavras, eles são falsos robôs do Google)" + +#: admin/wp-security-firewall-menu.php:840 +msgid "Googlebots have a unique indentity which cannot easily be forged and this feature will indentify any fake Google bots and block them from reading your site's pages." +msgstr "Googlebots tem uma identidade exclusiva, que não pode ser facilmente forjado e esse recurso irá identificar quaisquer falsos robôs do Google e bloqueá-los de ler as páginas do seu site." + +#: admin/wp-security-firewall-menu.php:846 +msgid "Attention: Sometimes non-malicious Internet organizations might have bots which impersonate as a \"Googlebot\"." +msgstr "Atenção: Organizações da internet, por vezes, não maliciosos podem ter robôs que imitam como um \"Googlebot\"." + +#: admin/wp-security-firewall-menu.php:847 +msgid "Just be aware that if you activate this feature the plugin will block all bots which use the \"Googlebot\" string in their User Agent information but are NOT officially from Google (irrespective whether they are malicious or not)." +msgstr "Esteja ciente de que, se você ativar esse recurso o plugin irá bloquear todos os robôs que usar a sequência de \"Googlebot\" em suas informações de agente de usuário, mas não são oficialmente do Google (independentemente se eles são mal-intencionados ou não). " + +#: admin/wp-security-firewall-menu.php:848 +msgid "All other bots from other organizations such as \"Yahoo\", \"Bing\" etc will not be affected by this feature." +msgstr "Todos os outros robôs de outras organizações, tais como \"Yahoo\", \"Bing\" etc não serão afetados por esse recurso." + +#: admin/wp-security-firewall-menu.php:854 +#: admin/wp-security-firewall-menu.php:864 +#: classes/grade-system/wp-security-feature-item-manager.php:93 +msgid "Block fake Googlebots" +msgstr "Bloquear Googlebots falsos" + +#: admin/wp-security-firewall-menu.php:867 +msgid "Check this if you want to block all fake Googlebots." +msgstr "Marque esta opção se você deseja bloquear todos os Googlebots falsos." + +#: admin/wp-security-firewall-menu.php:871 +msgid "This feature will check if the User Agent information of a bot contains the string \"Googlebot\"." +msgstr "Esta característica irá verificar se as informações do agente de usuário de um robô contém a sequência de caracteres \"Googlebot\"." + +#: admin/wp-security-firewall-menu.php:872 +msgid "It will then perform a few tests to verify if the bot is legitimately from Google and if so it will allow the bot to proceed." +msgstr "Em seguida, ele irá executar alguns testes para verificar se o robô é legitimamente do Google e se assim permitirá que o robô prosseguir." + +#: admin/wp-security-firewall-menu.php:873 +msgid "If the bot fails the checks then the plugin will mark it as being a fake Googlebot and it will block it" +msgstr "Se o robô falha nas verificações em seguida, o plugin irá marcá-lo como sendo um Googlebot falso e ele vai bloqueá-lo" + +#: admin/wp-security-firewall-menu.php:880 +msgid "Save internet bot settings" +msgstr "Salvar configurações de robô da internet" + +#: admin/wp-security-firewall-menu.php:916 +#: admin/wp-security-firewall-menu.php:938 +#: classes/grade-system/wp-security-feature-item-manager.php:95 +msgid "Prevent image hotlinking" +msgstr "Evitar hotlinking de imagem" + +#: admin/wp-security-firewall-menu.php:919 +msgid "A Hotlink is where someone displays an image on their site which is actually located on your site by using a direct link to the source of the image on your server." +msgstr "Um hotlink é onde alguém exibe uma imagem em seu site que encontra em seu site usando um link direto para a fonte da imagem no seu servidor." + +#: admin/wp-security-firewall-menu.php:920 +msgid "Due to the fact that the image being displayed on the other person's site is coming from your server, this can cause leaking of bandwidth and resources for you because your server has to present this image for the people viewing it on someone elses's site." +msgstr "Devido ao fato de que a imagem seja exibida no site da outra pessoa está vindo do seu servidor, isso pode causar vazamento de largura de banda e recursos para você, porque o servidor tem de apresentar essa imagem para as pessoas vê-lo em algum local do site da elses." + +#: admin/wp-security-firewall-menu.php:921 +msgid "This feature will prevent people from directly hotlinking images from your site's pages by writing some directives in your .htaccess file." +msgstr "Este recurso irá impedir pessoas de diretamente de hotlinking de imagens de páginas de seu site, escrevendo algumas diretivas em seu arquivo .htaccess." + +#: admin/wp-security-firewall-menu.php:926 +msgid "Prevent hotlinking" +msgstr "Evitar hotlinking" + +#: admin/wp-security-firewall-menu.php:941 +msgid "Check this if you want to prevent hotlinking to images on your site." +msgstr "Marque esta opção se você deseja evitar hotlinking de imagens no seu site." + +#: admin/wp-security-firewall-menu.php:961 +msgid "Nonce check failed for delete all 404 event logs operation!" +msgstr "Verificação núncio falhou para operação de exclusão de todos os registros de eventos 404!" + +#: admin/wp-security-firewall-menu.php:972 +msgid "404 Detection Feature - Delete all 404 event logs operation failed!" +msgstr "Recurso de detecção 404 - Excluir todos os registros de eventos 404 com falha na operação!" + +#: admin/wp-security-firewall-menu.php:976 +msgid "All 404 event logs were deleted from the DB successfully!" +msgstr "Todos os registros de eventos 404 foram excluídos do banco de dados com sucesso!" + +#: admin/wp-security-firewall-menu.php:1000 +msgid "You entered a non numeric value for the lockout time length field. It has been set to the default value." +msgstr "Você digitou um valor não numérico para o campo de comprimento tempo de bloqueio. Foi definido como o valor padrão." + +#: admin/wp-security-firewall-menu.php:1006 +msgid "You entered an incorrect format for the \"Redirect URL\" field. It has been set to the default value." +msgstr "Você digitou um formato incorreto para o campo \"Redirecionamento de URL\". Foi definido como o valor padrão." + +#: admin/wp-security-firewall-menu.php:1039 +msgid "404 detection configuration" +msgstr "Configuração de detecção 404" + +#: admin/wp-security-firewall-menu.php:1042 +msgid "A 404 or Not Found error occurs when somebody tries to access a non-existent page on your website." +msgstr "Um 404 ou nenhum erro encontrado ocorre quando alguém tenta acessar uma página inexistente em seu site." + +#: admin/wp-security-firewall-menu.php:1043 +msgid "Typically, most 404 errors happen quite innocently when people have mis-typed a URL or used an old link to page which doesn't exist anymore." +msgstr "Normalmente, a maioria dos erros 404 acontecer muito inocentemente quando as pessoas têm mal digitado uma URL ou usado um link antigo para a página que não existe mais." + +#: admin/wp-security-firewall-menu.php:1044 +msgid "However, in some cases you may find many repeated 404 errors which occur in a relatively short space of time and from the same IP address which are all attempting to access a variety of non-existent page URLs." +msgstr "No entanto, em alguns casos, você pode encontrar muitos repetidos erros 404 que ocorrem em um espaço relativamente curto de tempo e com o mesmo endereço IP que estão todos tentando acessar uma variedade de URLs de páginas inexistentes." + +#: admin/wp-security-firewall-menu.php:1045 +msgid "Such behaviour can mean that a hacker might be trying to find a particular page or URL for sinister reasons." +msgstr "Tal comportamento pode significar que um hacker pode estar tentando encontrar uma determinada página ou URL por razões sinistras." + +#: admin/wp-security-firewall-menu.php:1046 +msgid "This feature allows you to monitor all 404 events which occur on your site, and it also gives you the option of blocking IP addresses for a configured length of time." +msgstr "Este recurso permite que você monitore todos os eventos 404 que ocorrem em seu site, e também lhe dá a opção de bloquear endereços IP configurado por um período de tempo." + +#: admin/wp-security-firewall-menu.php:1047 +msgid "If you want to temporarily block or blacklist an IP address, simply click the \"Temp Block\" or \"Blacklist IP\" link for the applicable IP entry in the \"404 Event Logs\" table below." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1071 +msgid "404 detection options" +msgstr "Opções de detecção 404" + +#: admin/wp-security-firewall-menu.php:1083 +msgid "Enable 404 IP detection and lockout" +msgstr "Habilita detecção 404 de IP e bloqueio" + +#: admin/wp-security-firewall-menu.php:1086 +msgid "Check this if you want to enable the lockout of selected IP addresses." +msgstr "Marque esta opção se você deseja ativar o bloqueio de endereços IP selecionados." + +#: admin/wp-security-firewall-menu.php:1091 +msgid "When you enable this checkbox, all 404 events on your site will be logged in the table below. You can monitor these events and select some IP addresses listed in the table below and block them for a specified amount of time. All IP addresses you select to be blocked from the \"404 Event Logs\" table section will be unable to access your site during the time specified." +msgstr "Quando você ativa esta opção, todos os eventos 404 em seu site serão registrados na tabela abaixo. Você pode monitorar esses eventos e selecionar alguns endereços IP listados na tabela abaixo e bloqueá-los para um determinado período de tempo. Todos os endereços IP que você selecionar a ser bloqueado a partir da secção da tabela \"registros de evento 404\" não será capaz de acessar seu site durante o tempo especificado." + +#: admin/wp-security-firewall-menu.php:1099 +msgid "Enable 404 event logging" +msgstr "Habilitar registro de eventos 404" + +#: admin/wp-security-firewall-menu.php:1102 +msgid "Check this if you want to enable the logging of 404 events" +msgstr "Marque esta opção se você deseja ativar o registro de eventos 404" + +#: admin/wp-security-firewall-menu.php:1107 +msgid "Time length of 404 lockout (minutes)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1109 +msgid "Set the length of time for which a blocked IP address will be prevented from visiting your site" +msgstr "Defina o período de tempo durante o qual um endereço IP bloqueado será impedido de visitar o seu site" + +#: admin/wp-security-firewall-menu.php:1114 +msgid "You can lock any IP address which is recorded in the \"404 Event Logs\" table section below." +msgstr "Você pode bloquear qualquer endereço IP que está registrado na seção de tabela \"registros de evento 404\" abaixo." + +#: admin/wp-security-firewall-menu.php:1116 +msgid "To temporarily lock an IP address, hover over the ID column and click the \"Temp Block\" link for the applicable IP entry." +msgstr "Para bloquear temporariamente um endereço IP, passe o mouse sobre a coluna ID e clique no link \"Temp Block\" para a entrada IP aplicável." + +#: admin/wp-security-firewall-menu.php:1123 +msgid "404 lockout redirect URL" +msgstr "Redirecionamento de URL 404 bloqueada" + +#: admin/wp-security-firewall-menu.php:1125 +msgid "A blocked visitor will be automatically redirected to this URL." +msgstr "Um visitante bloqueado será automaticamente redirecionado para esta URL." + +#: admin/wp-security-firewall-menu.php:1135 +msgid "This list displays the 404 event logs when somebody tries to access a non-existent page on your website." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1136 +msgid "404 event logs that are older than %1$d days are purged automatically." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1141 +msgid "404 event logs" +msgstr "Registros de eventos 404" + +#: admin/wp-security-firewall-menu.php:1163 +#: admin/wp-security-firewall-menu.php:1172 +#: admin/wp-security-user-login-menu.php:495 +#: admin/wp-security-user-login-menu.php:504 +#: admin/wp-security-user-login-menu.php:653 +#: admin/wp-security-user-login-menu.php:662 +msgid "Export to CSV" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1169 +#: admin/wp-security-user-login-menu.php:501 +#: admin/wp-security-user-login-menu.php:659 +msgid "Click this button if you wish to download this log in CSV format." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1176 +#: admin/wp-security-firewall-menu.php:1185 +msgid "Delete all 404 event logs" +msgstr "Excluir todos os registros de eventos 404" + +#: admin/wp-security-firewall-menu.php:1182 +msgid "Click this button if you wish to purge all 404 event logs from the DB." +msgstr "Clique nesse botão se você deseja limpar todos os registros de eventos 404 do banco de dados." + +#: admin/wp-security-firewall-menu.php:1241 +msgid "Custom .htaccess rules settings" +msgstr "Configurações de regras .htaccess personalizadas" + +#: admin/wp-security-firewall-menu.php:1248 +msgid "This feature can be used to apply your own custom .htaccess rules and directives." +msgstr "Esse recurso pode ser usado para aplicar suas próprias regras .htaccess e diretivas personalizadas." + +#: admin/wp-security-firewall-menu.php:1249 +msgid "It is useful for when you want to tweak our existing firewall rules or when you want to add your own." +msgstr "É útil para quando você quer ajustar as nossas regras de firewall existentes ou quando você deseja adicionar o seu próprio." + +#: admin/wp-security-firewall-menu.php:1250 +msgid "NOTE: This feature can only be used if your site is hosted in an apache or similar web server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1256 +msgid "Warning: Only use this feature if you know what you are doing." +msgstr "Aviso: Só use esse recurso se você sabe o que está fazendo." + +#: admin/wp-security-firewall-menu.php:1257 +msgid "Incorrect .htaccess rules or directives can break or prevent access to your site." +msgstr "Regras .htaccess ou diretivas incorretas podem quebrar ou impedir o acesso ao seu site." + +#: admin/wp-security-firewall-menu.php:1258 +msgid "It is your responsibility to ensure that you are entering the correct code!" +msgstr "É de sua responsabilidade para garantir que você está digitando o código correto!" + +#: admin/wp-security-firewall-menu.php:1259 +msgid "If you break your site you will need to access your server via FTP or something similar and then edit your .htaccess file and delete the changes you made." +msgstr "Se você quebrar seu site, você precisará acessar o servidor via FTP ou algo similar e, em seguida, editar o seu arquivo .htaccess e excluir as alterações feitas." + +#: admin/wp-security-firewall-menu.php:1265 +msgid "Custom .htaccess rules" +msgstr "Regras .htaccess personalizadas" + +#: admin/wp-security-firewall-menu.php:1269 +msgid "Enable custom .htaccess rules" +msgstr "Habilitar regras .htaccess personalizadas" + +#: admin/wp-security-firewall-menu.php:1272 +msgid "Check this if you want to enable custom rules entered in the text box below" +msgstr "Marque esta opção se você deseja ativar regras personalizadas inseridas na caixa de texto abaixo" + +#: admin/wp-security-firewall-menu.php:1276 +msgid "Place custom rules at the top" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1279 +msgid "Check this if you want to place your custom rules at the beginning of all the rules applied by this plugin" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1283 +msgid "Enter custom .htaccess rules:" +msgstr "Digite regras .htaccess personalizadas:" + +#: admin/wp-security-firewall-menu.php:1287 +msgid "Enter your custom .htaccess rules/directives." +msgstr "Digite suas regras/diretivas .htaccess personalizadas" + +#: admin/wp-security-firewall-menu.php:1292 +msgid "Save custom rules" +msgstr "Salvar regras personalizadas" + +#: admin/wp-security-firewall-setup-notice.php:338 +#: admin/wp-security-firewall-setup-notice.php:407 +#: admin/wp-security-firewall-setup-notice.php:479 +#: admin/wp-security-firewall-setup-notice.php:595 +#: wp-security.php:43 +msgid "All In One WP Security and Firewall" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:340 +msgid "We were unable to create the file necessary to give you the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:341 +msgid "Your firewall will have reduced protection which means some of your firewall's functionality will be unavailable." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:342 +msgid "If you would like to manually set up the necessary file, please follow these steps:" +msgstr "" + +#. translators: %s Boostrap file name. +#. translators: %s Firewall file name. +#: admin/wp-security-firewall-setup-notice.php:346 +#: admin/wp-security-firewall-setup-notice.php:453 +msgid "1. Create a file with the name %s in the same directory as your WordPress install is in, i.e.:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:350 +msgid "2. Paste in the following code:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:352 +#: admin/wp-security-firewall-setup-notice.php:462 +msgid "3. Save the file and press the 'Try again' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:372 +msgid "1. Open the following file:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:378 +msgid "2. Look for the auto_prepend_file directive." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:382 +msgid "2. Look for the following:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:388 +msgid "3. Change it to the following:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:392 +msgid "4. Save the file and press the 'Try again' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:392 +#: admin/wp-security-firewall-setup-notice.php:441 +msgid "You may have to wait up to 5 minutes before the settings take effect." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:410 +msgid "Your firewall has been installed with the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:411 +msgid "You may have to wait 5 minutes for the changes to take effect." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:434 +msgid "1. Open your php.ini file." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:437 +msgid "2. Set the auto_prepend_file directive like below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:441 +msgid "3. Restart the webserver and refresh the page" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:458 +msgid "2. Paste in the following directives:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:482 +msgid "We were unable to set up your firewall with the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:483 +msgid "Your firewall will have reduced functionality." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:487 +msgid "To give your site the highest level of protection, please follow these steps:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:500 +msgid "Note: if you're unable to perform any of the aforementioned steps, please ask your web hosting provider for further assistance." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:517 +msgid "Try again" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:539 +msgid "We have detected that your AIOS firewall is not fully installed, and therefore does not have the highest level of protection. " +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:540 +msgid "Your firewall will have reduced functionality until it has been upgraded. " +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:542 +msgid "Upgrade your protection now" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:598 +msgid "Our PHP-based firewall has been created to give you even greater protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:602 +msgid "If you already have our .htaccess-based firewall enabled, you will still need to set up the PHP-based firewall to benefit from its protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:605 +msgid "To set up the PHP-based firewall, press the 'Set up now' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:608 +msgid "Set up now" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:614 +#: templates/notices/custom-notice.php:10 +#: templates/notices/custom-notice.php:12 +#: templates/notices/horizontal-notice.php:50 +#: templates/notices/horizontal-notice.php:52 +#: templates/notices/htaccess-to-php-feature-notice.php:10 +#: templates/notices/htaccess-to-php-feature-notice.php:12 +msgid "Dismiss" +msgstr "" + +#: admin/wp-security-list-404.php:91 +msgid "Event type" +msgstr "" + +#: admin/wp-security-list-404.php:92 +#: admin/wp-security-list-logged-in-users.php:46 +#: admin/wp-security-list-registered-users.php:74 +msgid "IP address" +msgstr "" + +#: admin/wp-security-list-404.php:93 +msgid "Attempted URL" +msgstr "" + +#: admin/wp-security-list-404.php:94 +msgid "Referer" +msgstr "" + +#: admin/wp-security-list-404.php:96 +msgid "Lock status" +msgstr "" + +#: admin/wp-security-list-404.php:118 +msgid "Temp block IP" +msgstr "" + +#: admin/wp-security-list-404.php:119 +msgid "Blacklist IP" +msgstr "" + +#: admin/wp-security-list-404.php:120 +#: admin/wp-security-list-acct-activity.php:82 +#: admin/wp-security-list-locked-ip.php:37 +#: admin/wp-security-list-locked-ip.php:84 +#: admin/wp-security-list-login-fails.php:73 +#: admin/wp-security-list-registered-users.php:93 +msgid "Delete" +msgstr "" + +#: admin/wp-security-list-404.php:128 +#: admin/wp-security-list-404.php:136 +#: admin/wp-security-list-404.php:143 +#: admin/wp-security-list-acct-activity.php:92 +#: admin/wp-security-list-comment-spammer-ip.php:95 +#: admin/wp-security-list-locked-ip.php:97 +#: admin/wp-security-list-locked-ip.php:105 +#: admin/wp-security-list-login-fails.php:85 +#: admin/wp-security-list-permanent-blocked-ip.php:96 +#: admin/wp-security-list-registered-users.php:107 +#: admin/wp-security-list-registered-users.php:115 +#: admin/wp-security-list-registered-users.php:123 +msgid "Please select some records using the checkboxes" +msgstr "Por favor, selecione alguns registros usando as caixas de seleção" + +#: admin/wp-security-list-404.php:278 +msgid "Nonce check failed for delete selected 404 event logs operation!" +msgstr "Verificação núncio falhou para operação de exclusão dos registros de eventos 404 selecionados!" + +#: admin/wp-security-list-acct-activity.php:35 +msgid "Are you sure you want to delete this item?" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:46 +msgid "Login session still active" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:60 +#: admin/wp-security-list-locked-ip.php:60 +#: admin/wp-security-list-logged-in-users.php:44 +#: admin/wp-security-list-login-fails.php:54 +#: admin/wp-security-list-registered-users.php:69 +msgid "User ID" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:61 +#: admin/wp-security-list-locked-ip.php:61 +#: admin/wp-security-list-login-fails.php:55 +msgid "Username" +msgstr "Nome de usuário" + +#: admin/wp-security-list-acct-activity.php:62 +msgid "Login date" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:63 +msgid "Logout date" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:136 +msgid "Nonce check failed for delete selected account activity logs operation!" +msgstr "Verificação núncio falhou para operação de exclusão dos registros de atividade das contas selecionadas!" + +#: admin/wp-security-list-comment-spammer-ip.php:59 +msgid "Spammer IP" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:60 +msgid "Number of spam comments from this IP" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:61 +msgid "Status" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:81 +msgid "Block" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:130 +#: admin/wp-security-list-comment-spammer-ip.php:179 +msgid "Nonce check failed for delete selected blocked IP operation!" +msgstr "Verificação núncio falhou para operação de exclusão de IP bloqueado selecionado!" + +#: admin/wp-security-list-comment-spammer-ip.php:137 +msgid "The selected IP addresses are now permanently blocked!" +msgstr "Os endereços IP selecionados agora estão permanentemente bloqueados!" + +#: admin/wp-security-list-comment-spammer-ip.php:193 +msgid "The selected IP addresses were saved in the blacklist configuration settings." +msgstr "Os endereços IP selecionados foram salvas nas definições de configuração de lista negra." + +#: admin/wp-security-list-comment-spammer-ip.php:201 +msgid "The .htaccess file was successfully modified to include the selected IP addresses." +msgstr "O arquivo .htaccess foi modificado com sucesso para incluir os endereços IP selecionados." + +#: admin/wp-security-list-comment-spammer-ip.php:212 +msgid "NOTE: The .htaccess file was not modified because you have disabled the \"Enable IP or User Agent Blacklisting\" check box." +msgstr "NOTA: O arquivo .htaccess não foi modificado porque você desativou a caixa de seleção \"Ativar IP ou lista negra de agente de usuário\"." + +#: admin/wp-security-list-comment-spammer-ip.php:213 +msgid "To block these IP addresses you will need to enable the above flag in the %s menu" +msgstr "Para bloquear esses endereços IP você precisará habilitar o sinalizador acima no menu %s" + +#: admin/wp-security-list-debug.php:47 +msgid "Level" +msgstr "" + +#: admin/wp-security-list-debug.php:48 +msgid "Message" +msgstr "" + +#: admin/wp-security-list-debug.php:49 +msgid "Type" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:36 +#: admin/wp-security-list-locked-ip.php:83 +msgid "Unlock" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:59 +msgid "Locked IP/range" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:62 +#: admin/wp-security-list-permanent-blocked-ip.php:67 +msgid "Reason" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:63 +msgid "Date locked" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:64 +msgid "Release date" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:134 +msgid "The selected IP entries were unlocked successfully." +msgstr "As entradas selecionadas do IP foram desbloqueadas com sucesso." + +#: admin/wp-security-list-locked-ip.php:140 +msgid "Nonce check failed for unlock IP operation!" +msgstr "Verificação núncio falhou para operação de desbloqueio de IP!" + +#: admin/wp-security-list-locked-ip.php:147 +msgid "The selected IP entry was unlocked successfully." +msgstr "A entrada IP selecionado foi desbloqueado com sucesso!" + +#: admin/wp-security-list-logged-in-users.php:45 +#: admin/wp-security-list-registered-users.php:70 +msgid "Login name" +msgstr "" + +#: admin/wp-security-list-logged-in-users.php:87 +msgid "Nonce check failed for force user logout operation!" +msgstr "Verificação núncio falhou para operação de saída do usuário à força!" + +#: admin/wp-security-list-logged-in-users.php:96 +msgid "The selected user was logged out successfully!" +msgstr "O usuário selecionado foi desconectado com sucesso!" + +#: admin/wp-security-list-login-fails.php:53 +msgid "Login IP range" +msgstr "" + +#: admin/wp-security-list-login-fails.php:130 +msgid "Nonce check failed for delete failed login record operation!" +msgstr "Verificação núncio falhou para operação de exclusão de registro de login com falha!" + +#: admin/wp-security-list-permanent-blocked-ip.php:66 +msgid "Blocked IP" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:87 +msgid "Unblock" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:122 +#: admin/wp-security-list-permanent-blocked-ip.php:139 +msgid "Successfully unblocked and deleted the selected record(s)." +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:126 +#: admin/wp-security-list-permanent-blocked-ip.php:143 +msgid "Failed to unblock and delete the selected record(s)." +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:133 +msgid "Nonce check failed for unblock IP operation!" +msgstr "Verificação núncio falhou para operação de desbloqueio de IP!" + +#: admin/wp-security-list-registered-users.php:71 +msgid "Email" +msgstr "" + +#: admin/wp-security-list-registered-users.php:72 +msgid "Register date" +msgstr "" + +#: admin/wp-security-list-registered-users.php:73 +msgid "Account status" +msgstr "" + +#: admin/wp-security-list-registered-users.php:92 +msgid "Approve" +msgstr "" + +#: admin/wp-security-list-registered-users.php:94 +msgid "Block IP" +msgstr "" + +#: admin/wp-security-list-registered-users.php:159 +msgid "The selected accounts were approved successfully!" +msgstr "As contas selecionadas foram aprovados com sucesso!" + +#: admin/wp-security-list-registered-users.php:163 +msgid "The following accounts failed to update successfully: " +msgstr "As seguintes contas falharam ao atualizar com sucesso: " + +#: admin/wp-security-list-registered-users.php:171 +msgid "The selected account was approved successfully!" +msgstr "A conta selecionada foi aprovada com sucesso!" + +#: admin/wp-security-list-registered-users.php:190 +msgid "Your account is now active" +msgstr "Sua conta já está ativa" + +#: admin/wp-security-list-registered-users.php:191 +msgid "Your account with username: " +msgstr "Sua conta com nome de usuário: " + +#: admin/wp-security-list-registered-users.php:191 +msgid " is now active" +msgstr " agora está ativa" + +#: admin/wp-security-list-registered-users.php:222 +msgid "The selected accounts were deleted successfully!" +msgstr "As contas selecionadas foram excluídas com sucesso!" + +#: admin/wp-security-list-registered-users.php:230 +msgid "Nonce check failed for delete registered user account operation!" +msgstr "Verificação núncio falhou para operação de exclusão de conta de usuário registrado!" + +#: admin/wp-security-list-registered-users.php:238 +msgid "The selected account was deleted successfully!" +msgstr "A conta selecionada foi excluída com sucesso!" + +#: admin/wp-security-list-registered-users.php:264 +msgid "The selected IP addresses were successfully added to the permanent block list!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:265 +#: admin/wp-security-list-registered-users.php:282 +msgid "View Blocked IPs" +msgstr "Ver IPs bloqueados" + +#: admin/wp-security-list-registered-users.php:274 +msgid "Nonce check failed for block IP operation of registered user!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:281 +msgid "The selected IP was successfully added to the permanent block list!" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:25 +msgid "Visitor lockout" +msgstr "Bloqueio de visitantes" + +#: admin/wp-security-maintenance-menu.php:85 +msgid "Site lockout feature settings saved!" +msgstr "Configurações de recurso de bloqueio de site salvas!" + +#: admin/wp-security-maintenance-menu.php:92 +msgid "General visitor lockout" +msgstr "Bloqueio de visitante geral" + +#: admin/wp-security-maintenance-menu.php:98 +msgid "This feature allows you to put your site into \"maintenance mode\" by locking down the front-end to all visitors except logged in users with super admin privileges." +msgstr "Esse recurso permite à você colocar seu site no \"modo de manutenção\" por bloquear o front-end para todos os visitantes, exceto usuários logados com privilégios de super administrador." + +#: admin/wp-security-maintenance-menu.php:99 +msgid "Locking your site down to general visitors can be useful if you are investigating some issues on your site or perhaps you might be doing some maintenance and wish to keep out all traffic for security reasons." +msgstr "Bloquear o seu site no ar para os visitantes em geral pode ser útil se você está investigando alguns problemas em seu site ou talvez você poderia estar fazendo alguma manutenção e deseja manter fora todo o tráfego por razões de segurança." + +#: admin/wp-security-maintenance-menu.php:104 +msgid "Enable front-end lockout" +msgstr "Habilitar bloqueio de front-end" + +#: admin/wp-security-maintenance-menu.php:107 +msgid "Check this if you want all visitors except those who are logged in as administrator to be locked out of the front-end of your site." +msgstr "Marque esta opção se você deseja que todos os visitantes, exceto aqueles que estão logado como administrador para ser bloqueado para fora do front-end do seu site." + +#: admin/wp-security-maintenance-menu.php:111 +msgid "Enter a message:" +msgstr "Digite uma mensagem:" + +#: admin/wp-security-maintenance-menu.php:123 +msgid "Enter a message you wish to display to visitors when your site is in maintenance mode." +msgstr "Digite uma mensagem que você deseja exibir aos visitantes, quando seu site estiver em modo de manutenção." + +#: admin/wp-security-maintenance-menu.php:130 +msgid "Save site lockout settings" +msgstr "Salvar configurações de bloqueio do site" + +#: admin/wp-security-misc-options-menu.php:28 +msgid "Copy protection" +msgstr "Proteção de cópia" + +#: admin/wp-security-misc-options-menu.php:29 +msgid "Frames" +msgstr "Quadros" + +#: admin/wp-security-misc-options-menu.php:30 +msgid "Users enumeration" +msgstr "Enumeração de usuários" + +#: admin/wp-security-misc-options-menu.php:31 +msgid "WP REST API" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:89 +msgid "Copy Protection feature settings saved!" +msgstr "Configurações de recurso de proteção contra cópia salvas!" + +#: admin/wp-security-misc-options-menu.php:94 +msgid "Disable the ability to copy text" +msgstr "Desabilitar a capacidade de copiar o texto" + +#: admin/wp-security-misc-options-menu.php:100 +msgid "This feature allows you to disable the ability to select and copy text from your front end." +msgstr "Esse recurso permite que você desative a capacidade de selecionar e copiar texto do seu front-end." + +#: admin/wp-security-misc-options-menu.php:101 +msgid "When admin user is logged in, the feature is automatically disabled for his session." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:106 +msgid "Enable copy protection" +msgstr "Habilitar proteção de cópia" + +#: admin/wp-security-misc-options-menu.php:109 +msgid "Check this if you want to disable the \"Right click\", \"Text selection\" and \"Copy\" option on the front end of your site." +msgstr "Marque esta opção se você deseja desativar o \"Clique Direito\", \"Seleção de Texto\" e a opção \"Copiar\" no front-end do seu site." + +#: admin/wp-security-misc-options-menu.php:116 +msgid "Save copy protection settings" +msgstr "Salvar configurações de proteção de cópia" + +#: admin/wp-security-misc-options-menu.php:140 +msgid "Frame Display Prevention feature settings saved!" +msgstr "Configurações de recursos de prevenção de exposição de quadro salvas!" + +#: admin/wp-security-misc-options-menu.php:145 +msgid "Prevent your site from being displayed in a frame" +msgstr "Impedir que o seu site seja exibido em um quadro" + +#: admin/wp-security-misc-options-menu.php:151 +msgid "This feature allows you to prevent other sites from displaying any of your content via a frame or iframe." +msgstr "Esse recurso permite que você impeça que outros sites de exibir qualquer um dos seus conteúdos através de um frame ou iframe." + +#: admin/wp-security-misc-options-menu.php:152 +msgid "When enabled, this feature will set the \"X-Frame-Options\" paramater to \"sameorigin\" in the HTTP header." +msgstr "Quando habilitado, esse recurso irá definir o parâmetro inválido \"X-Frame-Options\" para \"sameorigin\" no cabeçalho HTTP." + +#: admin/wp-security-misc-options-menu.php:157 +msgid "Enable iFrame protection" +msgstr "Habilitar proteção iFrame" + +#: admin/wp-security-misc-options-menu.php:160 +msgid "Check this if you want to stop other sites from displaying your content in a frame or iframe." +msgstr "Marque esta opção se você deseja impedir que outros sites exiba seu conteúdo em um frame ou iframe." + +#: admin/wp-security-misc-options-menu.php:191 +msgid "Users Enumeration Prevention feature settings saved!" +msgstr "Configurações de recurso de prevenção de enumeração de usuários salvas!" + +#: admin/wp-security-misc-options-menu.php:196 +msgid "Prevent users enumeration" +msgstr "Evitar enumeração de usuários" + +#: admin/wp-security-misc-options-menu.php:202 +msgid "This feature allows you to prevent external users/bots from fetching the user info with urls like \"/?author=1\"." +msgstr "Esse recurso permite-lhe evitar externas de usuários/robôs de buscar a informação do usuário com urls como \"/?author=1\"." + +#: admin/wp-security-misc-options-menu.php:203 +msgid "When enabled, this feature will print a \"forbidden\" error rather than the user information." +msgstr "Quando habilitado, esse recurso irá imprimir um erro \"proibido\", em vez das informações do usuário." + +#: admin/wp-security-misc-options-menu.php:208 +msgid "Disable users enumeration" +msgstr "Desabilitar enumeração de usuários" + +#: admin/wp-security-misc-options-menu.php:211 +msgid "Check this if you want to stop users enumeration." +msgstr "Marque esta opção se você deseja parar com a enumeração de usuários." + +#: admin/wp-security-misc-options-menu.php:242 +msgid "WP REST API Security feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:253 +msgid "This feature allows you to block WordPress REST API access for unauthorized requests." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:254 +msgid "When enabled this feature will only allow REST requests to be processed if the user is logged in." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:260 +msgid "Beware that if you are using other plugins which have registered REST endpoints (eg, Contact Form 7), then this feature will also block REST requests used by these plugins if the user is not logged in. It is recommended that you leave this feature disabled if you want uninterrupted functionality for such plugins." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:268 +msgid "Disallow unauthorized REST requests" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:271 +msgid "Check this if you want to stop REST API access for non-logged in requests." +msgstr "" + +#: admin/wp-security-settings-menu.php:25 +msgid "General settings" +msgstr "Configurações gerais" + +#: admin/wp-security-settings-menu.php:29 +#: admin/wp-security-settings-menu.php:33 +msgid "file" +msgstr "Arquivo" + +#: admin/wp-security-settings-menu.php:37 +msgid "Delete plugin settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:41 +msgid "WP version info" +msgstr "" + +#: admin/wp-security-settings-menu.php:45 +msgid "Import/Export" +msgstr "Importar / Exportar" + +#: admin/wp-security-settings-menu.php:52 +msgid "Advanced settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:128 +msgid "All the security features have been disabled successfully!" +msgstr "Todos os recursos de segurança foram desativados com sucesso!" + +#: admin/wp-security-settings-menu.php:132 +#: admin/wp-security-settings-menu.php:159 +msgid "Could not write to the .htaccess file. Please restore your .htaccess file manually using the restore functionality in the \".htaccess File\"." +msgstr "Não foi possível gravar no arquivo .htaccess. Por favor, restaure o arquivo .htaccess manualmente usando a funcionalidade de restauração do \"arquivo .htaccess\"." + +#: admin/wp-security-settings-menu.php:137 +msgid "Could not write to the wp-config.php. Please restore your wp-config.php file manually using the restore functionality in the \"wp-config.php File\"." +msgstr "Não foi possível escrever para o wp-config.php. Por favor, restaure o arquivo wp-config.php manualmente usando a funcionalidade de restauração do \"arquivo wp-config.php\"." + +#: admin/wp-security-settings-menu.php:155 +msgid "All firewall rules have been disabled successfully!" +msgstr "Todas as regras de firewall foram desativadas com sucesso!" + +#: admin/wp-security-settings-menu.php:177 +msgid "Deletion of aio_wp_security_configs option and .htaccess directives failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:179 +msgid "Reset of aio_wp_security_configs option failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:181 +msgid "Deletion of .htaccess directives failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:183 +msgid "All settings have been successfully reset." +msgstr "" + +#: admin/wp-security-settings-menu.php:203 +msgid "For information, updates and documentation, please visit the" +msgstr "Para informações, atualizações e documentação, por favor visite o" + +#: admin/wp-security-settings-menu.php:203 +msgid "Page" +msgstr "Página" + +#: admin/wp-security-settings-menu.php:204 +msgid "Follow us" +msgstr "Siga-nos" + +#: admin/wp-security-settings-menu.php:204 +msgid "on Twitter, Google+ or via Email to stay up to date about the new security features of this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:208 +msgid "WP Security plugin" +msgstr "Plugin de segurança WP" + +#: admin/wp-security-settings-menu.php:212 +msgid "Thank you for using the AIOS security plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:216 +msgid "There are a lot of security features in this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:221 +msgid "To start, go through each security option and enable the \"basic\" options." +msgstr "" + +#: admin/wp-security-settings-menu.php:225 +msgid "The more features you enable, the more security points you will achieve." +msgstr "" + +#: admin/wp-security-settings-menu.php:228 +msgid "Before doing anything we advise taking a backup of your .htaccess file, database and wp-config.php." +msgstr "" + +#: admin/wp-security-settings-menu.php:231 +msgid "Backup your database" +msgstr "Fazer backup de seu banco de dados" + +#: admin/wp-security-settings-menu.php:232 +#: admin/wp-security-settings-menu.php:433 +msgid "Backup .htaccess file" +msgstr "Fazer backup do arquivo .htaccess" + +#: admin/wp-security-settings-menu.php:233 +#: admin/wp-security-settings-menu.php:534 +msgid "Backup wp-config.php file" +msgstr "Fazer backup do arquivo wp-config.php" + +#: admin/wp-security-settings-menu.php:240 +msgid "Disable security features" +msgstr "Desabilitar recursos de segurança" + +#: admin/wp-security-settings-menu.php:246 +msgid "If you think that some plugin functionality on your site is broken due to a security feature you enabled in this plugin, then use the following option to turn off all the security features of this plugin." +msgstr "Se você acha que algumas funcionalidades do plugin em seu site estão quebrado devido a um recurso de segurança que você habilitou neste plugin, então use a seguinte opção para desativar todos os recursos de segurança deste plugin." + +#: admin/wp-security-settings-menu.php:250 +msgid "Disable all security features" +msgstr "Desabilitar todos os recursos de segurança" + +#: admin/wp-security-settings-menu.php:257 +#: admin/wp-security-settings-menu.php:267 +msgid "Disable all firewall rules" +msgstr "Desabilitar todas as regras de firewall" + +#: admin/wp-security-settings-menu.php:263 +msgid "This feature will disable all firewall rules which are currently active in this plugin and it will also delete these rules from your .htacess file. Use it if you think one of the firewall rules is causing an issue on your site." +msgstr "Este recurso irá desabilitar todas as regras de firewall que estão atualmente ativas neste plugin e também irá excluir essas regras do seu arquivo .htacess. Usá-lo, se você acha que uma das regras de firewall está causando um problema no seu site." + +#: admin/wp-security-settings-menu.php:274 +#: admin/wp-security-settings-menu.php:287 +msgid "Reset settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:279 +msgid "This button click will delete all of your settings related to the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:280 +msgid "This button click will reset/empty all the database tables of the security plugin also." +msgstr "" + +#: admin/wp-security-settings-menu.php:281 +msgid "Use this plugin if you were locked out by the All In One WP Security & Firewall Plugin and/or you are having issues logging in when that plugin is activated." +msgstr "" + +#: admin/wp-security-settings-menu.php:282 +msgid "In addition to the settings it will also delete any directives which were added to the .htaccess file by the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:283 +msgid "%1$sNOTE: %2$sAfter deleting the settings you will need to re-configure the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:295 +msgid "Debug settings" +msgstr "Configurações de depuração" + +#: admin/wp-security-settings-menu.php:301 +msgid "This setting allows you to enable/disable debug for this plugin." +msgstr "Essa configuração permite você ativar / desativar depuração para este plugin." + +#: admin/wp-security-settings-menu.php:307 +msgid "Enable debug" +msgstr "Habilitar depuração" + +#: admin/wp-security-settings-menu.php:310 +msgid "Check this if you want to enable debug. You should keep this option disabled after you have finished debugging the issue." +msgstr "" + +#: admin/wp-security-settings-menu.php:314 +msgid "Save debug settings" +msgstr "Salvar configurações de depuração" + +#: admin/wp-security-settings-menu.php:350 +msgid "Your .htaccess file was successfully backed up! Using an FTP program go to the \"/wp-content/aiowps_backups\" directory to save a copy of the file to your computer." +msgstr "Seu backup do arquivo .htaccess foi feito com sucesso! Usando um programa de FTP vá para o diretório \"/wp-content/aiowps_backups\" para salvar uma cópia do arquivo em seu computador." + +#: admin/wp-security-settings-menu.php:356 +msgid "htaccess file rename failed during backup. Please check your root directory for the backup file using FTP." +msgstr "Renomeação do arquivo .htaccess falhou durante o backup. Por favor, verifique o diretório raiz do arquivo de backup usando FTP." + +#: admin/wp-security-settings-menu.php:362 +msgid "htaccess backup failed." +msgstr "Backup htaccess falhou." + +#: admin/wp-security-settings-menu.php:377 +msgid "Please choose a .htaccess to restore from." +msgstr "Por favor, escolha um .htaccess para restaurar." + +#: admin/wp-security-settings-menu.php:392 +msgid "htaccess file restore failed. Please attempt to restore the .htaccess manually using FTP." +msgstr "Restauração do arquivo .htaccess falhou. Por favor, tente restaurar o .htaccess manualmente usando FTP." + +#: admin/wp-security-settings-menu.php:396 +msgid "Your .htaccess file has successfully been restored!" +msgstr "Seu arquivo .htaccess foi restaurado com sucesso!" + +#: admin/wp-security-settings-menu.php:402 +msgid "htaccess Restore operation failed! Please check the contents of the file you are trying to restore from." +msgstr "Operação de restauração htaccess falhou! Por favor, verifique o conteúdo do arquivo que você está tentando restaurar." + +#: admin/wp-security-settings-menu.php:408 +msgid ".htaccess file operations" +msgstr "Operações do arquivo .htaccess" + +#: admin/wp-security-settings-menu.php:411 +msgid "Your \".htaccess\" file is a key component of your website's security and it can be modified to implement various levels of protection mechanisms." +msgstr "Seu arquivo \".htaccess\" é um componente essencial de segurança do seu site e pode ser modificado para implementar vários níveis de mecanismos de proteção." + +#: admin/wp-security-settings-menu.php:412 +msgid "This feature allows you to backup and save your currently active .htaccess file should you need to re-use the the backed up file in the future." +msgstr "Este recurso permite fazer backup e salvar o seu arquivo .htaccess atualmente ativo, caso haja necessidade de voltar a usar o arquivo de backup no futuro." + +#: admin/wp-security-settings-menu.php:413 +msgid "You can also restore your site's .htaccess settings using a backed up .htaccess file." +msgstr "Você também pode restaurar as configurações .htaccess do seu site usando um backup do arquivo .htaccess." + +#: admin/wp-security-settings-menu.php:428 +msgid "Save the current .htaccess file" +msgstr "Salvar o arquivo .htaccess atual" + +#: admin/wp-security-settings-menu.php:432 +msgid "Click the button below to backup and save the currently active .htaccess file." +msgstr "Clique no botão abaixo para fazer backup e salvar o arquivo .htaccess atualmente ativo." + +#: admin/wp-security-settings-menu.php:437 +msgid "Restore from a backed up .htaccess file" +msgstr "Restaurar backup de um arquivo .htaccess" + +#: admin/wp-security-settings-menu.php:443 +msgid ".htaccess file to restore from" +msgstr "Arquivo .htaccess para restaurar" + +#: admin/wp-security-settings-menu.php:445 +msgid "Select Your htaccess File" +msgstr "" + +#: admin/wp-security-settings-menu.php:449 +msgid "After selecting your file, click the button below to restore your site using the backed up htaccess file (htaccess_backup.txt)." +msgstr "Depois de selecionar o arquivo, clique no botão abaixo para restaurar seu site usando o backup do arquivo .htaccess (htaccess_backup.txt)." + +#: admin/wp-security-settings-menu.php:455 +msgid "Restore .htaccess file" +msgstr "Restaurar arquivo .htaccess" + +#: admin/wp-security-settings-menu.php:477 +msgid "Please choose a wp-config.php file to restore from." +msgstr "Por favor, escolha um arquivo wp-config.php para restaurar." + +#: admin/wp-security-settings-menu.php:493 +msgid "wp-config.php file restore failed. Please attempt to restore this file manually using FTP." +msgstr "Restauração do arquivo wp-config.php falhou. Por favor, tente restaurar este arquivo manualmente usando o FTP." + +#: admin/wp-security-settings-menu.php:497 +msgid "Your wp-config.php file has successfully been restored!" +msgstr "Seu arquivo wp-config.php foi restaurado com sucesso!" + +#: admin/wp-security-settings-menu.php:503 +msgid "wp-config.php Restore operation failed! Please check the contents of the file you are trying to restore from." +msgstr "Operação de restauração wp-config.php falhou! Por favor, verifique o conteúdo do arquivo que você está tentando restaurar." + +#: admin/wp-security-settings-menu.php:509 +msgid "wp-config.php file operations" +msgstr "Operações do arquivo wp-config.php" + +#: admin/wp-security-settings-menu.php:512 +msgid "Your \"wp-config.php\" file is one of the most important in your WordPress installation. It is a primary configuration file and contains crucial things such as details of your database and other critical components." +msgstr "Seu arquivo \"wp-config.php\" é um dos mais importantes em sua instalação do WordPress. É um arquivo de configuração principal e contém coisas cruciais, tais como detalhes de seu banco de dados e outros componentes críticos." + +#: admin/wp-security-settings-menu.php:513 +msgid "This feature allows you to backup and save your currently active wp-config.php file should you need to re-use the the backed up file in the future." +msgstr "Este recurso permite fazer backup e salvar o seu arquivo wp-config.php atualmente ativo, caso haja necessidade de voltar a usar o arquivo de backup no futuro." + +#: admin/wp-security-settings-menu.php:514 +msgid "You can also restore your site's wp-config.php settings using a backed up wp-config.php file." +msgstr "Você também pode restaurar as configurações wp-config.php do seu site usando um backup do arquivo wp-config.php." + +#: admin/wp-security-settings-menu.php:529 +msgid "Save the current wp-config.php file" +msgstr "Salvar o arquivo wp-config.php atual" + +#: admin/wp-security-settings-menu.php:533 +msgid "Click the button below to backup and download the contents of the currently active wp-config.php file." +msgstr "Clique no botão abaixo para fazer backup e transferir o conteúdo do arquivo wp-config.php atualmente ativo." + +#: admin/wp-security-settings-menu.php:539 +msgid "Restore from a backed up wp-config file" +msgstr "Restaurar backup de um arquivo wp-config" + +#: admin/wp-security-settings-menu.php:545 +msgid "wp-config file to restore from" +msgstr "Arquivo wp-config para restaurar" + +#: admin/wp-security-settings-menu.php:547 +msgid "Select Your wp-config File" +msgstr "" + +#: admin/wp-security-settings-menu.php:551 +msgid "After selecting your file click the button below to restore your site using the backed up wp-config file (wp-config.php.backup.txt)." +msgstr "Depois de selecionar o arquivo, clique no botão abaixo para restaurar seu site usando o backup do arquivo wp-config (wp-config.php.backup.txt)." + +#: admin/wp-security-settings-menu.php:557 +msgid "Restore wp-config file" +msgstr "Restaurar arquivo wp-config" + +#: admin/wp-security-settings-menu.php:591 +msgid "Manage delete plugin settings saved." +msgstr "" + +#: admin/wp-security-settings-menu.php:596 +msgid "Manage delete plugin tasks" +msgstr "" + +#: admin/wp-security-settings-menu.php:603 +msgid "Delete database tables" +msgstr "" + +#: admin/wp-security-settings-menu.php:606 +msgid "Check this if you want to remove database tables when the plugin is uninstalled." +msgstr "" + +#: admin/wp-security-settings-menu.php:610 +msgid "Delete settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:613 +msgid "Check this if you want to remove all plugin settings when uninstalling the plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:613 +msgid "It will also remove all custom htaccess rules that were added by this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:647 +msgid "WP generator meta tag and version info" +msgstr "" + +#: admin/wp-security-settings-menu.php:650 +msgid "WordPress generator automatically adds some meta information inside the \"head\" tags of every page on your site's front end. Below is an example of this:" +msgstr "Gerador WordPress adiciona automaticamente algumas informações de meta dentro das tags \"head\" de cada página em front-end do seu site. Abaixo está um exemplo disso:" + +#: admin/wp-security-settings-menu.php:652 +msgid "The above meta information shows which version of WordPress your site is currently running and thus can help hackers or crawlers scan your site to see if you have an older version of WordPress or one with a known exploit." +msgstr "As informações de meta acima mostram qual versão do WordPress, seu site está atualmente em execução e, portanto, pode ajudar hackers ou rastreadores analisar o seu site para ver se você tem uma versão antiga do WordPress ou um com uma exploração conhecida." + +#: admin/wp-security-settings-menu.php:653 +msgid "There are also other ways wordpress reveals version info such as during style and script loading. An example of this is:" +msgstr "" + +#: admin/wp-security-settings-menu.php:655 +msgid "This feature will allow you to remove the WP generator meta info and other version info from your site's pages." +msgstr "" + +#: admin/wp-security-settings-menu.php:661 +msgid "WP generator meta info" +msgstr "Gerador de informações de meta WP" + +#: admin/wp-security-settings-menu.php:673 +msgid "Remove WP generator meta info" +msgstr "Remover gerador de informações de meta WP" + +#: admin/wp-security-settings-menu.php:676 +msgid "Check this if you want to remove the version and meta info produced by WP from all pages" +msgstr "" + +#: admin/wp-security-settings-menu.php:704 +msgid "Please choose a file to import your settings from." +msgstr "Por favor, escolha um arquivo para importar suas definições." + +#: admin/wp-security-settings-menu.php:736 +msgid "Import AIOS settings from " +msgstr "" + +#: admin/wp-security-settings-menu.php:742 +#: admin/wp-security-settings-menu.php:786 +msgid "The deletion of the import file failed. Please delete this file manually via the media menu for security purposes." +msgstr "A exclusão do arquivo de importação falhou. Por favor, apague este arquivo manualmente através do menu de mídia para fins de segurança." + +#: admin/wp-security-settings-menu.php:744 +#: admin/wp-security-settings-menu.php:788 +msgid "The file you uploaded was also deleted for security purposes because it contains security settings details." +msgstr "O arquivo que você carregou também foi excluído para fins de segurança, pois ele contém detalhes de configurações de segurança." + +#: admin/wp-security-settings-menu.php:759 +msgid "Your AIOS settings were successfully imported via file input." +msgstr "" + +#: admin/wp-security-settings-menu.php:760 +msgid "The deletion of the import file failed. Please delete this file manually via the media menu for security purposes because it contains security settings details." +msgstr "A exclusão do arquivo de importação falhou. Por favor, apague este arquivo manualmente através do menu de mídia para fins de segurança, pois ele contém detalhes de configurações de segurança." + +#: admin/wp-security-settings-menu.php:762 +msgid "Your AIOS settings were successfully imported. The file you uploaded was also deleted for security purposes because it contains security settings details." +msgstr "" + +#: admin/wp-security-settings-menu.php:765 +msgid "Your AIOS settings were successfully imported via text entry." +msgstr "" + +#: admin/wp-security-settings-menu.php:780 +msgid "The contents of your settings file appear invalid. Please check the contents of the file you are trying to import settings from." +msgstr "O conteúdo do seu arquivo de configurações aparece inválido. Por favor, verifique o conteúdo do arquivo que você está tentando importar configurações de." + +#: admin/wp-security-settings-menu.php:797 +msgid "Export or import your AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:800 +msgid "This section allows you to export or import your All In One WP Security & Firewall settings." +msgstr "Esta seção permite-lhe exportar ou importar suas configurações de All In One WP Security e Firewall" + +#: admin/wp-security-settings-menu.php:801 +msgid "This can be handy if you wanted to save time by applying the settings from one site to another site." +msgstr "Isto pode ser útil se você quiser economizar tempo aplicando as configurações de um site para outro site." + +#: admin/wp-security-settings-menu.php:802 +msgid "NOTE: Before importing, it is your responsibility to know what settings you are trying to import. Importing settings blindly can cause you to be locked out of your site." +msgstr "Antes de importar, é sua responsabilidade saber quais configurações que você está tentando importar. Importando configurações cegamente pode causar-lhe ser trancado para fora de seu site." + +#: admin/wp-security-settings-menu.php:803 +msgid "For Example: If a settings item relies on the domain URL then it may not work correctly when imported into a site with a different domain." +msgstr "Por exemplo: se um item de configurações depende do domínio URL, então pode não funcionar corretamente quando importado para um site com um domínio diferente." + +#: admin/wp-security-settings-menu.php:809 +#: admin/wp-security-settings-menu.php:818 +msgid "Export AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:815 +msgid "To export your All In One WP Security & Firewall settings click the button below." +msgstr "Para exportar as configurações All In One WP Security e Firewall, clique no botão abaixo." + +#: admin/wp-security-settings-menu.php:822 +#: admin/wp-security-settings-menu.php:851 +msgid "Import AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:828 +msgid "Use this section to import your All In One WP Security & Firewall settings from a file. Alternatively, copy/paste the contents of your import file into the textarea below." +msgstr "Use esta seção para importar as configurações de All In One WP Security e Firewall de um arquivo. Alternativamente, copiar / colar o conteúdo do seu arquivo de importação para a área de texto abaixo." + +#: admin/wp-security-settings-menu.php:830 +msgid "Import file" +msgstr "Importar arquivo" + +#: admin/wp-security-settings-menu.php:833 +msgid "Select Your Import Settings File" +msgstr "" + +#: admin/wp-security-settings-menu.php:837 +msgid "After selecting your file, click the button below to apply the settings to your site." +msgstr "Depois de selecionar o arquivo, clique no botão abaixo para aplicar as configurações para o seu site." + +#: admin/wp-security-settings-menu.php:844 +msgid "Copy/Paste import data" +msgstr "Copiar/Colar dados de importação" + +#: admin/wp-security-settings-menu.php:893 +msgid "Default - if correct, then this is the best option" +msgstr "" + +#: admin/wp-security-settings-menu.php:894 +msgid "Only use if you're using Cloudflare." +msgstr "" + +#: admin/wp-security-settings-menu.php:902 +msgid "(current value: %s)" +msgstr "" + +#: admin/wp-security-settings-menu.php:905 +msgid "no value (i.e. empty) on your server" +msgstr "" + +#: admin/wp-security-spam-menu.php:28 +msgid "Comment spam" +msgstr "SPAM de comentário" + +#: admin/wp-security-spam-menu.php:29 +msgid "Comment spam IP monitoring" +msgstr "Monitoramento de IP SPAM de comentário" + +#: admin/wp-security-spam-menu.php:30 +msgid "BuddyPress" +msgstr "BuddyPress" + +#: admin/wp-security-spam-menu.php:31 +msgid "bbPress" +msgstr "" + +#: admin/wp-security-spam-menu.php:57 +msgid "Spam prevention" +msgstr "Prevenção SPAM" + +#: admin/wp-security-spam-menu.php:99 +msgid "You entered a non numeric value for the \"move spam comments to trash after number of days\" field." +msgstr "" + +#: admin/wp-security-spam-menu.php:99 +#: admin/wp-security-spam-menu.php:297 +#: admin/wp-security-user-login-menu.php:118 +#: admin/wp-security-user-login-menu.php:124 +#: admin/wp-security-user-login-menu.php:130 +#: admin/wp-security-user-login-menu.php:136 +msgid "It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:129 +msgid "Comment spam settings" +msgstr "Configurações de SPAM de comentário" + +#: admin/wp-security-spam-menu.php:134 +msgid "Add CAPTCHA to comments form" +msgstr "Adicionar captcha para formulário de comentários" + +#: admin/wp-security-spam-menu.php:138 +msgid "This feature will add a CAPTCHA field in the WordPress comments form." +msgstr "" + +#: admin/wp-security-spam-menu.php:139 +msgid "Adding a CAPTCHA field in the comment form is a simple way of greatly reducing spam comments from bots without using .htaccess rules." +msgstr "Adicionando um campo de captcha no formulário de comentário é uma maneira simples de reduzir grandemente SPAM de comentários de robôs sem usar regras .htaccess." + +#: admin/wp-security-spam-menu.php:148 +msgid "Enable CAPTCHA on comment forms" +msgstr "Habilitar captcha em formulários de comentário" + +#: admin/wp-security-spam-menu.php:151 +msgid "Check this if you want to insert a CAPTCHA field on the comment forms." +msgstr "Marque esta opção se você deseja inserir um campo captcha em formulários o comentário" + +#: admin/wp-security-spam-menu.php:158 +msgid "Block spambot comments" +msgstr "Bloquear comentários spambot" + +#: admin/wp-security-spam-menu.php:162 +msgid "A large portion of WordPress blog comment spam is mainly produced by automated bots and not necessarily by humans." +msgstr "" + +#: admin/wp-security-spam-menu.php:163 +msgid "This feature will greatly minimize the useless and unecessary traffic and load on your server resulting from spam comments by blocking all comment requests which do not originate from your domain." +msgstr "Este recurso irá minimizar consideravelmente o tráfego e carga inútil e desnecessário em seu servidor, resultante de comentários de spam, bloqueando todas as solicitações de comentário que não são originários do seu domínio." + +#: admin/wp-security-spam-menu.php:164 +msgid "In other words, if the comment was not submitted by a human who physically submitted the comment on your site, the request will be blocked." +msgstr "Em outras palavras, se o comentário não foi enviado por um ser humano que fisicamente apresentou o comentário em seu site, a solicitação será bloqueada." + +#: admin/wp-security-spam-menu.php:182 +msgid "Block spambots from posting comments" +msgstr "Bloquear spambots de publicar comentários" + +#: admin/wp-security-spam-menu.php:185 +msgid "Check this if you want to apply a firewall rule which will block comments originating from spambots." +msgstr "Marque esta opção se você deseja aplicar uma regra de firewall que irá bloquear comentários provenientes de spambots." + +#: admin/wp-security-spam-menu.php:189 +msgid "This feature will implement a firewall rule to block all comment attempts which do not originate from your domain." +msgstr "Este recurso irá implementar uma regra de firewall para bloquear todas as tentativas de comentário que não são originários do seu domínio." + +#: admin/wp-security-spam-menu.php:190 +msgid "A legitimate comment is one which is submitted by a human who physically fills out the comment form and clicks the submit button. For such events, the HTTP_REFERRER is always set to your own domain." +msgstr "Um comentário legítimo é aquele que é enviado por um ser humano que fisicamente preenche o formulário de comentário e clica no botão enviar. Para tais eventos, a HTTP_REFERRER é sempre definido para seu próprio domínio." + +#: admin/wp-security-spam-menu.php:191 +msgid "A comment submitted by a spambot is done by directly calling the comments.php file, which usually means that the HTTP_REFERRER value is not your domain and often times empty." +msgstr "Um comentário enviado por um spambot é feito chamando diretamente o arquivo comments.php, que geralmente significa que o valor HTTP_REFERRER não é o seu domínio e muitas vezes vazio." + +#: admin/wp-security-spam-menu.php:192 +msgid "This feature will check and block comment requests which are not referred by your domain thus greatly reducing your overall blog spam and PHP requests done by the server to process these comments." +msgstr "Esta função irá verificar e bloquear solicitações de comentário que não são referidos por seu domínio reduzindo assim significativamente as suas solicitações globais do blog de SPAM e PHP feito pelo servidor para processar esses comentários." + +#: admin/wp-security-spam-menu.php:202 +msgid "Comment processing" +msgstr "" + +#: admin/wp-security-spam-menu.php:207 +msgid "Trash spam comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:216 +msgid "Move spam comments to trash after %s days." +msgstr "" + +#: admin/wp-security-spam-menu.php:224 +msgid "Enble this feature in order to move the spam comments to trash after given number of days." +msgstr "" + +#: admin/wp-security-spam-menu.php:262 +msgid "You entered a non numeric value for the minimum number of spam comments field. It has been set to the default value." +msgstr "Você digitou um valor não numérico para o número mínimo de campo de comentários de spam. Foi definido como o valor padrão." + +#: admin/wp-security-spam-menu.php:265 +msgid "You must enter an integer greater than zero for minimum number of spam comments field. It has been set to the default value." +msgstr "Você deve digitar um número inteiro maior que zero para o número mínimo de campo de comentários de spam. Foi definido como o valor padrão." + +#: admin/wp-security-spam-menu.php:292 +msgid "Nonce check failed for list spam comment IPs." +msgstr "Verificação núncio falhou para a lista de SPAM de comentários IPs!" + +#: admin/wp-security-spam-menu.php:297 +msgid "You entered a non numeric value for the minimum spam comments per IP field." +msgstr "" + +#: admin/wp-security-spam-menu.php:308 +msgid "Displaying results for IP addresses which have posted a minimum of %s spam comments." +msgstr "Mostrar resultados para endereços IP, que postaram um mínimo de %s SPAM de comentários" + +#: admin/wp-security-spam-menu.php:323 +msgid "Auto block spammer IPs" +msgstr "Bloquear automaticamente IPs SPAMMER" + +#: admin/wp-security-spam-menu.php:328 +msgid "This feature has detected that %s is not active. It is highly recommended that you activate the Akismet plugin to make the most of this feature." +msgstr "Esse recurso detectou que o %s não está ativo. É altamente recomendável que você ative o plugin Akismet para aproveitar ao máximo este recurso." + +#: admin/wp-security-spam-menu.php:337 +msgid "This feature allows you to automatically and permanently block IP addresses which have exceeded a certain number of comments labelled as spam." +msgstr "Esse recurso permite que você automaticamente e permanentemente bloquear endereços IP que tenham ultrapassado um determinado número de comentários marcados como SPAM." + +#: admin/wp-security-spam-menu.php:338 +msgid "Comments are usually labelled as spam either by the Akismet plugin or manually by the WP administrator when they mark a comment as \"spam\" from the WordPress Comments menu." +msgstr "Comentários são geralmente marcados como SPAM pelo plugin Akismet ou manualmente pelo administrador do WP quando eles marcar um comentário como \"spam\" no menu comentários do WordPress." + +#: admin/wp-security-spam-menu.php:352 +msgid "You currently have no IP addresses permanently blocked due to spam." +msgstr "Atualmente você não tem endereços IP permanentemente bloqueados devido à SPAM." + +#: admin/wp-security-spam-menu.php:365 +msgid "Spammer IPs added to permanent block list today: " +msgstr "IPs spammer adicionado a lista de bloqueios permanente hoje: " + +#: admin/wp-security-spam-menu.php:366 +msgid "All time total: " +msgstr "Total de todo tempo: " + +#: admin/wp-security-spam-menu.php:367 +msgid "View blocked IPs" +msgstr "Ver IPs bloqueados" + +#: admin/wp-security-spam-menu.php:380 +msgid "Enable auto block of spam comment IPs" +msgstr "Ativar o bloqueio automático de IPs de comentário SPAM" + +#: admin/wp-security-spam-menu.php:383 +msgid "Check this box if you want this plugin to automatically block IP addresses which submit spam comments." +msgstr "Marque esta caixa se você deseja que este plugin para bloquear automaticamente endereços IP que apresentem comentários SPAM." + +#: admin/wp-security-spam-menu.php:387 +msgid "Minimum number of spam comments" +msgstr "Número mínimo de comentários SPAM" + +#: admin/wp-security-spam-menu.php:389 +msgid "Specify the minimum number of spam comments for an IP address before it is permanently blocked." +msgstr "Especifica o número mínimo de comentários SPAM para um endereço IP antes que seja permanentemente bloqueado." + +#: admin/wp-security-spam-menu.php:393 +msgid "Example 1: Setting this value to \"1\" will block ALL IP addresses which were used to submit at least one spam comment." +msgstr "Exemplo 1: Definir esse valor para \"1\" irá bloquear todos os endereços IP que foram usados ​​para enviar pelo menos um comentário SPAM." + +#: admin/wp-security-spam-menu.php:394 +msgid "Example 2: Setting this value to \"5\" will block only those IP addresses which were used to submit 5 spam comments or more on your site." +msgstr "Exemplo 2: Definir esse valor para \"5\" irá bloquear apenas os endereços IP que foram usados ​​para enviar 5 comentários SPAM ou mais em seu site." + +#: admin/wp-security-spam-menu.php:412 +msgid "List spammer IP addresses" +msgstr "Lista de endereços IP SPAMMER" + +#: admin/wp-security-spam-menu.php:416 +msgid "This section displays a list of the IP addresses of the people or bots who have left spam comments on your site." +msgstr "Esta seção exibe uma lista dos endereços IP das pessoas ou robôs que deixaram comentários SPAM em seu site." + +#: admin/wp-security-spam-menu.php:417 +msgid "This information can be handy for identifying the most persistent IP addresses or ranges used by spammers." +msgstr "Esta informação pode ser útil para identificar os endereços IP mais persistentes ou intervalos usados ​​por spammers." + +#: admin/wp-security-spam-menu.php:418 +msgid "By inspecting the IP address data coming from spammers you will be in a better position to determine which addresses or address ranges you should block by adding them to the permanent block list." +msgstr "" + +#: admin/wp-security-spam-menu.php:419 +msgid "To add one or more of the IP addresses displayed in the table below to your blacklist, simply click the \"Block\" link for the individual row or select more than one address using the checkboxes and then choose the \"block\" option from the Bulk Actions dropdown list and click the \"Apply\" button." +msgstr "" + +#: admin/wp-security-spam-menu.php:427 +msgid "Minimum number of spam comments per IP" +msgstr "Número mínimo de comentários SPAM por IP" + +#: admin/wp-security-spam-menu.php:429 +msgid "This field allows you to list only those IP addresses which have been used to post X or more spam comments." +msgstr "Este campo permite listar apenas os endereços IP que foram usados ​​para postar X ou mais comentários SPAM." + +#: admin/wp-security-spam-menu.php:433 +msgid "Example 1: Setting this value to \"0\" or \"1\" will list ALL IP addresses which were used to submit spam comments." +msgstr "Exemplo 1: Definir esse valor para \"0\" ou \"1\" irá listar todos os endereços IP que foram usados ​​para enviar comentários SPAM." + +#: admin/wp-security-spam-menu.php:434 +msgid "Example 2: Setting this value to \"5\" will list only those IP addresses which were used to submit 5 spam comments or more on your site." +msgstr "Exemplo 2: Definir esse valor para \"5\" irá listar apenas os endereços IP que foram usados ​​para enviar 5 comentários SPAM ou mais em seu site." + +#: admin/wp-security-spam-menu.php:441 +msgid "Find IP addresses" +msgstr "Encontrar endereços IP" + +#: admin/wp-security-spam-menu.php:445 +msgid "Spammer IP address results" +msgstr "Resultados de endereço IP SPAMMER" + +#: admin/wp-security-spam-menu.php:451 +#: classes/wp-security-utility.php:253 +msgid "The plugin has detected that you are using a Multi-Site WordPress installation." +msgstr "O plugin detectou que você está usando uma instalação de WordPress Multi site." + +#: admin/wp-security-spam-menu.php:452 +msgid "Only the \"superadmin\" can block IP addresses from the main site." +msgstr "Somente o \"super administrador\" pode bloquear endereços IP a partir do site principal." + +#: admin/wp-security-spam-menu.php:453 +msgid "Take note of the IP addresses you want blocked and ask the superadmin to add these to the blacklist using the \"Blacklist Manager\" on the main site." +msgstr "Tome nota dos endereços IP que deseja bloquear e pedir ao super administrador para adicioná-los à lista negra usando o \"Gerenciador de lista negra\" no site principal." + +#: admin/wp-security-spam-menu.php:498 +msgid "BuddyPress spam settings" +msgstr "Configurações de SPAM BuddyPress" + +#: admin/wp-security-spam-menu.php:503 +msgid "Add CAPTCHA to BuddyPress registration form" +msgstr "Adicionar captcha para formulário de registro BuddyPress" + +#: admin/wp-security-spam-menu.php:507 +msgid "This feature will add a simple math CAPTCHA field in the BuddyPress registration form." +msgstr "Este recurso irá adicionar um campo de matemática captcha simples no formulário de inscrição BuddyPress." + +#: admin/wp-security-spam-menu.php:508 +msgid "Adding a CAPTCHA field in the registration form is a simple way of greatly reducing spam signups from bots without using .htaccess rules." +msgstr "Adicionando um campo de captcha no formulário de inscrição é uma maneira simples de reduzir grandemente inscrições SPAM de robôs sem usar regras .htaccess." + +#: admin/wp-security-spam-menu.php:518 +msgid "Enable CAPTCHA on BuddyPress registration form" +msgstr "Habilitar captcha no formulário de registro BuddyPress" + +#: admin/wp-security-spam-menu.php:521 +msgid "Check this if you want to insert a CAPTCHA field on the BuddyPress registration forms." +msgstr "Marque esta opção se você deseja inserir um campo captcha no formulários de registro BuddyPress" + +#: admin/wp-security-spam-menu.php:530 +msgid "BuddyPress is not active! In order to use this feature you will need to have BuddyPress installed and activated." +msgstr "BuddyPress não está ativo! Para utilizar este recurso, você precisará ter o BuddyPress instalado e ativado." + +#: admin/wp-security-spam-menu.php:560 +msgid "bbPress spam settings" +msgstr "" + +#: admin/wp-security-spam-menu.php:565 +msgid "Add CAPTCHA to bbPress new topic form" +msgstr "" + +#: admin/wp-security-spam-menu.php:569 +msgid "This feature will add a simple math CAPTCHA field in the bbPress new topic form." +msgstr "" + +#: admin/wp-security-spam-menu.php:570 +msgid "Adding a CAPTCHA field in this form is a simple way of greatly reducing spam submitted from bots." +msgstr "" + +#: admin/wp-security-spam-menu.php:580 +msgid "Enable CAPTCHA on bbPress new topic form" +msgstr "" + +#: admin/wp-security-spam-menu.php:583 +msgid "Check this if you want to insert a CAPTCHA field on the bbPress new topic forms." +msgstr "" + +#: admin/wp-security-spam-menu.php:592 +msgid "bbPress is not active. In order to use this feature you will need to have bbPress installed and activated." +msgstr "" + +#: admin/wp-security-tools-menu.php:34 +msgid "WHOIS lookup" +msgstr "Pesquisa WHOIS" + +#: admin/wp-security-tools-menu.php:95 +#: admin/wp-security-tools-menu.php:136 +msgid "Querying %s: %s" +msgstr "" + +#: admin/wp-security-tools-menu.php:103 +#: admin/wp-security-tools-menu.php:112 +#: admin/wp-security-tools-menu.php:151 +msgid "Redirected to %s" +msgstr "" + +#: admin/wp-security-tools-menu.php:173 +msgid "The WHOIS lookup feature gives you a way to look up who owns an IP address or domain name." +msgstr "" + +#: admin/wp-security-tools-menu.php:173 +msgid "You can use this to investigate users engaging in malicious activity on your site." +msgstr "" + +#: admin/wp-security-tools-menu.php:176 +msgid "WHOIS lookup on IP or domain" +msgstr "" + +#: admin/wp-security-tools-menu.php:183 +msgid "IP address or domain name:" +msgstr "" + +#: admin/wp-security-tools-menu.php:190 +msgid "Look up IP or domain" +msgstr "" + +#: admin/wp-security-tools-menu.php:219 +msgid "Please enter a valid IP address or domain name to look up." +msgstr "" + +#: admin/wp-security-tools-menu.php:220 +#: admin/wp-security-tools-menu.php:226 +msgid "Nothing to show." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:32 +msgid "WP username" +msgstr "Nome de usuário WP" + +#: admin/wp-security-user-accounts-menu.php:33 +msgid "Display name" +msgstr "Nome de exibição" + +#: admin/wp-security-user-accounts-menu.php:34 +msgid "Password" +msgstr "Senha" + +#: admin/wp-security-user-accounts-menu.php:60 +msgid "User accounts" +msgstr "Contas de usuários" + +#: admin/wp-security-user-accounts-menu.php:82 +msgid "Admin user security" +msgstr "Segurança do usuário administrador" + +#: admin/wp-security-user-accounts-menu.php:85 +msgid "By default, WordPress sets the administrator username to \"admin\" at installation time." +msgstr "Por padrão, o WordPress define o nome do usuário administrador para \"admin\" no momento da instalação." + +#: admin/wp-security-user-accounts-menu.php:86 +msgid "A lot of hackers try to take advantage of this information by attempting \"Brute force login attacks\" where they repeatedly try to guess the password by using \"admin\" for username." +msgstr "Um monte de hackers tentam tirar proveito desta informação pela tentativa \"Ataques Acesso de Força Bruta\" onde eles repetidamente tentam adivinhar a senha usando \"admin\" para o nome de usuário." + +#: admin/wp-security-user-accounts-menu.php:87 +msgid "From a security perspective, changing the default \"admin\" user name is one of the first and smartest things you should do on your site." +msgstr "Numa perspectiva de segurança, alterar o nome de usuário padrão \"admin\" é uma das primeiras e mais inteligentes coisas que você deve fazer em seu site." + +#: admin/wp-security-user-accounts-menu.php:88 +msgid "This feature will allow you to change your default \"admin\" user name to a more secure name of your choosing." +msgstr "Este recurso permitirá que você altere seu nome de usuário \"admin\" padrão para um nome mais seguro de sua escolha." + +#: admin/wp-security-user-accounts-menu.php:95 +msgid "List of administrator accounts" +msgstr "Lista de contas de administrador" + +#: admin/wp-security-user-accounts-menu.php:104 +#: classes/grade-system/wp-security-feature-item-manager.php:43 +msgid "Change admin username" +msgstr "Alterar nome de usuário admin" + +#: admin/wp-security-user-accounts-menu.php:112 +msgid "Your site currently has an account which uses the default \"admin\" username. It is highly recommended that you change this name to something else. Use the following field to change the admin username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:118 +msgid "New admin username" +msgstr "Novo nome de usuário admin" + +#: admin/wp-security-user-accounts-menu.php:120 +msgid "Choose a new username for admin." +msgstr "Escolha um novo nome de usuário para o administrador." + +#: admin/wp-security-user-accounts-menu.php:124 +msgid "Change username" +msgstr "Alterar nome de usuário" + +#: admin/wp-security-user-accounts-menu.php:126 +msgid "NOTE: If you are currently logged in as \"admin\" you will be automatically logged out after changing your username and will be required to log back in." +msgstr "NOTA: Se você está conectado no momento como \"admin\" você será automaticamente desconectado depois de mudar seu nome de usuário e será necessário fazer login novamente." + +#: admin/wp-security-user-accounts-menu.php:133 +msgid "No action required! " +msgstr "Nenhuma ação necessária! " + +#: admin/wp-security-user-accounts-menu.php:135 +msgid "Your site does not have any account which uses the default \"admin\" username. " +msgstr "Seu site não tem qualquer conta que usa o nome de usuário padrão \"admin\"." + +#: admin/wp-security-user-accounts-menu.php:136 +msgid "This is good security practice." +msgstr "Esta é uma boa prática de segurança." + +#: admin/wp-security-user-accounts-menu.php:148 +msgid "Display name security" +msgstr "Segurança do nome de exibição" + +#: admin/wp-security-user-accounts-menu.php:151 +msgid "When you submit a post or answer a comment, WordPress will usually display your \"nickname\"." +msgstr "Quando você envia uma mensagem ou responde a um comentário, o WordPress normalmente exibirá o seu \"apelido\"." + +#: admin/wp-security-user-accounts-menu.php:152 +msgid "By default the nickname is set to the login (or user) name of your account." +msgstr "Por padrão, o apelido é definido para o nome de login (ou usuário) da sua conta." + +#: admin/wp-security-user-accounts-menu.php:153 +msgid "From a security perspective, leaving your nickname the same as your user name is bad practice because it gives a hacker at least half of your account's login credentials." +msgstr "De uma perspectiva de segurança, deixar seu apelido o mesmo que seu nome de usuário é uma prática ruim, porque dá um hacker pelo menos metade das credenciais de login da sua conta." + +#: admin/wp-security-user-accounts-menu.php:154 +msgid "Therefore to further tighten your site's security you are advised to change your nickname and Display name to be different from your Username." +msgstr "Portanto, para apertar ainda mais a segurança do seu site você é aconselhado a alterar o seu apelido e nome de exibição para ser diferente do seu nome de usuário." + +#: admin/wp-security-user-accounts-menu.php:160 +msgid "Modify accounts with identical login name and display name" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:169 +msgid "Your site currently has the following accounts which have an identical login name and display name." +msgstr "Seu site tem atualmente as seguintes contas que têm um nome de login e nome de exibição idêntico." + +#: admin/wp-security-user-accounts-menu.php:170 +msgid "Follow the link to edit the user profile of that particular user account, change Nickname, choose a different Display name compared to Username, and press the \"Update User\" button.)" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:185 +msgid "No action required." +msgstr "Nenhuma ação necessária." + +#: admin/wp-security-user-accounts-menu.php:186 +msgid "Your site does not have a user account where the display name is identical to the username." +msgstr "Seu site não tem uma conta de usuário onde o nome de exibição é idêntico ao nome de usuário." + +#: admin/wp-security-user-accounts-menu.php:197 +msgid "Password tool" +msgstr "Ferramenta de senha" + +#: admin/wp-security-user-accounts-menu.php:200 +msgid "Poor password selection is one of the most common weak points of many sites and is usually the first thing a hacker will try to exploit when attempting to break into your site." +msgstr "Seleção de senha pobres é um dos pontos fracos mais comuns de muitos sites, e é geralmente a primeira coisa que um hacker vai tentar explorar ao tentar entrar no seu site." + +#: admin/wp-security-user-accounts-menu.php:201 +msgid "Many people fall into the trap of using a simple word or series of numbers as their password. Such a predictable and simple password would take a competent hacker merely minutes to guess your password by using a simple script which cycles through the easy and most common combinations." +msgstr "Muitas pessoas caem na armadilha de usar uma palavra simples ou uma série de números como sua senha. Uma senha tão previsível e simples levaria um hacker competente apenas minutos para adivinhar sua senha usando um script simples que percorre as combinações mais comuns e fácil." + +#: admin/wp-security-user-accounts-menu.php:202 +msgid "The longer and more complex your password is the harder it is for hackers to \"crack\" because more complex passwords require much greater computing power and time." +msgstr "O mais longo e mais complexo sua senha é o mais difícil é para os hackers \"crack\" porque as senhas mais complexas exigem muito maior poder de computação e tempo." + +#: admin/wp-security-user-accounts-menu.php:203 +msgid "This section contains a useful password strength tool which you can use to check whether your password is sufficiently strong enough." +msgstr "Esta seção contém uma ferramenta de força de senha útil que você pode usar para verificar se sua senha é suficientemente forte o suficiente." + +#: admin/wp-security-user-accounts-menu.php:208 +msgid "Password strength tool" +msgstr "Ferramenta de força de senha" + +#: admin/wp-security-user-accounts-menu.php:210 +msgid "This password tool uses an algorithm which calculates how long it would take for your password to be cracked using the computing power of an off-the-shelf current model desktop PC with high end processor, graphics card and appropriate password cracking software." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:213 +msgid "Start typing a password." +msgstr "Comece a digitar uma senha." + +#: admin/wp-security-user-accounts-menu.php:216 +msgid "It would take a desktop PC approximately" +msgstr "Demora aproximadamente um PC desktop" + +#: admin/wp-security-user-accounts-menu.php:217 +msgid "1 sec" +msgstr "1 segundo" + +#: admin/wp-security-user-accounts-menu.php:217 +msgid "to crack your password!" +msgstr "para quebrar sua senha!" + +#: admin/wp-security-user-accounts-menu.php:222 +msgid "Password Strength" +msgstr "Força da senha" + +#: admin/wp-security-user-accounts-menu.php:245 +msgid "Username " +msgstr "Nome de usuário " + +#: admin/wp-security-user-accounts-menu.php:245 +msgid " already exists. Please enter another value. " +msgstr " já existe. Por favor, digite outro valor. " + +#: admin/wp-security-user-accounts-menu.php:262 +msgid "The database update operation of the user account failed!" +msgstr "Falha na operação de atualização do banco de dados da conta de usuário!" + +#: admin/wp-security-user-accounts-menu.php:291 +msgid "You entered an invalid username. Please enter another value. " +msgstr "Você digitou um nome de usuário inválido. Por favor, digite outro valor." + +#: admin/wp-security-user-accounts-menu.php:295 +msgid "Please enter a value for your username. " +msgstr "Por favor, digite o seu nome de usuário." + +#: admin/wp-security-user-accounts-menu.php:302 +msgid "Username successfully changed." +msgstr "Nome de usuário alterado com sucesso!" + +#: admin/wp-security-user-accounts-menu.php:322 +msgid "Account login name" +msgstr "Nome de login de conta" + +#: admin/wp-security-user-accounts-menu.php:331 +msgid "Edit user" +msgstr "" + +#: admin/wp-security-user-login-menu.php:54 +#: admin/wp-security-user-login-menu.php:474 +msgid "Failed login records" +msgstr "Registros de falhas de login" + +#: admin/wp-security-user-login-menu.php:55 +#: classes/grade-system/wp-security-feature-item-manager.php:51 +msgid "Force logout" +msgstr "Forçar saída" + +#: admin/wp-security-user-login-menu.php:56 +#: admin/wp-security-user-login-menu.php:632 +msgid "Account activity logs" +msgstr "Logs de atividade de conta" + +#: admin/wp-security-user-login-menu.php:58 +#: admin/wp-security-user-login-menu.php:769 +msgid "Additional settings" +msgstr "" + +#: admin/wp-security-user-login-menu.php:81 +msgid "User login" +msgstr "Login de usuário" + +#: admin/wp-security-user-login-menu.php:118 +msgid "You entered a non-numeric value for the max login attempts field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:124 +msgid "You entered a non numeric value for the login retry time period field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:130 +msgid "You entered a non numeric value for the lockout time length field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:136 +msgid "You entered a non numeric value for the maximim lockout time length field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:141 +msgid "You entered an invalid minimum lockout time length, it must be less than the maximum lockout time length value." +msgstr "" + +#: admin/wp-security-user-login-menu.php:141 +msgid "Both have been set to the default values." +msgstr "" + +#: admin/wp-security-user-login-menu.php:160 +msgid "Please fill in one or more email addresses to notify." +msgstr "" + +#: admin/wp-security-user-login-menu.php:162 +msgid "You have entered one or more invalid email addresses." +msgstr "" + +#: admin/wp-security-user-login-menu.php:165 +msgid "It has been set to your WordPress admin email as default." +msgstr "" + +#: admin/wp-security-user-login-menu.php:250 +msgid "Login lockout configuration" +msgstr "" + +#: admin/wp-security-user-login-menu.php:254 +msgid "One of the ways hackers try to compromise sites is via a " +msgstr "Uma das maneiras que hackers tentam comprometer sites é através de um " + +#: admin/wp-security-user-login-menu.php:254 +msgid "Brute force login attack" +msgstr "Ataque de Login de Força Bruta" + +#: admin/wp-security-user-login-menu.php:254 +msgid "This is where attackers use repeated login attempts until they guess the password." +msgstr "Isto é onde os atacantes usam tentativas de login repetidos até eles adivinhar a senha." + +#: admin/wp-security-user-login-menu.php:255 +msgid "Apart from choosing strong passwords, monitoring and blocking IP addresses which are involved in repeated login failures in a short period of time is a very effective way to stop these types of attacks." +msgstr "Além de escolher senhas fortes, monitoramento e bloqueio de endereços IP que estão envolvidos em falhas de login repetidos em um curto período de tempo é uma maneira muito eficaz de parar esses tipos de ataques." + +#: admin/wp-security-user-login-menu.php:256 +msgid "You may also want to checkout our %s feature for another secure way to protect against these types of attacks." +msgstr "Você também pode querer fazer o check-out em nosso recurso de %s para uma outra forma segura de proteger contra esses tipos de ataques." + +#: admin/wp-security-user-login-menu.php:261 +msgid "Login lockout options" +msgstr "" + +#: admin/wp-security-user-login-menu.php:272 +msgid "Enable login lockout feature" +msgstr "" + +#: admin/wp-security-user-login-menu.php:275 +msgid "Check this if you want to enable the login lockout feature and apply the settings below" +msgstr "" + +#: admin/wp-security-user-login-menu.php:279 +msgid "Allow unlock requests" +msgstr "Permite desbloquear pedidos" + +#: admin/wp-security-user-login-menu.php:282 +msgid "Check this if you want to allow users to generate an automated unlock request link which will unlock their account" +msgstr "Marque esta opção se você deseja permitir que os usuários para gerar um link de solicitação de desbloqueio automático que irá desbloquear as suas contas" + +#: admin/wp-security-user-login-menu.php:286 +msgid "Max login attempts" +msgstr "Tentativas de login máximo" + +#: admin/wp-security-user-login-menu.php:288 +msgid "Set the value for the maximum login retries before IP address is locked out" +msgstr "Defina o valor para o número máximo de tentativas de login antes de endereço IP está bloqueado" + +#: admin/wp-security-user-login-menu.php:292 +msgid "Login retry time period (min)" +msgstr "Período de tempo (min) para fazer login novamente" + +#: admin/wp-security-user-login-menu.php:294 +msgid "If the maximum number of failed login attempts for a particular IP address occur within this time period the plugin will lock out that address" +msgstr "Se o número máximo de tentativas de login para um determinado endereço IP ocorrer dentro deste período de tempo o plugin irá bloquear esse endereço" + +#: admin/wp-security-user-login-menu.php:299 +msgid "Minimum lockout time length" +msgstr "" + +#: admin/wp-security-user-login-menu.php:305 +msgid "Set the minimum time period in minutes of lockout." +msgstr "" + +#: admin/wp-security-user-login-menu.php:306 +msgid "This failed login lockout time will be tripled on each failed login." +msgstr "" + +#: admin/wp-security-user-login-menu.php:313 +msgid "Maximum lockout time length" +msgstr "" + +#: admin/wp-security-user-login-menu.php:318 +msgid "Set the maximum time period in minutes of lockout." +msgstr "" + +#: admin/wp-security-user-login-menu.php:319 +msgid "No IP address will be blocked for more than this time period after making a failed login attempt." +msgstr "" + +#: admin/wp-security-user-login-menu.php:324 +msgid "Display generic error message" +msgstr "Exibir mensagem de erro genérico" + +#: admin/wp-security-user-login-menu.php:327 +msgid "Check this if you want to show a generic error message when a login attempt fails" +msgstr "Marque esta opção se deseja mostrar uma mensagem de erro genérico quando uma tentativa de login falhar" + +#: admin/wp-security-user-login-menu.php:331 +msgid "Instantly lockout invalid usernames" +msgstr "Bloquear instantaneamente nome de usuário inválido" + +#: admin/wp-security-user-login-menu.php:334 +msgid "Check this if you want to instantly lockout login attempts with usernames which do not exist on your system" +msgstr "Marque esta opção se você deseja instantaneamente o bloqueio de tentativas de login com nomes de usuários que não existem em seu sistema" + +#: admin/wp-security-user-login-menu.php:339 +msgid "Instantly lockout specific usernames" +msgstr "" + +#: admin/wp-security-user-login-menu.php:349 +msgid "Insert one username per line. Existing usernames are not blocked even if present in the list." +msgstr "" + +#: admin/wp-security-user-login-menu.php:354 +msgid "Notify by email" +msgstr "Notificar por e-mail" + +#: admin/wp-security-user-login-menu.php:358 +msgid "Check this if you want to receive an email when someone has been locked out due to maximum failed login attempts" +msgstr "Marque esta opção se você deseja receber um e-mail quando alguém foi bloqueado devido a tentativas máximas na falha de login" + +#: admin/wp-security-user-login-menu.php:361 +msgid "Fill in one email address per line." +msgstr "" + +#: admin/wp-security-user-login-menu.php:365 +msgid "Each email address must be on a new line." +msgstr "" + +#: admin/wp-security-user-login-menu.php:366 +msgid "If a valid email address has not been filled in, it will not be saved." +msgstr "" + +#: admin/wp-security-user-login-menu.php:367 +msgid "The valid email address format is userid@example.com" +msgstr "" + +#: admin/wp-security-user-login-menu.php:368 +msgid "Example: %s" +msgstr "" + +#: admin/wp-security-user-login-menu.php:375 +msgid "Enable PHP backtrace in email" +msgstr "" + +#: admin/wp-security-user-login-menu.php:379 +msgid "Check this if you want to include the PHP backtrace in notification emails." +msgstr "" + +#: admin/wp-security-user-login-menu.php:379 +msgid "This is internal coding information which makes it easier to investigate where an issued occurred." +msgstr "" + +#: admin/wp-security-user-login-menu.php:389 +msgid "Currently locked out IP address ranges" +msgstr "Atualmente bloqueado intervalos de endereços IP" + +#: admin/wp-security-user-login-menu.php:394 +msgid "To see a list of all locked IP addresses and ranges go to the %s tab in the dashboard menu." +msgstr "Para ver uma lista de todos os endereços IP bloqueados e intervalos ir para a aba %s no menu do painel." + +#: admin/wp-security-user-login-menu.php:399 +msgid "Login lockout IP whitelist settings" +msgstr "" + +#: admin/wp-security-user-login-menu.php:405 +msgid "Enable login lockout IP whitelist" +msgstr "" + +#: admin/wp-security-user-login-menu.php:416 +msgid "The addresses specified here will never be blocked by the login lockout feature." +msgstr "" + +#: admin/wp-security-user-login-menu.php:450 +msgid "User login feature - Delete all failed login records operation failed." +msgstr "Recurso de login de usuário - Excluir todas as falhas de operação de registros de falhas de login!" + +#: admin/wp-security-user-login-menu.php:452 +msgid "All records from the failed logins table were deleted successfully." +msgstr "Todos os registros da tabela falhas de logins foram excluídos com sucesso!" + +#: admin/wp-security-user-login-menu.php:467 +msgid "This tab displays the failed login attempts for your site." +msgstr "Essa guia exibe as tentativas de login para o seu site." + +#: admin/wp-security-user-login-menu.php:468 +msgid "The information below can be handy if you need to do security investigations because it will show you the IP range, username and ID (if applicable) and the time/date of the failed login attempt." +msgstr "As informações abaixo podem ser útil se você precisa fazer investigações de segurança porque ele lhe mostrará o intervalo de IP, nome de usuário e ID (se aplicável) e a hora/data da falha de tentativa de login." + +#: admin/wp-security-user-login-menu.php:469 +msgid "Failed login records that are older than %1$d days are purged automatically." +msgstr "" + +#: admin/wp-security-user-login-menu.php:508 +#: admin/wp-security-user-login-menu.php:517 +msgid "Delete all failed login records" +msgstr "Excluir todos os registros de falha de login" + +#: admin/wp-security-user-login-menu.php:514 +msgid "Click this button if you wish to delete all failed login records in one go." +msgstr "Clique nesse botão se você deseja excluir todos os registros de falhas de login de uma só vez." + +#: admin/wp-security-user-login-menu.php:544 +msgid "You entered a non numeric value for the logout time period field. It has been set to the default value." +msgstr "Você digitou um valor não numérico para o campo de período de tempo de saída. Foi definido como o valor padrão." + +#: admin/wp-security-user-login-menu.php:569 +msgid "Setting an expiry period for your WP administration session is a simple way to protect against unauthorized access to your site from your computer." +msgstr "Definir um período de expiração para a sessão de administração do WP é uma maneira simples para proteger contra o acesso não autorizado ao seu site a partir do seu computador." + +#: admin/wp-security-user-login-menu.php:570 +msgid "This feature allows you to specify a time period in minutes after which the admin session will expire and the user will be forced to log back in." +msgstr "Este recurso permite que você especifique um período de tempo em minutos, após o qual a sessão de administração irá expirar e o usuário será forçado a voltar a iniciar sessão." + +#: admin/wp-security-user-login-menu.php:575 +msgid "Force user logout options" +msgstr "Opções de saída do usuário à força" + +#: admin/wp-security-user-login-menu.php:587 +msgid "Enable force WP user logout" +msgstr "Habilitar saída do usuário WP à força" + +#: admin/wp-security-user-login-menu.php:590 +msgid "Check this if you want to force a wp user to be logged out after a configured amount of time" +msgstr "Marque esta opção se você deseja forçar um usuário wp a ser desconectado após um período de tempo configurado" + +#: admin/wp-security-user-login-menu.php:594 +msgid "Logout the WP user after XX minutes" +msgstr "Desconectar usuário WP após XX minutos" + +#: admin/wp-security-user-login-menu.php:596 +msgid "(Minutes) The user will be forced to log back in after this time period has elapased." +msgstr "(Minutos) O usuário será obrigado a efetuar login novamente após este período de tempo tem passado." + +#: admin/wp-security-user-login-menu.php:625 +msgid "This tab displays the activity for accounts registered with your site that have logged in using the WordPress login form." +msgstr "" + +#: admin/wp-security-user-login-menu.php:626 +msgid "The information below can be handy if you need to do security investigations because it will show you the last 100 recent login events by username, IP address and time/date." +msgstr "" + +#: admin/wp-security-user-login-menu.php:627 +msgid "Account activity logs that are older than %1$d days are purged automatically." +msgstr "" + +#: admin/wp-security-user-login-menu.php:697 +msgid "Refresh logged in user data" +msgstr "Atualizar dados de usuários conectados" + +#: admin/wp-security-user-login-menu.php:701 +msgid "Refresh data" +msgstr "Atualizar dados" + +#: admin/wp-security-user-login-menu.php:706 +msgid "This tab displays all users who are currently logged into your site." +msgstr "Essa guia exibe todos os usuários que estão atualmente conectados no seu site." + +#: admin/wp-security-user-login-menu.php:707 +msgid "If you suspect there is a user or users who are logged in which should not be, you can block them by inspecting the IP addresses from the data below and adding them to your blacklist." +msgstr "Se você suspeitar que há um ou mais usuários que estão conectados que não deve ser, você pode bloqueá-los inspecionando os endereços IP a partir dos dados abaixo e adicioná-los à sua lista negra." + +#: admin/wp-security-user-login-menu.php:708 +msgid "You can also instantly log them out by clicking on the \"Force logout\" link when you hover over the row in the user id column." +msgstr "Você também pode imediatamente desconecta-los clicando no link \"Força Saída\" quando você passa o mouse sobre a linha na coluna Id do usuário." + +#: admin/wp-security-user-login-menu.php:713 +msgid "Currently logged in users" +msgstr "Usuários atualmente conectados" + +#: admin/wp-security-user-login-menu.php:761 +msgid "WordPress 5.6 introduced a new feature called \"Application passwords\"." +msgstr "" + +#: admin/wp-security-user-login-menu.php:762 +msgid "This allows you to create a token from the WordPress dashboard which then can be used in the authorization header." +msgstr "" + +#: admin/wp-security-user-login-menu.php:763 +msgid "This feature allows you to disable application passwords as they can leave your site vulnerable to social engineering and phishing scams." +msgstr "" + +#: admin/wp-security-user-login-menu.php:780 +#: classes/grade-system/wp-security-feature-item-manager.php:53 +msgid "Disable application password" +msgstr "" + +#: admin/wp-security-user-login-menu.php:783 +msgid "Check this if you want to disable the application password." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:27 +msgid "Manual approval" +msgstr "Aprovação manual" + +#: admin/wp-security-user-registration-menu.php:28 +#: classes/grade-system/wp-security-feature-item-manager.php:59 +msgid "Registration CAPTCHA" +msgstr "Captcha em registro" + +#: admin/wp-security-user-registration-menu.php:29 +msgid "Registration honeypot" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:55 +msgid "User registration" +msgstr "Registro de usuário" + +#: admin/wp-security-user-registration-menu.php:115 +msgid "User registration settings" +msgstr "Configurações de registro de usuários" + +#: admin/wp-security-user-registration-menu.php:119 +msgid "Manually approve new registrations" +msgstr "Aprovar manualmente novos registros" + +#: admin/wp-security-user-registration-menu.php:123 +msgid "If your site allows people to create their own accounts via the WordPress registration form, then you can minimize spam or bogus registrations by manually approving each registration." +msgstr "Se o seu site permite que as pessoas criem suas próprias contas, através do formulário de inscrição WordPress, então você pode minimizar SPAM ou registros falsos, aprovando manualmente cada registro." + +#: admin/wp-security-user-registration-menu.php:124 +msgid "This feature will automatically set a newly registered account to \"pending\" until the administrator activates it. Therefore undesirable registrants will be unable to log in without your express approval." +msgstr "Este recurso irá definir automaticamente uma conta recém registrada para \"pendente\" até que o administrador a ative. Portanto inscritos indesejáveis ​​não serão capazes de entrar sem a sua autorização expressa." + +#: admin/wp-security-user-registration-menu.php:125 +msgid "You can view all accounts which have been newly registered via the handy table below and you can also perform bulk activation/deactivation/deletion tasks on each account." +msgstr "Você pode ver todas as contas que foram recentemente registradas através da tabela acessível abaixo e você também pode executar tarefas de ativação / desativação / exclusão em massa em cada conta." + +#: admin/wp-security-user-registration-menu.php:142 +msgid "Enable manual approval of new registrations" +msgstr "Habilitar aprovação manual de novos registros" + +#: admin/wp-security-user-registration-menu.php:145 +msgid "Check this if you want to automatically disable all newly registered accounts so that you can approve them manually." +msgstr "Marque esta opção se você deseja desabilitar automaticamente todas as contas recém registradas de modo que você possa aprová-las manualmente." + +#: admin/wp-security-user-registration-menu.php:154 +msgid "Approve registered users" +msgstr "Aprovar os usuários registrados" + +#: admin/wp-security-user-registration-menu.php:206 +msgid "This feature allows you to add a CAPTCHA form on the WordPress registration page." +msgstr "Este recurso permite que você adicione uma formulário captcha na página de registro WordPress." + +#: admin/wp-security-user-registration-menu.php:207 +msgid "Users who attempt to register will also need to enter the answer to a simple mathematical question - if they enter the wrong answer, the plugin will not allow them to register." +msgstr "Usuários que tentam registrar também precisará digitar a resposta a uma simples questão de matemática - se entrarem com a resposta errada, o plugin não irá permitir-lhes para se registrar." + +#: admin/wp-security-user-registration-menu.php:208 +msgid "Therefore, adding a CAPTCHA form on the registration page is another effective yet simple spam registration prevention technique." +msgstr "Portanto, adicionando um formulário captcha na página de registro é outra técnica de prevenção de registro SPAM eficaz, ainda que simples." + +#: admin/wp-security-user-registration-menu.php:212 +msgid "Registration page CAPTCHA settings" +msgstr "Configurações de captcha na página de registro" + +#: admin/wp-security-user-registration-menu.php:219 +msgid "The core default behaviour for WordPress Multi Site regarding user registration is that all users are registered via the main site." +msgstr "O comportamento padrão de núcleo para WordPress Multi Site sobre registro de usuário é que todos os usuários são registrados através do site principal." + +#: admin/wp-security-user-registration-menu.php:220 +msgid "Therefore, if you would like to add a CAPTCHA form to the registration page for a Multi Site, please go to \"Registration CAPTCHA\" settings on the main site." +msgstr "Portanto, se você gostaria de adicionar um formulário captcha à página de registro para um multi site, por favor, vá para Configurações \"Captcha Registro\" no site principal." + +#: admin/wp-security-user-registration-menu.php:235 +msgid "Enable CAPTCHA on registration page" +msgstr "Habilitar captcha na página de registro" + +#: admin/wp-security-user-registration-menu.php:238 +msgid "Check this if you want to insert a CAPTCHA form on the WordPress user registration page (if you allow user registration)." +msgstr "Marque esta opção se você deseja inserir um formulário captcha na página de registro de usuário do WordPress (se você permitir o registo do usuário)." + +#: admin/wp-security-user-registration-menu.php:276 +msgid "This feature allows you to add a special hidden \"honeypot\" field on the WordPress registration page. This will only be visible to robots and not humans." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:277 +msgid "Since robots usually fill in every input field from a registration form, they will also submit a value for the special hidden honeypot field." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:279 +msgid "Therefore, if the plugin detects that this field has a value when the registration form is submitted, then the robot which is attempting to register on your site will be redirected to its localhost address - http://127.0.0.1." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:285 +msgid "Registration form honeypot settings" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:296 +msgid "Enable honeypot on registration page" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:299 +msgid "Check this if you want to enable the honeypot feature for the registration page" +msgstr "" + +#: classes/aios-ajax.php:89 +msgid "Invalid IP retrieve method." +msgstr "" + +#: classes/aios-ajax.php:131 +#: wp-security-core.php:258 +msgid "The security check failed; try refreshing the page." +msgstr "" + +#: classes/aios-ajax.php:152 +#: wp-security-core.php:268 +msgid "You are not allowed to run this command." +msgstr "" + +#: classes/aios-ajax.php:173 +#: wp-security-core.php:282 +msgid "Options can only be saved by network admin" +msgstr "" + +#: classes/aios-ajax.php:202 +msgid "The command \"%s\" was not found" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:39 +msgid "Remove WP generator meta tag" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:45 +msgid "Change display name" +msgstr "Alterar nome de exibição" + +#: classes/grade-system/wp-security-feature-item-manager.php:57 +msgid "Registration approval" +msgstr "Aprovação do registro" + +#: classes/grade-system/wp-security-feature-item-manager.php:61 +msgid "Enable registration honeypot" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:73 +msgid "WordPress files access" +msgstr "Acesso arquivos WordPress" + +#: classes/grade-system/wp-security-feature-item-manager.php:77 +msgid "IP and user agent blacklisting" +msgstr "Lista negra de agente de usuário e IP" + +#: classes/grade-system/wp-security-feature-item-manager.php:81 +msgid "Enable basic firewall" +msgstr "Habilitar firewall básico" + +#: classes/grade-system/wp-security-feature-item-manager.php:82 +msgid "Enable pingback vulnerability protection" +msgstr "Habilitar proteção vulnerabilidade pingback" + +#: classes/grade-system/wp-security-feature-item-manager.php:83 +msgid "Block accesss to debug log file" +msgstr "Bloquear o acesso ao arquivo de registro de depuração" + +#: classes/grade-system/wp-security-feature-item-manager.php:87 +msgid "Forbid proxy comments" +msgstr "Proibir comentários proxy" + +#: classes/grade-system/wp-security-feature-item-manager.php:88 +msgid "Deny bad queries" +msgstr "Impedir consultas duvidosas" + +#: classes/grade-system/wp-security-feature-item-manager.php:91 +msgid "5G/6G blacklist" +msgstr "Lista negra 5G/6G" + +#: classes/grade-system/wp-security-feature-item-manager.php:97 +msgid "Enable IP blocking for 404 detection" +msgstr "Habilitar o bloqueio de IP para a detecção de 404" + +#: classes/grade-system/wp-security-feature-item-manager.php:101 +msgid "Enable rename login page" +msgstr "Habilitar renomeação da página de login" + +#: classes/grade-system/wp-security-feature-item-manager.php:106 +msgid "Lost password CAPTCHA" +msgstr "Captcha senha perdida" + +#: classes/grade-system/wp-security-feature-item-manager.php:107 +msgid "Custom login CAPTCHA" +msgstr "Captcha login personalizado" + +#: classes/grade-system/wp-security-feature-item-manager.php:108 +msgid "Woo login CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:109 +msgid "Woo lost password CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:110 +msgid "Woo register CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:112 +msgid "Login IP whitelisting" +msgstr "Lista branca IP login" + +#: classes/grade-system/wp-security-feature-item-manager.php:114 +msgid "Enable login honeypot" +msgstr "Habilitar pote de mel em login" + +#: classes/grade-system/wp-security-feature-item-manager.php:118 +msgid "Comment CAPTCHA" +msgstr "Captcha comentário" + +#: classes/grade-system/wp-security-feature-item-manager.php:119 +msgid "Block spambots" +msgstr "Bloquear Spambots" + +#: classes/grade-system/wp-security-feature-item-manager.php:121 +msgid "BuddyPress registration CAPTCHA" +msgstr "Captcha registro BuddyPress" + +#: classes/grade-system/wp-security-feature-item-manager.php:123 +msgid "bbPress new topic CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item.php:29 +msgid "Basic" +msgstr "Básico" + +#: classes/grade-system/wp-security-feature-item.php:31 +msgid "Intermediate" +msgstr "Intermediario" + +#: classes/grade-system/wp-security-feature-item.php:33 +msgid "Advanced" +msgstr "Avançado" + +#: classes/wp-security-captcha.php:47 +#: classes/wp-security-general-init-tasks.php:407 +msgid "Please enter an answer in digits:" +msgstr "Favor digite a resposta em dígitos:" + +#: classes/wp-security-captcha.php:127 +msgid "one" +msgstr "um" + +#: classes/wp-security-captcha.php:128 +msgid "two" +msgstr "dois" + +#: classes/wp-security-captcha.php:129 +msgid "three" +msgstr "três" + +#: classes/wp-security-captcha.php:130 +msgid "four" +msgstr "quatro" + +#: classes/wp-security-captcha.php:131 +msgid "five" +msgstr "cinco" + +#: classes/wp-security-captcha.php:132 +msgid "six" +msgstr "seis" + +#: classes/wp-security-captcha.php:133 +msgid "seven" +msgstr "sete" + +#: classes/wp-security-captcha.php:134 +msgid "eight" +msgstr "oito" + +#: classes/wp-security-captcha.php:135 +msgid "nine" +msgstr "nove" + +#: classes/wp-security-captcha.php:136 +msgid "ten" +msgstr "dez" + +#: classes/wp-security-captcha.php:137 +msgid "eleven" +msgstr "onze" + +#: classes/wp-security-captcha.php:138 +msgid "twelve" +msgstr "doze" + +#: classes/wp-security-captcha.php:139 +msgid "thirteen" +msgstr "treze" + +#: classes/wp-security-captcha.php:140 +msgid "fourteen" +msgstr "catorze" + +#: classes/wp-security-captcha.php:141 +msgid "fifteen" +msgstr "quinze" + +#: classes/wp-security-captcha.php:142 +msgid "sixteen" +msgstr "dezesseis" + +#: classes/wp-security-captcha.php:143 +msgid "seventeen" +msgstr "dezessete" + +#: classes/wp-security-captcha.php:144 +msgid "eighteen" +msgstr "dezoito" + +#: classes/wp-security-captcha.php:145 +msgid "nineteen" +msgstr "dezenove" + +#: classes/wp-security-captcha.php:146 +msgid "twenty" +msgstr "vinte" + +#: classes/wp-security-cronjob-handler.php:34 +msgid "Every 15 minutes" +msgstr "" + +#: classes/wp-security-debug-logger.php:46 +msgid "Unable to get the reason why" +msgstr "" + +#: classes/wp-security-debug-logger.php:47 +msgid "Unable to clear the logs" +msgstr "" + +#: classes/wp-security-file-scan.php:85 +msgid "All In One WP Security - File change detected!" +msgstr "All In One WP Security - Alteração de arquivo detectada!" + +#: classes/wp-security-file-scan.php:87 +msgid "A file change was detected on your system for site URL" +msgstr "Um arquivo substituido foi detectado em seu sistema do website URL" + +#: classes/wp-security-file-scan.php:87 +msgid ". Scan was generated on" +msgstr ". Verificação foi gerada em" + +#: classes/wp-security-file-scan.php:88 +msgid "A summary of the scan results is shown below:" +msgstr "Um resumo dos resultados da verificação é mostrado abaixo:" + +#: classes/wp-security-file-scan.php:91 +msgid "Login to your site to view the scan details." +msgstr "Logue-se em seu website para ver os detalhes da verificação." + +#: classes/wp-security-file-scan.php:313 +msgid "The following files were added to your host" +msgstr "Os seguintes arquivos foram adicionados ao seu host" + +#: classes/wp-security-file-scan.php:315 +#: classes/wp-security-file-scan.php:323 +#: classes/wp-security-file-scan.php:332 +msgid "modified on: " +msgstr "modificado em: " + +#: classes/wp-security-file-scan.php:321 +msgid "The following files were removed from your host" +msgstr "Os seguintes arquivos foram removidos do seu hospedeiro" + +#: classes/wp-security-file-scan.php:330 +msgid "The following files were changed on your host" +msgstr "Os seguintes arquivos foram alterados em seu hospedeiro" + +#: classes/wp-security-general-init-tasks.php:212 +#: classes/wp-security-general-init-tasks.php:481 +msgid "Application passwords have been disabled by All In One WP Security & Firewall plugin." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:428 +#: classes/wp-security-general-init-tasks.php:541 +#: classes/wp-security-general-init-tasks.php:574 +#: classes/wp-security-user-login.php:137 +#: classes/wp-security-user-registration.php:74 +msgid "ERROR: Your answer was incorrect - please try again." +msgstr "ERRO: A sua resposta está INCORRETA - por favor, tente novamente." + +#: classes/wp-security-general-init-tasks.php:463 +msgid "Enter something special:" +msgstr "Digite algo especial:" + +#: classes/wp-security-general-init-tasks.php:476 +msgid "Application passwords" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:485 +msgid "Change setting" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:487 +msgid "Site admin can only change this setting." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:516 +msgid "Error: You entered an incorrect CAPTCHA answer. Please go back and try again." +msgstr "Erro: Você digitou a resposta CAPTCHA, de forma incorreta. Por favor, volte e tente NOVAMENTE." + +#: classes/wp-security-general-init-tasks.php:558 +msgid "Your CAPTCHA answer was incorrect - please try again." +msgstr "Sua resposta CAPTCHA estava errada - por favor, tente novamente." + +#: classes/wp-security-general-init-tasks.php:567 +msgid "ERROR: Your IP address is currently locked please contact the administrator!" +msgstr "" + +#. translators: %s: Admin Dashboard > WP Security > Brute Force > Login CAPTCHA Tab Link +#: classes/wp-security-general-init-tasks.php:642 +msgid "Your Google reCAPTCHA site key is wrong. Please fill the correct reCAPTCHA keys %s to use the Google reCAPTCHA feature." +msgstr "" + +#. translators: %s: Admin Dashboard > WP Security > Brute Force > Login CAPTCHA Tab Link +#: classes/wp-security-general-init-tasks.php:642 +#: classes/wp-security-notices.php:99 +msgid "here" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +msgid "Would you like All In One WP Security & Firewall to re-insert the security rules in your .htaccess file which were cleared when you deactivated the plugin?" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +#: templates/may-also-like.php:40 +#: templates/may-also-like.php:43 +#: templates/may-also-like.php:54 +#: templates/may-also-like.php:57 +#: templates/may-also-like.php:68 +#: templates/may-also-like.php:71 +#: templates/may-also-like.php:91 +#: templates/may-also-like.php:103 +#: templates/may-also-like.php:115 +#: templates/may-also-like.php:127 +#: templates/may-also-like.php:139 +#: templates/may-also-like.php:151 +#: templates/may-also-like.php:168 +#: templates/may-also-like.php:171 +#: templates/may-also-like.php:183 +#: templates/may-also-like.php:195 +#: templates/may-also-like.php:207 +#: templates/may-also-like.php:219 +#: templates/may-also-like.php:231 +#: templates/may-also-like.php:243 +#: templates/may-also-like.php:252 +#: templates/may-also-like.php:255 +#: templates/may-also-like.php:264 +#: templates/may-also-like.php:267 +#: templates/may-also-like.php:279 +#: templates/may-also-like.php:297 +#: templates/may-also-like.php:309 +#: templates/may-also-like.php:327 +#: templates/may-also-like.php:339 +#: templates/may-also-like.php:351 +#: templates/may-also-like.php:368 +#: templates/may-also-like.php:380 +msgid "Yes" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +#: templates/may-also-like.php:88 +#: templates/may-also-like.php:100 +#: templates/may-also-like.php:112 +#: templates/may-also-like.php:124 +#: templates/may-also-like.php:136 +#: templates/may-also-like.php:148 +#: templates/may-also-like.php:180 +#: templates/may-also-like.php:192 +#: templates/may-also-like.php:204 +#: templates/may-also-like.php:216 +#: templates/may-also-like.php:228 +#: templates/may-also-like.php:240 +#: templates/may-also-like.php:276 +#: templates/may-also-like.php:294 +#: templates/may-also-like.php:306 +#: templates/may-also-like.php:324 +#: templates/may-also-like.php:336 +#: templates/may-also-like.php:348 +#: templates/may-also-like.php:365 +#: templates/may-also-like.php:377 +#: templates/notices/custom-notice.php:27 +msgid "No" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:674 +msgid "Your registration is pending approval." +msgstr "" + +#: classes/wp-security-notices.php:25 +msgid "The All in One Security plugin has disabled the login whitelist setting that you have enabled in the past." +msgstr "" + +#: classes/wp-security-notices.php:29 +msgid "Your website is running on an Apache webserver, the login whitelisting might not be functional until the recent update of AIOS (because it relied upon Apache-specific module features)." +msgstr "" + +#: classes/wp-security-notices.php:31 +msgid "Your website is running on a non-Apache webserver, so the login whitelisting was not functional until the recent update of AIOS (because it relied upon Apache-specific features)." +msgstr "" + +#: classes/wp-security-notices.php:33 +msgid "It began working with AIOS version 5.0.8." +msgstr "" + +#: classes/wp-security-notices.php:33 +msgid "We have disabled it so that your login page will not be blocked unexpectedly." +msgstr "" + +#: classes/wp-security-notices.php:42 +msgid "Would you like to re-enable login whitelisting?" +msgstr "" + +#: classes/wp-security-notices.php:48 +msgid "Removed database backup feature from the All In One WP Security & Firewall plugin" +msgstr "" + +#: classes/wp-security-notices.php:50 +msgid "Beginning with version 5.0.0, AIOS has replaced the AIOS backup method with the superior UpdraftPlus method." +msgstr "" + +#: classes/wp-security-notices.php:51 +msgid "It remains free and is fully supported by the UpdraftPlus team." +msgstr "" + +#: classes/wp-security-notices.php:54 +msgid "You are seeing this notice because you have previously set up automated database backups in AIOS." +msgstr "" + +#: classes/wp-security-notices.php:55 +msgid "Would you like to set up scheduled backups with UpdraftPlus?" +msgstr "" + +#: classes/wp-security-notices.php:61 +msgid "Setup UpdraftPlus backup plugin" +msgstr "" + +#: classes/wp-security-notices.php:67 +msgid "Important: set up your IP address detection settings" +msgstr "" + +#: classes/wp-security-notices.php:69 +msgid "The All in One Security plugin couldn't be certain about the correct method to detect the IP address for your site visitors with your currently-configured IP address detection settings." +msgstr "" + +#: classes/wp-security-notices.php:70 +msgid "It is important for your security to set the IP address detection settings properly." +msgstr "" + +#: classes/wp-security-notices.php:73 +msgid "Please go to the settings and set them now." +msgstr "" + +#: classes/wp-security-notices.php:79 +msgid "Setup IP address detection settings" +msgstr "" + +#: classes/wp-security-notices.php:85 +msgid "Important: Disabled login whitelist setting" +msgstr "" + +#: classes/wp-security-notices.php:91 +msgid "Turn it back on" +msgstr "" + +#: classes/wp-security-notices.php:92 +msgid "Edit the settings" +msgstr "" + +#: classes/wp-security-notices.php:95 +msgid "Keep it off" +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Hey - We noticed All In One WP Security & Firewall has kept your site safe for a while. If you like us, please consider leaving a positive review to spread the word. Or if you have any issues or questions please leave us a support message %s." +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Thank you so much!" +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Team All In One WP Security & Firewall" +msgstr "" + +#: classes/wp-security-notices.php:109 +msgid "Enhance your security even more by backing up your site" +msgstr "" + +#: classes/wp-security-notices.php:110 +msgid "UpdraftPlus is the world's most trusted backup plugin from the owners of All In One WP Security & Firewall" +msgstr "" + +#: classes/wp-security-notices.php:121 +msgid "After you've secured your site, we recommend you install our WP-Optimize plugin to streamline it for better website performance." +msgstr "" + +#: classes/wp-security-process-renamed-login-page.php:152 +msgid "Not available." +msgstr "" + +#: classes/wp-security-two-factor-login.php:34 +msgid "Two factor authentication - Admin settings" +msgstr "" + +#: classes/wp-security-two-factor-login.php:97 +msgid "Two Factor Auth" +msgstr "" + +#: classes/wp-security-two-factor-login.php:153 +msgid "PHP OpenSSL or mcrypt module required" +msgstr "" + +#: classes/wp-security-two-factor-login.php:153 +msgid "The All In One WP Security plugin's Two Factor Authentication module requires either the PHP openssl (preferred) or mcrypt module to be installed. Please ask your web hosting company to install one of them." +msgstr "" + +#: classes/wp-security-user-login.php:71 +msgid "You have disabled login lockout by defining the AIOS_DISABLE_LOGIN_LOCKOUT constant value as true, and the login lockout setting has enabled it." +msgstr "" + +#. translators: 1: Locked IP Addresses admin page link +#: classes/wp-security-user-login.php:73 +msgid "Delete your login lockout IP from %s and define the AIOS_DISABLE_LOGIN_LOCKOUT constant value as false." +msgstr "" + +#: classes/wp-security-user-login.php:100 +msgid "ERROR: Access from your IP address has been blocked for security reasons. Please contact the administrator." +msgstr "" + +#: classes/wp-security-user-login.php:108 +msgid "Service temporarily unavailable" +msgstr "" + +#: classes/wp-security-user-login.php:163 +msgid "ACCOUNT PENDING: Your account is currently not active. An administrator needs to activate your account before you can login." +msgstr "CONTA PENDENTE: A sua CONTA não está ativa. Um administrador precisa ativar a sua conta antes de você efetuar o LOGIN." + +#: classes/wp-security-user-login.php:242 +msgid "ERROR: Invalid login credentials." +msgstr "ERRO: As suas informações de login são INVÁLIDAS." + +#: classes/wp-security-user-login.php:392 +msgid "Site Lockout Notification" +msgstr "Notificação de bloqueio do site" + +#: classes/wp-security-user-login.php:393 +msgid "User login lockout events had occurred due to too many failed login attempts or invalid username:" +msgstr "" + +#: classes/wp-security-user-login.php:396 +msgid "Username:" +msgstr "" + +#: classes/wp-security-user-login.php:397 +msgid "IP address:" +msgstr "" + +#: classes/wp-security-user-login.php:399 +msgid "IP range:" +msgstr "" + +#: classes/wp-security-user-login.php:404 +msgid "Log into your site WordPress administration panel to see the duration of the lockout or to unlock the user." +msgstr "" + +#: classes/wp-security-user-login.php:515 +msgid "Unlock request notification" +msgstr "Desbloquear solicitação de notificação" + +#: classes/wp-security-user-login.php:516 +msgid "You have requested for the account with email address %s to be unlocked. Please click the link below to unlock your account:" +msgstr "" + +#: classes/wp-security-user-login.php:516 +msgid "Unlock link: %s" +msgstr "" + +#: classes/wp-security-user-login.php:516 +msgid "After clicking the above link you will be able to login to the WordPress administration panel." +msgstr "Após clicar no link acima, você será capaz de acessar o painel de administração do WordPress." + +#: classes/wp-security-user-login.php:739 +msgid "Your session has expired because it has been over %d minutes since your last login." +msgstr "A sua sessão foi encerrada porque já se passaram %d minutos do seu último login." + +#: classes/wp-security-user-login.php:740 +#: classes/wp-security-user-login.php:744 +msgid "Please log back in to continue." +msgstr "Por favor efetue o login novamente para continuar." + +#: classes/wp-security-user-login.php:743 +msgid "You were logged out because you just changed the \"admin\" username." +msgstr "Você foi desconectado porque você apenas alterou o nome de usuário \"admin\"." + +#: classes/wp-security-user-login.php:773 +msgid "Request unlock" +msgstr "Solicitação de desbloqueio" + +#: classes/wp-security-user-registration.php:68 +msgid "ERROR: You are not allowed to register because your IP address is currently locked!" +msgstr "ERRO: Você não tem permissão para se registrar porque seu endereço IP está atualmente bloqueado!" + +#: classes/wp-security-utility-ip-address.php:217 +#: classes/wp-security-utility-ip-address.php:231 +#: classes/wp-security-utility-ip-address.php:245 +#: classes/wp-security-utility-ip-address.php:257 +#: classes/wp-security-utility-ip-address.php:269 +msgid " is not a valid ip address format." +msgstr " esse formato de endereço de IP não é válido." + +#: classes/wp-security-utility-ip-address.php:274 +msgid "You cannot ban your own IP address: " +msgstr "Você não pode banir o seu próprio endereço IP" + +#: classes/wp-security-utility.php:254 +msgid "This feature can only be configured by the \"superadmin\" on the main site." +msgstr "Este recurso só pode ser configurado pelo \"super administrador\" no site principal." + +#: other-includes/wp-security-unlock-request.php:32 +msgid "ERROR: Unable to process your request!" +msgstr "ERRO: Não é possível processar o seu pedido!" + +#: other-includes/wp-security-unlock-request.php:45 +msgid "Please enter a valid email address" +msgstr "Por favor digite um endereço de e-mail válido" + +#: other-includes/wp-security-unlock-request.php:57 +msgid "User account not found!" +msgstr "Conta de usuário não encontrada!" + +#: other-includes/wp-security-unlock-request.php:71 +msgid "Error: No locked entry was found in the database with your IP address range." +msgstr "Erro: Nenhuma entrada bloqueada foi encontrada no banco de dados com seu intervalo de endereços IP!" + +#: other-includes/wp-security-unlock-request.php:76 +msgid "An email has been sent to you with the unlock instructions." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:93 +msgid "You are here because you have been locked out due to too many incorrect login attempts." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:94 +msgid "Please enter your email address and you will receive an email with instructions on how to unlock yourself." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:104 +msgid "Email Address" +msgstr "Endereço de e-mail" + +#: other-includes/wp-security-unlock-request.php:108 +msgid "Send unlock request" +msgstr "" + +#: templates/admin/incompatible-plugin.php:6 +msgid "Two Factor Authentication" +msgstr "" + +#: templates/admin/incompatible-plugin.php:10 +msgid "Two Factor Authentication currently disabled" +msgstr "" + +#: templates/admin/incompatible-plugin.php:12 +#: templates/admin/incompatible-plugin.php:16 +msgid "Two factor authentication in All In One WP Security is currently disabled because the incompatible plugin %s is active." +msgstr "" + +#: templates/automated-database-backup.php:4 +msgid "Automated scheduled backups" +msgstr "Backups agendados automatizados" + +#: templates/automated-database-backup.php:9 +msgid "Automate backup in the UpdraftPlus plugin" +msgstr "" + +#: templates/automated-database-backup.php:19 +msgid "The AIOS 5.0.0 version release has removed the automated backup feature." +msgstr "" + +#: templates/automated-database-backup.php:20 +msgid "The AIOS automated backup had issues that made it less robust than we could be happy with." +msgstr "" + +#: templates/automated-database-backup.php:21 +msgid "Follow this link to automate backups in the superior UpdraftPlus backup plugin." +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:5 +msgid "Each IP address must be on a new line." +msgstr "Cada endereço IP deve estar em uma nova linha." + +#: templates/info/ip-address-ip-range-info.php:6 +msgid "To specify an IPv4 range use a wildcard \"*\" character. Acceptable ways to use wildcards is shown in the examples below:" +msgstr "Para especificar um endereço IPv4 escala usar um caractere curinga \"*\". Maneiras aceitáveis para usar caracteres curinga é mostrada nos exemplos abaixo:" + +#: templates/info/ip-address-ip-range-info.php:7 +msgid "Example 1: 195.47.89.*" +msgstr "Exemplo 1: 195.47.89.*" + +#: templates/info/ip-address-ip-range-info.php:8 +msgid "Example 2: 195.47.*.*" +msgstr "Exemplo 2: 195.47.*.*" + +#: templates/info/ip-address-ip-range-info.php:9 +msgid "Example 3: 195.*.*.*" +msgstr "Exemplo 3: 195.*.*.*" + +#: templates/info/ip-address-ip-range-info.php:10 +msgid "To specify an IPv6 range use CIDR format as shown in the examples below:" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:11 +msgid "Example 4: 2401:4900:54c3:af15:2:2:5dc0:0/112" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:12 +msgid "Example 5: 2001:db8:1263::/48" +msgstr "" + +#: templates/may-also-like.php:5 +msgid "All-In-One Security (AIOS) Free vs Premium Comparison Chart" +msgstr "" + +#: templates/may-also-like.php:7 +msgid "FAQs" +msgstr "" + +#: templates/may-also-like.php:9 +msgid "Ask a pre-sales question" +msgstr "" + +#: templates/may-also-like.php:17 +msgid "All In One WP Security & Firewall Free" +msgstr "" + +#: templates/may-also-like.php:26 +#: templates/may-also-like.php:386 +msgid "Installed" +msgstr "" + +#: templates/may-also-like.php:29 +#: templates/may-also-like.php:389 +msgid "Upgrade now" +msgstr "" + +#: templates/may-also-like.php:34 +msgid "Login security feature suite" +msgstr "" + +#: templates/may-also-like.php:35 +msgid "Protect against brute-force attacks and keep bots at bay." +msgstr "" + +#: templates/may-also-like.php:35 +msgid "AIOS takes WordPress' default login security features to a whole new level." +msgstr "" + +#: templates/may-also-like.php:37 +msgid "To see all login security features, visit %s" +msgstr "" + +#: templates/may-also-like.php:48 +msgid "Firewall and file protection feature suite" +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Protection from the latest exploits." +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Activate firewall settings ranging from basic, intermediate and advanced." +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Get comprehensive, instant protection with All-in-One Security." +msgstr "" + +#: templates/may-also-like.php:51 +msgid "To see all firewall and file protection features, visit %s" +msgstr "" + +#: templates/may-also-like.php:62 +msgid "Content protection feature suite" +msgstr "" + +#: templates/may-also-like.php:63 +msgid "Eliminate spam and protect your content to dramatically improve your website's interactions with search engines." +msgstr "" + +#: templates/may-also-like.php:65 +msgid "To see all content protection features, visit %s" +msgstr "" + +#: templates/may-also-like.php:76 +msgid "Malware scanning" +msgstr "" + +#: templates/may-also-like.php:77 +msgid "Finding out by accident that your site has been infected with malware is too late." +msgstr "" + +#: templates/may-also-like.php:79 +msgid "Malware can have a dramatic effect on your site's search rankings and you may not even know about it." +msgstr "" + +#: templates/may-also-like.php:79 +msgid "It can slow your website down, access customer data, send unsolicited emails, change your content or prevent users from accessing it." +msgstr "" + +#: templates/may-also-like.php:84 +msgid "Automatic malware scanning" +msgstr "" + +#: templates/may-also-like.php:85 +msgid "Best-in-class scanning for the latest malware, trojans and spyware 24/7." +msgstr "" + +#: templates/may-also-like.php:96 +msgid "Response time monitoring" +msgstr "" + +#: templates/may-also-like.php:97 +msgid "You'll know immediately if your website's response time is negatively affected." +msgstr "" + +#: templates/may-also-like.php:108 +msgid "Up-time monitoring" +msgstr "" + +#: templates/may-also-like.php:109 +msgid "AIOS checks your website's uptime every 5 minutes." +msgstr "" + +#: templates/may-also-like.php:109 +msgid "We'll notify you straight away if your site/server goes down." +msgstr "" + +#: templates/may-also-like.php:120 +msgid "Prevents blacklisting by search engines" +msgstr "" + +#: templates/may-also-like.php:121 +msgid "AIOS monitors your site's blacklist status daily." +msgstr "" + +#: templates/may-also-like.php:121 +msgid "We'll notify you within 24 hours if something's amiss so you can take action, before it's too late." +msgstr "" + +#: templates/may-also-like.php:132 +msgid "Flexible assignment" +msgstr "" + +#: templates/may-also-like.php:133 +msgid "Register and remove websites from the scanning service at any time." +msgstr "" + +#: templates/may-also-like.php:144 +msgid "Malware reports" +msgstr "" + +#: templates/may-also-like.php:145 +msgid "Reports are available via the 'My Account' page and directly via email." +msgstr "" + +#: templates/may-also-like.php:156 +msgid "Flexible two-factor authentication" +msgstr "" + +#: templates/may-also-like.php:157 +msgid "With Two-Factor Authentication (TFA) users enter their username and password and a one-time code sent to a device to login." +msgstr "" + +#: templates/may-also-like.php:159 +msgid "TFA is a feature in both our free and premium packages, but AIOS Premium affords whole new levels of control over how TFA is implemented." +msgstr "" + +#: templates/may-also-like.php:164 +msgid "Authenticator apps" +msgstr "" + +#: templates/may-also-like.php:165 +msgid "Supports TOTP and HOTP protocols." +msgstr "" + +#: templates/may-also-like.php:165 +msgid "TFA Can be used with Google Authenticator, Microsoft Authenticator, Authy and many more." +msgstr "" + +#: templates/may-also-like.php:176 +msgid "Role specific configuration" +msgstr "" + +#: templates/may-also-like.php:177 +msgid "Make it compulsory for certain roles e.g. for admin and editor roles." +msgstr "" + +#: templates/may-also-like.php:188 +msgid "Require TFA after a set time period" +msgstr "" + +#: templates/may-also-like.php:189 +msgid "For example you could require all admins to have TFA once their accounts are a week old." +msgstr "" + +#: templates/may-also-like.php:200 +msgid "Trusted devices - control how often TFA is required" +msgstr "" + +#: templates/may-also-like.php:201 +msgid "Ask for TFA after a chosen number of days for trusted devices instead of on every login." +msgstr "" + +#: templates/may-also-like.php:212 +msgid "Anti-bot protection" +msgstr "" + +#: templates/may-also-like.php:213 +msgid "Option to hide the existence of forms on WooCommerce login pages unless JavaScript is active." +msgstr "" + +#: templates/may-also-like.php:224 +msgid "Customise TFA design layout" +msgstr "" + +#: templates/may-also-like.php:225 +msgid "Customise the design of TFA so it aligns with your existing web design." +msgstr "" + +#: templates/may-also-like.php:236 +msgid "TFA emergency codes" +msgstr "" + +#: templates/may-also-like.php:237 +msgid "Generate a one-time use emergency code to allow access if your device is lost." +msgstr "" + +#: templates/may-also-like.php:248 +msgid "TFA multisite compatibility" +msgstr "" + +#: templates/may-also-like.php:249 +msgid "TFA is Compatible with multisite networks and sub-sites." +msgstr "" + +#: templates/may-also-like.php:260 +msgid "TFA support for common login forms" +msgstr "" + +#: templates/may-also-like.php:261 +msgid "Supports WooCommerce, Affiliates-WP and Theme my Login login forms." +msgstr "" + +#: templates/may-also-like.php:272 +msgid "TFA support for other login forms" +msgstr "" + +#: templates/may-also-like.php:273 +msgid "Supports Elementor Pro, bbPress and all third-party login forms without any further coding needed." +msgstr "" + +#: templates/may-also-like.php:284 +msgid "Smart 404 blocking" +msgstr "" + +#: templates/may-also-like.php:285 +msgid "404 errors can occur when someone legitimately mistypes a URL, but they're also generated by hackers searching for weaknesses in your site." +msgstr "" + +#: templates/may-also-like.php:290 +msgid "Automatically and permanently blocks bots producing 404s" +msgstr "" + +#: templates/may-also-like.php:291 +msgid "AIOS Premium provides more protection than the competition by automatically and permanently blocking IP addresses of bots and hackers based on how many 404 errors they generate." +msgstr "" + +#: templates/may-also-like.php:302 +msgid "404 error charts" +msgstr "" + +#: templates/may-also-like.php:303 +msgid "Handy charts keep you informed of how many 404s have occurred and which IP address or country is producing them." +msgstr "" + +#: templates/may-also-like.php:314 +msgid "Country blocking" +msgstr "" + +#: templates/may-also-like.php:315 +msgid "Most malicious attacks come from a handful of countries and so it's possible to prevent most attacks with our country blocking tool." +msgstr "" + +#: templates/may-also-like.php:320 +msgid "Block traffic based on country of origin" +msgstr "" + +#: templates/may-also-like.php:321 +msgid "AIOS Premium utilises an IP database that promises 99.5% accuracy." +msgstr "" + +#: templates/may-also-like.php:332 +msgid "Block traffic to specific pages based on country of origin" +msgstr "" + +#: templates/may-also-like.php:333 +msgid "Block access to your whole site or on a page-by-page basis." +msgstr "" + +#: templates/may-also-like.php:344 +msgid "Whitelist some users from blocked countries" +msgstr "" + +#: templates/may-also-like.php:345 +msgid "Whitelist IP addresses or IP ranges even if they are part of a blocked country." +msgstr "" + +#: templates/may-also-like.php:356 +msgid "Premium support" +msgstr "" + +#: templates/may-also-like.php:361 +msgid "Unlimited support" +msgstr "" + +#: templates/may-also-like.php:362 +msgid "Personalised, email support from our team of Security experts, as and when you need it." +msgstr "" + +#: templates/may-also-like.php:373 +msgid "Guaranteed response time" +msgstr "" + +#: templates/may-also-like.php:374 +msgid "We offer a guaranteed response time of three days." +msgstr "" + +#: templates/may-also-like.php:374 +msgid "99% of our Premium customers receive a response to their enquiry within 24 hours during the working week." +msgstr "" + +#: templates/may-also-like.php:397 +msgid "Our other plugins" +msgstr "" + +#: templates/may-also-like.php:411 +msgid "UpdraftPlus – the ultimate protection for your site, hard work and business" +msgstr "" + +#: templates/may-also-like.php:412 +msgid "Simplifies backups and restoration." +msgstr "" + +#: templates/may-also-like.php:412 +msgid "It is the world's highest ranking and most popular scheduled backup plugin, with over three million currently-active installs." +msgstr "" + +#: templates/may-also-like.php:413 +#: templates/may-also-like.php:419 +#: templates/may-also-like.php:425 +#: templates/may-also-like.php:431 +msgid "Try for free" +msgstr "" + +#: templates/may-also-like.php:417 +msgid "WP-Optimize – keep your database fast and efficient" +msgstr "" + +#: templates/may-also-like.php:418 +msgid "Makes your site fast and efficient." +msgstr "" + +#: templates/may-also-like.php:418 +msgid "It cleans the database, compresses images and caches pages for ultimate speed." +msgstr "" + +#: templates/may-also-like.php:423 +msgid "UpdraftCentral – save hours managing multiple WP sites from one place" +msgstr "" + +#: templates/may-also-like.php:424 +msgid "Highly efficient way to manage, optimize, update and backup multiple websites from one place." +msgstr "" + +#: templates/may-also-like.php:429 +msgid "Easy Updates Manager" +msgstr "" + +#: templates/may-also-like.php:430 +msgid "Keeps your WordPress site up to date and bug free." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:2 +msgid "IP address detection settings" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:6 +msgid "The IP address detection settings allow you to specify how visitors' IP addresses are made known to PHP (and hence to WordPress and its plugins)." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:7 +msgid "Usually, this is automatic and there is only one choice." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:8 +msgid "However in some setups, such as those using proxies (including load-balancers and security firewalls like Cloudflare), it may be necessary to set this manually." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "Attention" +msgstr "Atenção!" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "It is important to set this correctly - otherwise you may make it possible for a hacker to ban all your visitors (e.g. via banning Cloudflare from connecting to you) instead of being banned himself." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "The default is to use the REMOTE_ADDR PHP server variable. If this variable does not contain the visitor's IP address, then whilst you can make a different selection below, it is better to ask your web hosting company to have it correctly set." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:10 +msgid "This is the most secure setup, because when set correctly it is immune from being spoofed by an attacker." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:16 +msgid "You have no available IP address detection method(s); you must contact your web hosting company." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:22 +#: templates/menus/settings/advanced-settings.php:27 +#: templates/menus/settings/advanced-settings.php:32 +msgid "Your detected IP address according to %s:" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:38 +msgid "If your site is setup on localhost, you won't see your external IP address using your server's IP detection setting; but on a localhost-served site (not available to the outside world), the setting is irrelevant and can be ignored." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:61 +msgid "Choose a $_SERVER variable you would like to detect visitors' IP address using." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:67 +msgid "If your chosen server variable fails the plugin will automatically fall back to retrieving the IP address from $_SERVER[\"REMOTE_ADDR\"]" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:73 +msgid "Your IP address if using this setting:" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:75 +msgid "fetching..." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:81 +#: templates/menus/settings/advanced-settings.php:190 +msgid "getting..." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:89 +msgid "look-up possibly blocked by an ad-blocker or similar tool" +msgstr "" + +#: templates/notices/cookie-based-brute-force-prevention-disabled.php:4 +msgid "Cookie based brute force login prevention currently disabled" +msgstr "" + +#: templates/notices/cookie-based-brute-force-prevention-disabled.php:6 +msgid "Cookie based brute force login prevention is currently disabled via the AIOS_DISABLE_COOKIE_BRUTE_FORCE_PREVENTION constant (which is mostly likely to be defined in your wp-config.php)" +msgstr "" + +#: templates/notices/disable-login-whitelist.php:4 +msgid "Login whitelisting currently disabled" +msgstr "" + +#: templates/notices/disable-login-whitelist.php:6 +msgid "Login whitelisting is currently disabled via the AIOS_DISABLE_LOGIN_WHITELIST constant (which is mostly likely to be defined in your wp-config.php)" +msgstr "" + +#: templates/notices/horizontal-notice.php:8 +#: templates/notices/horizontal-notice.php:40 +msgid "notice image" +msgstr "" + +#: templates/notices/horizontal-notice.php:18 +msgid "Ok, you deserve it" +msgstr "" + +#: templates/notices/horizontal-notice.php:22 +msgid "Maybe later" +msgstr "" + +#: templates/notices/horizontal-notice.php:26 +msgid "Never" +msgstr "" + +#: templates/notices/horizontal-notice.php:66 +msgid "Get UpdraftCentral" +msgstr "" + +#: templates/notices/horizontal-notice.php:68 +msgid "Get UpdraftPlus" +msgstr "" + +#: templates/notices/horizontal-notice.php:70 +msgid "Get WP-Optimize" +msgstr "" + +#: templates/notices/horizontal-notice.php:72 +msgid "Find out more." +msgstr "" + +#: templates/notices/horizontal-notice.php:74 +msgid "Sign up" +msgstr "" + +#: templates/notices/horizontal-notice.php:76 +msgid "Go there" +msgstr "" + +#: templates/notices/horizontal-notice.php:78 +msgid "Read more" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:4 +msgid "Dismiss (for %s months)" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:6 +msgid "Thank you for installing All In One WP Security & Firewall!" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:13 +msgid "Super-charge and secure your WordPress site even more with our other top plugins:" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:17 +msgid "%s makes your site fast and efficient. It cleans the database, compresses images and caches pages for ultimate speed." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:21 +msgid "%s simplifies backups and restoration. It is the world's highest ranking and most popular scheduled backup plugin, with over three million currently-active installs." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:25 +msgid "%s is a highly efficient way to manage, optimize, update and backup multiple websites from one place." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:29 +msgid "%s is a WordPress subscription extension for WooCommerce store owners." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:33 +msgid "More quality plugins" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:33 +msgid "Premium WooCommerce plugins" +msgstr "" + +#: templates/partials/non-apache-feature-notice.php:9 +msgid "This feature works only on the Apache server." +msgstr "" + +#: templates/partials/non-apache-feature-notice.php:10 +msgid "You are using the non-apache server %s, so this feature won't work on your site." +msgstr "" + +#: wp-security-core.php:236 +#: wp-security.php:45 +msgid "This plugin requires PHP version %s." +msgstr "" + +#: wp-security-core.php:237 +msgid "Current site PHP version is %s." +msgstr "" + +#: wp-security-core.php:238 +#: wp-security.php:47 +msgid "You will need to ask your web hosting company to upgrade." +msgstr "" + +#: wp-security-core.php:397 +msgid "Error:" +msgstr "" + +#: wp-security-core.php:397 +msgid "template not found" +msgstr "" + +#: wp-security.php:44 +msgid "All In One WP Security and Firewall plugin has been deactivated." +msgstr "" + +#: wp-security.php:46 +msgid "Your current PHP version is %s." +msgstr "" diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-sv_SE.mo b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-sv_SE.mo new file mode 100755 index 0000000000000000000000000000000000000000..093a7b9806a7fde18fa35fd78746162e6962e590 GIT binary patch literal 3388 zcma);O^jSe5yv~k0la)ji4;CW5Ve*-PMkNMF^L_|+7`3xSu^r_ceFdZAri#&yw~%l zciwal-Th|0;=%o& z&wx*!5#kHr)8Gd90(b{J0MCKH2baOWgI@uco)Y4-;0xdv!K>hxz#Z`Opank({uo>Z z-vD0*-vf8RvmX}%U&VJomP+#R(@h?EQAl?L7-><>5 z;BV^r--4{~t$O@6$a;PUvi!Rs{>2|_z7Mj#zkufuv%i8r!uSl7u7E!QuYm7>yWoGo zC2$vyi{N*`F8Btx1-=h*yuS9S>U`G02F5A)4ES^KbKnv9W$+w__( z9mzDcr3s`xrKNMqgyN8l4R{gsTs5d;NM=)QG}g&r9T}xEPr+6aGAKGct!Su5*2OtW zrJ=&++B6 zD+=zAWG;E*&L}`GEp$53CZ{k~B!_mcsL*D@meYYQ3L5fsft9v41z%Y9RqL|8Q{JBr zg0_Zc(x{>#x>KnO>SP(qh_2zyyq&5r=H2{ErEsP#y3SeGrcKtKPEhOrQihOxj=q`^?o=6+Cy$e>?@%FOV0~kh&c{K-Csqkns5vmw$mhtp z67b)}N1QU+D8Y|7vKaWdBtGMu*Y^ZI@q2(0B&n+gW2ck|2daQpz=T7&6HI4##|CC$s!y4?PH>p~NPOB;w!GN^at3pKDV zS>3nJ(E7eA3WLaA8{$Hx>KmhaqLJF^4XiYIDRY$!l$?I#y30t!d9;tN<$l`u==E*# z^Se9Ur8~Vl-IJKK8qK9OBs&6^3=U`TGpKvv;;cXkTH%ayUWMzsgZ1Q<6FGKcq+HTP z{mM`++Vsj$hoyc|I$0#^)=hnz%q$N5^-C)#Zv5u@c|*(BsrCHI(zlXZ3NCY1Zd2dl zKmxTIFE_5>O*KqbQA}nsjN8;WnY^tI4^Y?q25Nen?%rLwt4?0-DCyF1A8V54Bdd0h zZK+zToM}_#&BMZeduwyBHK5MkUg!3pbGpRe)FIFW(Xq6+@9;6EM72T%kQ20+(4d|% zC}3Ghld56l67OHc)$;1I-pkg!Y9E3OG3- zk1=}$5jKOJBK_Eo;_HrbN9`A~Y9~7rr{`oAM|muyIgNQoJ7tYAfIOUXK((L9wpdq1 zn{dx!3*nAn5W%COKnM{6h0?M(LV>BY54jT46h#WjN4uq=&e?IKJR+cv z%VIKG+%JN{x!r<;0o`*bCz5PBrkS&I$;Xv1j=0(4T|-n}U=Nh{wRG1uy@ll+gITZSY&c-Uxg5$3)?7YS%N5BG#- z#2;==aqw{Cq}kxNiOS%!R|b`oJvzQ04Z$m\n" +"Language-Team: Tor-Bjorn Fjellner 6 Nov 2014 \n" +"Language: sv_SE\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 1.5.7\n" +"X-Poedit-Basepath: .\n" +"X-Poedit-KeywordsList: __;_e\n" +"X-Poedit-SearchPath-0: .\n" +"X-Poedit-SourceCharset: UTF-8\n" + +#. Plugin Name of the plugin +msgid "All In One WP Security" +msgstr "" + +#. Plugin URI of the plugin +msgid "https://wordpress.org/plugins/all-in-one-wp-security-and-firewall/" +msgstr "" + +#. Description of the plugin +msgid "All round best WordPress security plugin!" +msgstr "" + +#. Author of the plugin +msgid "All In One WP Security & Firewall Team" +msgstr "" + +#. Author URI of the plugin +msgid "https://teamupdraft.com/" +msgstr "" + +#: admin/general/wp-security-list-table.php:483 +msgid "Are you sure you want to perform this bulk action?" +msgstr "" + +#: admin/wp-security-admin-init.php:259 +msgid "Unexpected response:" +msgstr "" + +#: admin/wp-security-admin-init.php:290 +msgid "Enjoyed %1$s? Please leave us a %2$s rating. We really appreciate your support!" +msgstr "" + +#: admin/wp-security-admin-init.php:414 +#: classes/wp-security-two-factor-login.php:95 +msgid "WP Security" +msgstr "" + +#: admin/wp-security-admin-init.php:415 +#: admin/wp-security-dashboard-menu.php:26 +#: admin/wp-security-dashboard-menu.php:76 +msgid "Dashboard" +msgstr "" + +#: admin/wp-security-admin-init.php:416 +#: admin/wp-security-settings-menu.php:95 +msgid "Settings" +msgstr "" + +#: admin/wp-security-admin-init.php:417 +msgid "User Accounts" +msgstr "" + +#: admin/wp-security-admin-init.php:418 +msgid "User Login" +msgstr "" + +#: admin/wp-security-admin-init.php:419 +msgid "User Registration" +msgstr "" + +#: admin/wp-security-admin-init.php:420 +msgid "Database Security" +msgstr "" + +#: admin/wp-security-admin-init.php:424 +msgid "Filesystem Security" +msgstr "" + +#: admin/wp-security-admin-init.php:429 +msgid "Blacklist Manager" +msgstr "" + +#: admin/wp-security-admin-init.php:434 +#: admin/wp-security-firewall-menu.php:60 +msgid "Firewall" +msgstr "" + +#: admin/wp-security-admin-init.php:436 +msgid "Brute Force" +msgstr "" + +#: admin/wp-security-admin-init.php:437 +msgid "Spam Prevention" +msgstr "" + +#: admin/wp-security-admin-init.php:441 +#: admin/wp-security-filescan-menu.php:53 +msgid "Scanner" +msgstr "" + +#: admin/wp-security-admin-init.php:443 +#: admin/wp-security-maintenance-menu.php:51 +msgid "Maintenance" +msgstr "" + +#: admin/wp-security-admin-init.php:444 +#: admin/wp-security-misc-options-menu.php:57 +msgid "Miscellaneous" +msgstr "" + +#: admin/wp-security-admin-init.php:445 +#: admin/wp-security-tools-menu.php:64 +msgid "Tools" +msgstr "" + +#: admin/wp-security-admin-init.php:457 +msgid "Premium Upgrade" +msgstr "" + +#: admin/wp-security-admin-menu.php:67 +msgid "Settings successfully updated." +msgstr "" + +#: admin/wp-security-admin-menu.php:77 +msgid "Successfully deleted the selected record(s)." +msgstr "" + +#: admin/wp-security-admin-menu.php:86 +msgid "Failed to delete the selected record(s)." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:25 +msgid "Ban users" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:51 +msgid "Blacklist manager" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:132 +#: admin/wp-security-firewall-menu.php:1233 +#: admin/wp-security-list-404.php:234 +#: admin/wp-security-list-comment-spammer-ip.php:205 +msgid "The plugin was unable to write to the .htaccess file. Please edit file manually." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:139 +msgid "Ban IPs or user agents" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:142 +msgid "The All In One WP Security Blacklist feature gives you the option of banning certain host IP addresses or ranges and also user agents." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:143 +msgid "This feature will deny total site access for users which have IP addresses or user agents matching those which you have configured in the settings below." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:144 +msgid "The plugin achieves this by making appropriate modifications to your .htaccess file." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:145 +msgid "By blocking people, you are using the most secure first line of defence, which denies all access to blacklisted visitors as soon as they hit your hosting server." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:154 +#: admin/wp-security-firewall-menu.php:1055 +#: templates/may-also-like.php:20 +msgid "All In One WP Security & Firewall Premium" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:155 +#: admin/wp-security-firewall-menu.php:1056 +msgid "You may also be interested in %s." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "This plugin adds a number of extra features including %s and %s." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "smart 404 blocking" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "country IP blocking" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:170 +msgid "IP hosts and user agent blacklist settings" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:182 +#: admin/wp-security-brute-force-menu.php:193 +#: admin/wp-security-brute-force-menu.php:331 +msgid "must read this message" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:183 +#: admin/wp-security-brute-force-menu.php:194 +msgid "This feature can lock you out of admin if it doesn't work correctly on your site. You %s before activating this feature." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:189 +msgid "Enable IP or user agent blacklisting" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:192 +msgid "Check this if you want to enable the banning (or blacklisting) of selected IP addresses and/or user agents specified in the settings below" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:196 +msgid "Enter IP addresses:" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:200 +msgid "Enter one or more IP addresses or IP ranges." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:205 +msgid "Enter user agents:" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:210 +msgid "Enter one or more user agent strings." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:211 +#: admin/wp-security-brute-force-menu.php:374 +#: admin/wp-security-brute-force-menu.php:408 +#: admin/wp-security-brute-force-menu.php:431 +#: admin/wp-security-brute-force-menu.php:452 +#: admin/wp-security-filescan-menu.php:309 +#: admin/wp-security-filescan-menu.php:326 +#: admin/wp-security-firewall-menu.php:175 +#: admin/wp-security-firewall-menu.php:212 +#: admin/wp-security-firewall-menu.php:232 +#: admin/wp-security-firewall-menu.php:258 +#: admin/wp-security-firewall-menu.php:385 +#: admin/wp-security-firewall-menu.php:415 +#: admin/wp-security-firewall-menu.php:446 +#: admin/wp-security-firewall-menu.php:474 +#: admin/wp-security-firewall-menu.php:503 +#: admin/wp-security-firewall-menu.php:681 +#: admin/wp-security-firewall-menu.php:699 +#: admin/wp-security-firewall-menu.php:737 +#: admin/wp-security-firewall-menu.php:868 +#: admin/wp-security-firewall-menu.php:1087 +#: admin/wp-security-firewall-menu.php:1110 +#: admin/wp-security-spam-menu.php:186 +#: admin/wp-security-spam-menu.php:221 +#: admin/wp-security-spam-menu.php:390 +#: admin/wp-security-spam-menu.php:430 +#: admin/wp-security-user-login-menu.php:362 +#: templates/info/ip-address-ip-range-info.php:2 +#: templates/menus/settings/advanced-settings.php:63 +msgid "More info" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:214 +msgid "Each user agent string must be on a new line." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:215 +msgid "Example 1 - A single user agent string to block:" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:217 +msgid "Example 2 - A list of more than 1 user agent strings to block" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:225 +#: admin/wp-security-brute-force-menu.php:213 +#: admin/wp-security-brute-force-menu.php:686 +#: admin/wp-security-brute-force-menu.php:806 +#: admin/wp-security-brute-force-menu.php:868 +#: admin/wp-security-filescan-menu.php:351 +#: admin/wp-security-filesystem-menu.php:242 +#: admin/wp-security-firewall-menu.php:945 +#: admin/wp-security-firewall-menu.php:1129 +#: admin/wp-security-misc-options-menu.php:167 +#: admin/wp-security-misc-options-menu.php:218 +#: admin/wp-security-misc-options-menu.php:278 +#: admin/wp-security-settings-menu.php:619 +#: admin/wp-security-settings-menu.php:680 +#: admin/wp-security-spam-menu.php:233 +#: admin/wp-security-spam-menu.php:407 +#: admin/wp-security-spam-menu.php:526 +#: admin/wp-security-spam-menu.php:588 +#: admin/wp-security-user-login-menu.php:384 +#: admin/wp-security-user-login-menu.php:422 +#: admin/wp-security-user-login-menu.php:601 +#: admin/wp-security-user-login-menu.php:788 +#: admin/wp-security-user-registration-menu.php:150 +#: admin/wp-security-user-registration-menu.php:242 +#: admin/wp-security-user-registration-menu.php:305 +#: templates/menus/settings/advanced-settings.php:217 +msgid "Save settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:33 +#: admin/wp-security-brute-force-menu.php:759 +#: admin/wp-security-dashboard-menu.php:651 +msgid "Rename login page" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:34 +#: admin/wp-security-brute-force-menu.php:154 +msgid "Cookie based brute force prevention" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:35 +#: classes/grade-system/wp-security-feature-item-manager.php:105 +msgid "Login CAPTCHA" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:36 +#: admin/wp-security-brute-force-menu.php:746 +msgid "Login whitelist" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:37 +msgid "Honeypot" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:67 +msgid "Brute force" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:105 +msgid "Please enter a value for your login page slug." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:109 +msgid "You cannot use the value \"wp-admin\" for your login page slug." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:111 +msgid "You must use alpha numeric characters for your login page slug." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:116 +#: admin/wp-security-filescan-menu.php:174 +#: admin/wp-security-firewall-menu.php:151 +#: admin/wp-security-firewall-menu.php:1011 +#: admin/wp-security-spam-menu.php:101 +#: admin/wp-security-spam-menu.php:270 +#: admin/wp-security-spam-menu.php:302 +#: admin/wp-security-user-login-menu.php:184 +#: admin/wp-security-user-login-menu.php:553 +#: templates/partials/non-apache-feature-notice.php:9 +msgid "Attention:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:133 +msgid "Could not delete the Cookie-based directives from the .htaccess file. Please check the file permissions." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:155 +msgid "Login page white list" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:156 +msgid "An effective Brute Force prevention technique is to change the default WordPress login page URL." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:157 +msgid "Normally if you wanted to login to WordPress you would type your site's home URL followed by wp-login.php." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:158 +msgid "This feature allows you to change the login URL by setting your own slug and renaming the last portion of the login URL which contains the wp-login.php to any string that you like." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:159 +msgid "By doing this, malicious bots and hackers will not be able to access your login page because they will not know the correct login page URL." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:161 +msgid "You may also be interested in the following alternative brute force prevention features:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:172 +msgid "Your WordPress login page URL has been renamed." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:173 +msgid "Your current login URL is:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:181 +msgid "Rename login page settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:195 +msgid "NOTE: If you are hosting your site on WPEngine or a provider which performs server caching, you will need to ask the host support people to NOT cache your renamed login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:200 +msgid "Enable rename login page feature" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:203 +msgid "Check this if you want to enable the rename login page feature" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:207 +msgid "Login page URL" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:209 +msgid "Enter a string which will represent your secure login page slug. You are encouraged to choose something which is hard to guess and only you will remember." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:243 +msgid "Settings have not been saved - your secret word must consist only of alphanumeric characters, ie, letters and/or numbers only." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:257 +msgid "You have successfully enabled the cookie based brute force prevention feature" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:258 +msgid "From now on you will need to log into your WP Admin using the following URL:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:260 +msgid "It is important that you save this URL value somewhere in case you forget it, OR," +msgstr "" + +#: admin/wp-security-brute-force-menu.php:261 +msgid "simply remember to add a \"?%s=1\" to your current site URL address." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:265 +msgid "You have successfully saved cookie based brute force prevention feature settings." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:295 +msgid "Brute force prevention firewall settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:300 +msgid "A Brute Force Attack is when a hacker tries many combinations of usernames and passwords until they succeed in guessing the right combination." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:301 +msgid "Due to the fact that at any one time there may be many concurrent login attempts occurring on your site via malicious automated robots, this also has a negative impact on your server's memory and performance." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:302 +msgid "The features in this tab will stop the majority of brute force login attacks thus providing even better protection for your WP login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:307 +#: admin/wp-security-firewall-menu.php:654 +msgid "backup" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:308 +msgid "video tutorial" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:309 +msgid "To learn more about how to use this feature, please watch the following %s." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:310 +#: admin/wp-security-brute-force-menu.php:758 +msgid "Cookie-Based Brute Force Login Prevention" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:320 +#: admin/wp-security-user-login-menu.php:253 +msgid "Cookie based brute force login prevention" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:331 +msgid "This feature can lock you out of admin if it doesn't work correctly on your site. You " +msgstr "" + +#: admin/wp-security-brute-force-menu.php:342 +msgid "The cookie test was successful. You can now enable this feature." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:350 +msgid "The cookie test failed on this server. Consequently, this feature cannot be used on this site." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:357 +msgid "Before using this feature, you must perform a cookie test first." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:359 +msgid "This ensures that your browser cookie is working correctly and that you won't lock yourself out." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:364 +msgid "Perform cookie test" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:370 +#: classes/grade-system/wp-security-feature-item-manager.php:103 +msgid "Enable brute force attack prevention" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:373 +msgid "Check this if you want to protect your login page from Brute Force Attack." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:378 +msgid "This feature will deny access to your WordPress login page for all people except those who have a special cookie in their browser." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:380 +msgid "To use this feature do the following:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:382 +msgid "1) Enable the checkbox." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:384 +msgid "2) Enter a secret word consisting of alphanumeric characters which will be difficult to guess. This secret word will be useful whenever you need to know the special URL which you will use to access the login page (see point below)." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:386 +msgid "3) You will then be provided with a special login URL. You will need to use this URL to login to your WordPress site instead of the usual login URL. NOTE: The system will deposit a special cookie in your browser which will allow you access to the WordPress administration login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:388 +msgid "Any person trying to access your login page who does not have the special cookie in their browser will be automatically blocked." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:395 +msgid "Secret word" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:397 +msgid "Choose a secret word consisting of alphanumeric characters which you can use to access your special URL. Your are highly encouraged to choose a word which will be difficult to guess." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:401 +msgid "Re-direct URL" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:405 +msgid "Specify a URL to redirect a hacker to when they try to access your WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:412 +msgid "The URL specified here can be any site's URL and does not have to be your own. For example you can be as creative as you like and send hackers to the CIA or NSA home page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:414 +msgid "This field will default to: http://127.0.0.1 if you do not enter a value." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:416 +msgid "Useful Tip:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:418 +msgid "It's a good idea to not redirect attempted brute force login attempts to your site because it increases the load on your server." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:420 +msgid "Redirecting a hacker or malicious bot back to \"http://127.0.0.1\" is ideal because it deflects them back to their own local host and puts the load on their server instead of yours." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:427 +msgid "My site has posts or pages which are password protected" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:430 +msgid "Check this if you are using the native WordPress password protection feature for some or all of your blog posts or pages." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:435 +msgid "In the cases where you are protecting some of your posts or pages using the in-built WordPress password protection feature, a few extra lines of directives and exceptions need to be added so that people trying to access pages are not automatically blocked." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:437 +msgid "By enabling this checkbox, the plugin will add the necessary rules and exceptions so that people trying to access these pages are not automatically blocked." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:439 +msgid "Helpful Tip:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:441 +msgid "If you do not use the WordPress password protection feature for your posts or pages then it is highly recommended that you leave this checkbox disabled." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:448 +msgid "My site has a theme or plugins which use AJAX" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:451 +msgid "Check this if your site uses AJAX functionality." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:456 +msgid "In the cases where your WordPress installation has a theme or plugin that uses AJAX, a few extra lines of directives and exceptions need to be added to prevent AJAX requests from being automatically blocked by the brute force prevention feature." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:458 +msgid "By enabling this checkbox, the plugin will add the necessary rules and exceptions so that AJAX operations will work as expected." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:467 +msgid "Save feature settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:525 +msgid "This feature allows you to add a CAPTCHA form on various WordPress login pages and forms." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:526 +msgid "Adding a CAPTCHA form on a login page or form is another effective yet simple \"Brute Force\" prevention technique." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:527 +msgid "You have the option of using either %s or a plain maths CAPTCHA form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:528 +msgid "If you enable Google reCAPTCHA the reCAPTCHA widget will be displayed for all forms the CAPTCHA settings below." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:529 +msgid "If Google reCAPTCHA is disabled the simple maths CAPTCHA form will apply and users will need to enter the answer to a simple mathematical question." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:535 +msgid "Google reCAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:540 +msgid "By enabling these settings the Google reCAPTCHA v2 widget will be applied by default for all forms with CAPTCHA enabled." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:549 +msgid "reCAPTCHA will not work because you have disabled login lockout by activating the AIOS_DISABLE_LOGIN_LOCKOUT constant value in a configuration file." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:550 +msgid "To enable it, define AIOS_DISABLE_LOGIN_LOCKOUT constant value as false, or remove it." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:558 +msgid "Use Google reCAPTCHA as default" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:561 +msgid "Check this if you want to default to Google reCAPTCHA for all settings below. (If this is left unchecked, all CAPTCHA forms will revert to the plain maths CAPTCHA)" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:565 +msgid "Site key" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:571 +msgid "Secret key" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:580 +msgid "Login form CAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:589 +msgid "Enable CAPTCHA on login page" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:592 +msgid "Check this if you want to insert a CAPTCHA form on the login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:598 +msgid "Lost password form CAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:608 +msgid "Enable CAPTCHA on lost password page" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:611 +msgid "Check this if you want to insert a CAPTCHA form on the lost password page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:617 +msgid "Custom login form CAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:626 +msgid "Enable CAPTCHA on custom login form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:629 +msgid "Check this if you want to insert CAPTCHA on a custom login form generated by the following WP function: wp_login_form()" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:639 +msgid "WooCommerce forms CAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:648 +msgid "Enable CAPTCHA on WooCommerce login form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:651 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce login form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:661 +msgid "Enable CAPTCHA on WooCommerce lost password form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:664 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce lost password form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:674 +msgid "Enable CAPTCHA on WooCommerce registration form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:677 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce registration form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:749 +msgid "The All In One WP Security Whitelist feature gives you the option of only allowing certain IP addresses or ranges to have access to your WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:750 +msgid "This feature will deny login access for all IP addresses which are not in your whitelist as configured in the settings below." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:751 +msgid "The plugin achieves this by writing the appropriate directives to your .htaccess file." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:752 +msgid "By allowing/blocking IP addresses, you are using the most secure first line of defence because login access will only be granted to whitelisted IP addresses and other addresses will be blocked as soon as they try to access your login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:760 +msgid "Attention: If in addition to enabling the white list feature, you also have one of the %s or %s features enabled, you will still need to use your secret word or special slug in the URL when trying to access your WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:761 +msgid "These features are NOT functionally related. Having both of them enabled on your site means you are creating 2 layers of security." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:772 +msgid "Login IP whitelist settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:783 +msgid "Enable IP whitelisting" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:786 +#: admin/wp-security-user-login-menu.php:408 +msgid "Check this if you want to enable the whitelisting of selected IP addresses specified in the settings below" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:790 +msgid "Your current IP address" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:793 +msgid "You can copy and paste this address in the text box below if you want to include it in your login whitelist." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:797 +#: admin/wp-security-user-login-menu.php:412 +msgid "Enter whitelisted IP addresses:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:801 +#: admin/wp-security-user-login-menu.php:416 +msgid "Enter one or more IP addresses or IP ranges you wish to include in your whitelist." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:801 +msgid "Only the addresses specified here will have access to the WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:839 +msgid "This feature allows you to add a special hidden \"honeypot\" field on the WordPress login page. This will only be visible to robots and not humans." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:840 +msgid "Since robots usually fill in every input field from a login form, they will also submit a value for the special hidden honeypot field." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:841 +#: admin/wp-security-user-registration-menu.php:278 +msgid "The way honeypots work is that a hidden field is placed somewhere inside a form which only robots will submit. If that field contains a value when the form is submitted then a robot has most likely submitted the form and it is consequently dealt with." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:842 +msgid "Therefore, if the plugin detects that this field has a value when the login form is submitted, then the robot which is attempting to login to your site will be redirected to its localhost address - http://127.0.0.1." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:848 +msgid "Login form honeypot settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:859 +msgid "Enable honeypot on login page" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:862 +msgid "Check this if you want to enable the honeypot feature for the login page" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:27 +#: admin/wp-security-dashboard-menu.php:374 +#: classes/wp-security-user-login.php:74 +msgid "Locked IP addresses" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:28 +msgid "Permanent block list" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:29 +msgid "Logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:33 +msgid "Premium upgrade" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:131 +#: admin/wp-security-dashboard-menu.php:518 +#: admin/wp-security-user-login-menu.php:53 +#: classes/grade-system/wp-security-feature-item-manager.php:49 +msgid "Login lockout" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:132 +msgid "This tab displays the list of all IP addresses which are currently temporarily locked out due to the login lockout feature:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:138 +msgid "Currently locked out IP addresses and ranges" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:183 +msgid "This tab displays the list of all permanently blocked IP addresses." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:184 +#: admin/wp-security-spam-menu.php:339 +msgid "NOTE: This feature does NOT use the .htaccess file to permanently block the IP addresses so it should be compatible with all web servers running WordPress." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:189 +msgid "Permanently blocked IP addresses" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:200 +#: admin/wp-security-firewall-menu.php:1151 +#: admin/wp-security-user-login-menu.php:485 +#: admin/wp-security-user-login-menu.php:643 +#: admin/wp-security-user-registration-menu.php:164 +msgid "Search" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:238 +#: admin/wp-security-dashboard-menu.php:249 +#: admin/wp-security-dashboard-menu.php:260 +msgid "All In One WP Security & Firewall" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:250 +msgid "Debug logs have been cleared." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:261 +msgid "Unable to clear the logs; an invalid nonce was provided" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:274 +msgid "Debug log options" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:281 +msgid "Clear logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:289 +msgid "Debug logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:362 +msgid "Security strength meter" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:363 +msgid "Security points breakdown" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:364 +msgid "Spread the word" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:365 +msgid "Get to know the developers" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:366 +msgid "Critical feature status" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:367 +msgid "Last 5 logins" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:368 +msgid "Maintenance mode status" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:373 +#: admin/wp-security-dashboard-menu.php:664 +#: admin/wp-security-user-login-menu.php:57 +msgid "Logged in users" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:417 +msgid "Total Achievable Points: " +msgstr "" + +#: admin/wp-security-dashboard-menu.php:419 +msgid "Current Score of Your Site: " +msgstr "" + +#: admin/wp-security-dashboard-menu.php:472 +msgid "We are working hard to make your WordPress site more secure. Please support us, here is how:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:473 +msgid "Follow us on" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:477 +msgid "Post to Twitter" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:481 +msgid "Give us a good rating" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:488 +msgid "Wanna know more about the developers behind this plugin?" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:499 +msgid "Below is the current status of the critical features that you should activate on your site to achieve a minimum level of recommended security" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:503 +msgid "Admin username" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:533 +msgid "File permission" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:548 +msgid "Basic firewall" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:577 +msgid "No data found." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:581 +msgid "Last 5 logins summary:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:585 +msgid "User" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:586 +#: admin/wp-security-list-404.php:95 +#: admin/wp-security-list-login-fails.php:56 +#: admin/wp-security-list-permanent-blocked-ip.php:68 +msgid "Date" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:587 +msgid "IP" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:608 +msgid "Maintenance mode is currently enabled. Remember to turn it off when you are done" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:610 +msgid "Maintenance mode is currently off." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:614 +msgid "Maintenance mode" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:632 +msgid "Cookie based brute force" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:636 +#: admin/wp-security-dashboard-menu.php:654 +msgid "The %s feature is currently active." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:637 +#: admin/wp-security-dashboard-menu.php:655 +msgid "Your new WordPress login URL is now:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:666 +msgid "Number of users currently logged into your site (including you) is:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:667 +msgid "There are no other users currently logged in." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:680 +msgid "Number of users currently logged in site-wide (including you) is:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:681 +msgid "There are no other site-wide users currently logged in." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:694 +#: admin/wp-security-dashboard-menu.php:711 +msgid "Go to the %s menu to see more details" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:707 +msgid "There are no IP addresses currently locked out." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:710 +msgid "Number of temporarily locked out IP addresses: " +msgstr "" + +#: admin/wp-security-database-menu.php:52 +msgid "UpdraftPlus is installed but currently not active." +msgstr "" + +#: admin/wp-security-database-menu.php:52 +msgid "Follow this link to activate UpdraftPlus, to take a backup." +msgstr "" + +#: admin/wp-security-database-menu.php:57 +msgid "Follow this link to install UpdraftPlus, to take a database backup." +msgstr "" + +#: admin/wp-security-database-menu.php:87 +#: admin/wp-security-database-menu.php:92 +msgid "Database backup" +msgstr "" + +#: admin/wp-security-database-menu.php:91 +#: classes/grade-system/wp-security-feature-item-manager.php:65 +msgid "Database prefix" +msgstr "" + +#: admin/wp-security-database-menu.php:119 +msgid "Database security" +msgstr "" + +#: admin/wp-security-database-menu.php:147 +msgid "Nonce check failed for DB prefix change operation!" +msgstr "" + +#: admin/wp-security-database-menu.php:155 +msgid "The plugin has detected that it cannot write to the wp-config.php file. This feature can only be used if the plugin can successfully write to the wp-config.php file." +msgstr "" + +#: admin/wp-security-database-menu.php:168 +msgid "Please enter a value for the DB prefix." +msgstr "" + +#: admin/wp-security-database-menu.php:177 +msgid "ERROR: The table prefix can only contain numbers, letters, and underscores." +msgstr "" + +#: admin/wp-security-database-menu.php:186 +#: admin/wp-security-database-menu.php:245 +msgid "Change database prefix" +msgstr "" + +#: admin/wp-security-database-menu.php:189 +msgid "Your WordPress database is the most important asset of your website because it contains a lot of your site's precious information." +msgstr "" + +#: admin/wp-security-database-menu.php:190 +msgid "The database is also a target for hackers via methods such as SQL injections and malicious and automated code which targets certain tables." +msgstr "" + +#: admin/wp-security-database-menu.php:191 +msgid "One way to add a layer of protection for your DB is to change the default WordPress table prefix from \"wp_\" to something else which will be difficult for hackers to guess." +msgstr "" + +#: admin/wp-security-database-menu.php:192 +msgid "This feature allows you to easily change the prefix to a value of your choice or to a random value set by this plugin." +msgstr "" + +#: admin/wp-security-database-menu.php:198 +msgid "Database prefix options" +msgstr "" + +#: admin/wp-security-database-menu.php:210 +msgid "database backup" +msgstr "" + +#: admin/wp-security-database-menu.php:211 +msgid "It is recommended that you perform a %s before using this feature" +msgstr "" + +#: admin/wp-security-database-menu.php:221 +msgid "Current database table prefix" +msgstr "" + +#: admin/wp-security-database-menu.php:227 +msgid "Your site is currently using the default WordPress database prefix value of \"wp_\"." +msgstr "" + +#: admin/wp-security-database-menu.php:227 +msgid "To increase your site's security you should consider changing the database prefix value to another value." +msgstr "" + +#: admin/wp-security-database-menu.php:234 +msgid "Generate new database table prefix" +msgstr "" + +#: admin/wp-security-database-menu.php:238 +msgid "Check this if you want the plugin to generate a random 6 character string for the table prefix" +msgstr "" + +#: admin/wp-security-database-menu.php:239 +msgid "OR" +msgstr "" + +#: admin/wp-security-database-menu.php:241 +msgid "Choose your own database prefix by specifying a string which contains letters and/or numbers and/or underscores. Example: xyz_" +msgstr "" + +#: admin/wp-security-database-menu.php:265 +msgid "Take a database backup using UpdraftPlus" +msgstr "" + +#: admin/wp-security-database-menu.php:270 +msgid "Manual backup" +msgstr "" + +#: admin/wp-security-database-menu.php:274 +msgid "UpdraftPlus Backup/Restore" +msgstr "" + +#: admin/wp-security-database-menu.php:274 +msgid "Your backups are on the UpdraftPlus Backup/Restore admin page." +msgstr "" + +#: admin/wp-security-database-menu.php:276 +msgid "Create database backup now" +msgstr "" + +#: admin/wp-security-database-menu.php:308 +msgid "Error - Could not get tables or no tables found!" +msgstr "" + +#: admin/wp-security-database-menu.php:312 +msgid "Starting DB prefix change operations....." +msgstr "" + +#: admin/wp-security-database-menu.php:314 +msgid "Your WordPress system has a total of %s tables and your new DB prefix will be: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:320 +#: classes/wp-security-utility.php:306 +msgid "Failed to make a backup of the wp-config.php file. This operation will not go ahead." +msgstr "" + +#: admin/wp-security-database-menu.php:324 +msgid "A backup copy of your wp-config.php file was created successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:351 +msgid "%s table name update failed" +msgstr "" + +#: admin/wp-security-database-menu.php:363 +msgid "Please change the prefix manually for the above tables to: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:366 +msgid "%s tables had their prefix updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:387 +msgid "wp-config.php file was updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:390 +msgid "The \"wp-config.php\" file was not able to be modified." +msgstr "" + +#: admin/wp-security-database-menu.php:390 +msgid "Please modify this file manually using your favourite editor and search for variable \"$table_prefix\" and assign the following value to that variable: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:401 +#: admin/wp-security-database-menu.php:420 +msgid "Update of table %s failed: unable to change %s to %s" +msgstr "" + +#: admin/wp-security-database-menu.php:405 +msgid "The options table records which had references to the old DB prefix were updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:424 +msgid "The %s table records which had references to the old DB prefix were updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:452 +msgid "Error updating user_meta table where new meta_key = %s, old meta_key = %s and user_id = %s." +msgstr "" + +#: admin/wp-security-database-menu.php:457 +msgid "The usermeta table records which had references to the old DB prefix were updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:459 +msgid "The database prefix change tasks have been completed." +msgstr "" + +#: admin/wp-security-database-menu.php:503 +msgid "Checking for MySQL tables of type \"view\"....." +msgstr "" + +#: admin/wp-security-database-menu.php:520 +msgid "Update of the following MySQL view definition failed: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:527 +msgid "%s view definitions were updated successfully!" +msgstr "" + +#: admin/wp-security-filescan-menu.php:26 +#: classes/grade-system/wp-security-feature-item-manager.php:127 +msgid "File change detection" +msgstr "" + +#: admin/wp-security-filescan-menu.php:27 +msgid "Malware scan" +msgstr "" + +#: admin/wp-security-filescan-menu.php:88 +msgid "There have been no file changes since the last scan." +msgstr "" + +#: admin/wp-security-filescan-menu.php:98 +msgid "Nonce check failed for manual file change detection scan operation!" +msgstr "" + +#: admin/wp-security-filescan-menu.php:104 +msgid "There was an error during the file change detection scan. Please check the AIOS logs." +msgstr "" + +#: admin/wp-security-filescan-menu.php:110 +msgid "The plugin has detected that this is your first file change detection scan. The file details from this scan will be used to detect file changes for future scans." +msgstr "" + +#: admin/wp-security-filescan-menu.php:112 +msgid "Scan complete - There were no file changes detected!" +msgstr "" + +#: admin/wp-security-filescan-menu.php:133 +msgid "You entered a non numeric value for the \"backup time interval\" field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-filescan-menu.php:167 +msgid "The following address was removed because it is not a valid email address: " +msgstr "" + +#: admin/wp-security-filescan-menu.php:206 +msgid "NEW SCAN COMPLETED: The plugin has detected that you have made changes to the \"File Types To Ignore\" or \"Files To Ignore\" fields." +msgstr "" + +#: admin/wp-security-filescan-menu.php:206 +msgid "In order to ensure that future scan results are accurate, the old scan data has been refreshed." +msgstr "" + +#: admin/wp-security-filescan-menu.php:215 +msgid "All In One WP Security & Firewall has detected that there was a change in your host's files." +msgstr "" + +#: admin/wp-security-filescan-menu.php:217 +msgid "View scan details and clear this message" +msgstr "" + +#: admin/wp-security-filescan-menu.php:226 +msgid "If given an opportunity hackers can insert their code or files into your system which they can then use to carry out malicious acts on your site." +msgstr "" + +#: admin/wp-security-filescan-menu.php:227 +msgid "Being informed of any changes in your files can be a good way to quickly prevent a hacker from causing damage to your website." +msgstr "" + +#: admin/wp-security-filescan-menu.php:228 +msgid "In general, WordPress core and plugin files and file types such as \".php\" or \".js\" should not change often and when they do, it is important that you are made aware when a change occurs and which file was affected." +msgstr "" + +#: admin/wp-security-filescan-menu.php:229 +msgid "The \"File Change Detection Feature\" will notify you of any file change which occurs on your system, including the addition and deletion of files by performing a regular automated or manual scan of your system's files." +msgstr "" + +#: admin/wp-security-filescan-menu.php:230 +msgid "This feature also allows you to exclude certain files or folders from the scan in cases where you know that they change often as part of their normal operation. (For example log files and certain caching plugin files may change often and hence you may choose to exclude such files from the file change detection scan)" +msgstr "" + +#: admin/wp-security-filescan-menu.php:241 +msgid "It appears that your server is using an old PHP version which is missing the %s. The file scanner feature needs this class in order to work. If you would like to use this feature please upgrade your server PHP version to 5.3 or greater." +msgstr "" + +#: admin/wp-security-filescan-menu.php:249 +msgid "Manual file change detection scan" +msgstr "" + +#: admin/wp-security-filescan-menu.php:255 +msgid "To perform a manual file change detection scan click on the button below." +msgstr "" + +#: admin/wp-security-filescan-menu.php:258 +msgid "Perform scan now" +msgstr "" + +#: admin/wp-security-filescan-menu.php:262 +msgid "View last saved file change results" +msgstr "" + +#: admin/wp-security-filescan-menu.php:268 +msgid "Click the button below to view the saved file change results from the last scan." +msgstr "" + +#: admin/wp-security-filescan-menu.php:271 +msgid "View last file change" +msgstr "" + +#: admin/wp-security-filescan-menu.php:275 +msgid "File change detection settings" +msgstr "" + +#: admin/wp-security-filescan-menu.php:287 +msgid "Enable automated file change detection scan" +msgstr "" + +#: admin/wp-security-filescan-menu.php:290 +msgid "Check this if you want the system to automatically/periodically scan your files to check for file changes based on the settings below" +msgstr "" + +#: admin/wp-security-filescan-menu.php:294 +msgid "Scan time interval" +msgstr "" + +#: admin/wp-security-filescan-menu.php:297 +msgid "Hours" +msgstr "" + +#: admin/wp-security-filescan-menu.php:298 +msgid "Days" +msgstr "" + +#: admin/wp-security-filescan-menu.php:299 +msgid "Weeks" +msgstr "" + +#: admin/wp-security-filescan-menu.php:301 +msgid "Set the value for how often you would like a scan to occur" +msgstr "" + +#: admin/wp-security-filescan-menu.php:305 +msgid "File types to ignore" +msgstr "" + +#: admin/wp-security-filescan-menu.php:308 +msgid "Enter each file type or extension on a new line which you wish to exclude from the file change detection scan." +msgstr "" + +#: admin/wp-security-filescan-menu.php:312 +msgid "You can exclude file types from the scan which would not normally pose any security threat if they were changed. These can include things such as image files." +msgstr "" + +#: admin/wp-security-filescan-menu.php:313 +msgid "Example: If you want the scanner to ignore files of type jpg, png, and bmp, then you would enter the following:" +msgstr "" + +#: admin/wp-security-filescan-menu.php:314 +msgid "jpg" +msgstr "" + +#: admin/wp-security-filescan-menu.php:315 +msgid "png" +msgstr "" + +#: admin/wp-security-filescan-menu.php:316 +msgid "bmp" +msgstr "" + +#: admin/wp-security-filescan-menu.php:322 +msgid "Files/Directories to ignore" +msgstr "" + +#: admin/wp-security-filescan-menu.php:325 +msgid "Enter each file or directory on a new line which you wish to exclude from the file change detection scan." +msgstr "" + +#: admin/wp-security-filescan-menu.php:329 +msgid "You can exclude specific files/directories from the scan which would not normally pose any security threat if they were changed. These can include things such as log files." +msgstr "" + +#: admin/wp-security-filescan-menu.php:330 +msgid "Example: If you want the scanner to ignore certain files in different directories or whole directories, then you would enter the following:" +msgstr "" + +#: admin/wp-security-filescan-menu.php:331 +msgid "cache/config/master.php" +msgstr "" + +#: admin/wp-security-filescan-menu.php:332 +msgid "somedirectory" +msgstr "" + +#: admin/wp-security-filescan-menu.php:339 +msgid "Send email when change detected" +msgstr "" + +#: admin/wp-security-filescan-menu.php:343 +msgid "Check this if you want the system to email you if a file change was detected" +msgstr "" + +#: admin/wp-security-filescan-menu.php:347 +msgid "Enter one or more email addresses on a new line." +msgstr "" + +#: admin/wp-security-filescan-menu.php:364 +msgid "What is malware?" +msgstr "" + +#: admin/wp-security-filescan-menu.php:365 +msgid "The word malware stands for Malicious Software. It can consist of things like trojan horses, adware, worms, spyware and any other undesirable code which a hacker will try to inject into your website." +msgstr "" + +#: admin/wp-security-filescan-menu.php:366 +msgid "Often when malware code has been inserted into your site you will normally not notice anything out of the ordinary based on appearances, but it can have a dramatic effect on your site's search ranking." +msgstr "" + +#: admin/wp-security-filescan-menu.php:367 +msgid "This is because the bots and spiders from search engines such as Google have the capability to detect malware when they are indexing the pages on your site, and consequently they can blacklist your website which will in turn affect your search rankings." +msgstr "" + +#: admin/wp-security-filescan-menu.php:369 +msgid "CLICK HERE" +msgstr "" + +#: admin/wp-security-filescan-menu.php:371 +msgid "Scanning for malware" +msgstr "" + +#: admin/wp-security-filescan-menu.php:372 +msgid "Due to the constantly changing and complex nature of Malware, scanning for such things using a standalone plugin will not work reliably. This is something best done via an external scan of your site regularly." +msgstr "" + +#: admin/wp-security-filescan-menu.php:373 +msgid "This is why we have created an easy-to-use scanning service which is hosted off our own server which will scan your site for malware once every day and notify you if it finds anything." +msgstr "" + +#: admin/wp-security-filescan-menu.php:374 +msgid "When you sign up for this service you will get the following:" +msgstr "" + +#: admin/wp-security-filescan-menu.php:376 +msgid "Automatic daily scan of 1 website" +msgstr "" + +#: admin/wp-security-filescan-menu.php:377 +msgid "Automatic malware and blacklist monitoring" +msgstr "" + +#: admin/wp-security-filescan-menu.php:378 +msgid "Automatic email alerting" +msgstr "" + +#: admin/wp-security-filescan-menu.php:379 +msgid "Site uptime monitoring" +msgstr "" + +#: admin/wp-security-filescan-menu.php:380 +msgid "Site response time monitoring" +msgstr "" + +#: admin/wp-security-filescan-menu.php:381 +msgid "We provide advice for malware cleanup" +msgstr "" + +#: admin/wp-security-filescan-menu.php:382 +msgid "Blacklist removal" +msgstr "" + +#: admin/wp-security-filescan-menu.php:383 +msgid "No contract (cancel anytime)" +msgstr "" + +#: admin/wp-security-filescan-menu.php:385 +msgid "To learn more please %s." +msgstr "" + +#: admin/wp-security-filescan-menu.php:406 +msgid "Latest file change scan results" +msgstr "" + +#: admin/wp-security-filescan-menu.php:416 +msgid "The following files were added to your host." +msgstr "" + +#: admin/wp-security-filescan-menu.php:419 +#: admin/wp-security-filescan-menu.php:440 +#: admin/wp-security-filescan-menu.php:464 +msgid "File" +msgstr "" + +#: admin/wp-security-filescan-menu.php:420 +#: admin/wp-security-filescan-menu.php:441 +#: admin/wp-security-filescan-menu.php:465 +msgid "File size" +msgstr "" + +#: admin/wp-security-filescan-menu.php:421 +#: admin/wp-security-filescan-menu.php:442 +#: admin/wp-security-filescan-menu.php:466 +msgid "File modified" +msgstr "" + +#: admin/wp-security-filescan-menu.php:437 +msgid "The following files were removed from your host." +msgstr "" + +#: admin/wp-security-filescan-menu.php:461 +msgid "The following files were changed on your host." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:26 +#: classes/grade-system/wp-security-feature-item-manager.php:69 +msgid "File permissions" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:27 +msgid "PHP file editing" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:28 +msgid "WP file access" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:29 +msgid "Host system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:55 +msgid "Filesystem security" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:80 +msgid "Nonce check failed for manual DB backup operation!" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:90 +msgid "The permissions for %s were successfully changed to %s" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:94 +msgid "Unable to change permissions for %s!" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:100 +msgid "File permissions scan" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:103 +msgid "Your WordPress file and folder permission settings govern the accessibility and read/write privileges of the files and folders which make up your WP installation." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:104 +msgid "Your WP installation already comes with reasonably secure file permission settings for the filesystem." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:105 +msgid "However, sometimes people or other plugins modify the various permission settings of certain core WP folders or files such that they end up making their site less secure because they chose the wrong permission values." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:106 +msgid "This feature will scan the critical WP core folders and files and will highlight any permission settings which are insecure." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:114 +msgid "This plugin has detected that your site is running on a Windows server." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:115 +msgid "This feature is not applicable for Windows server installations." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:121 +msgid "WP directory and file permissions scan results" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:133 +#: admin/wp-security-filesystem-menu.php:152 +msgid "Name" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:134 +#: admin/wp-security-filesystem-menu.php:153 +msgid "File/Folder" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:135 +#: admin/wp-security-filesystem-menu.php:154 +msgid "Current permissions" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:136 +#: admin/wp-security-filesystem-menu.php:155 +msgid "Recommended permissions" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:137 +#: admin/wp-security-filesystem-menu.php:156 +msgid "Recommended action" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:195 +msgid "Your PHP file editing settings were saved successfully." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:199 +msgid "Operation failed! Unable to modify or make a backup of wp-config.php file!" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:212 +#: classes/grade-system/wp-security-feature-item-manager.php:71 +msgid "File editing" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:215 +msgid "The WordPress Dashboard by default allows administrators to edit PHP files, such as plugin and theme files." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:216 +msgid "This is often the first tool an attacker will use if able to login, since it allows code execution." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:217 +msgid "This feature will disable the ability for people to edit PHP files via the dashboard." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:223 +msgid "Disable PHP file editing" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:235 +msgid "Disable ability to edit PHP files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:238 +msgid "Check this if you want to remove the ability for people to edit PHP files via the WP dashboard" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:282 +msgid "You have successfully saved the Prevent Access to Default WP Files configuration." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:286 +#: admin/wp-security-firewall-menu.php:126 +#: admin/wp-security-firewall-menu.php:346 +#: admin/wp-security-firewall-menu.php:613 +#: admin/wp-security-firewall-menu.php:912 +#: admin/wp-security-settings-menu.php:772 +#: admin/wp-security-spam-menu.php:124 +msgid "Could not write to the .htaccess file. Please check the file permissions." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:291 +msgid "WordPress files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:294 +msgid "This feature allows you to prevent access to files such as %s, %s and %s which are delivered with all WP installations." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:295 +msgid "By preventing access to these files you are hiding some key pieces of information (such as WordPress version info) from potential hackers." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:300 +msgid "Prevent access to default WP files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:311 +msgid "Prevent access to WP default install files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:314 +msgid "Check this if you want to prevent access to readme.html, license.txt and wp-config-sample.php." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:318 +msgid "Save setting" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:342 +msgid "System logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:345 +msgid "Sometimes your hosting platform will produce error or warning logs in a file called \"error_log\"." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:346 +msgid "Depending on the nature and cause of the error or warning, your hosting server can create multiple instances of this file in numerous directory locations of your WordPress installation." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:347 +msgid "By occasionally viewing the contents of these logs files you can keep informed of any underlying problems on your system which you might need to address." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:353 +msgid "View system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:355 +msgid "Please click the button below to view the latest system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:358 +msgid "Enter System Log File Name" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:360 +msgid "Enter your system log file name. (Defaults to error_log)" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:363 +msgid "View latest system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:365 +msgid "Loading..." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:382 +msgid "No system logs were found." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:435 +msgid "Set recommended permissions" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:441 +msgid "No action required" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:481 +msgid "Showing latest entries of error_log file: %s" +msgstr "" + +#: admin/wp-security-firewall-menu.php:28 +msgid "Basic firewall rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:29 +msgid "Additional firewall rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:30 +msgid "6G Blacklist firewall rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:31 +msgid "Internet bots" +msgstr "" + +#: admin/wp-security-firewall-menu.php:32 +msgid "Prevent hotlinks" +msgstr "" + +#: admin/wp-security-firewall-menu.php:33 +msgid "404 detection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:34 +msgid "Custom rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:122 +#: admin/wp-security-firewall-menu.php:908 +#: admin/wp-security-spam-menu.php:120 +#: admin/wp-security-spam-menu.php:494 +#: admin/wp-security-spam-menu.php:556 +#: admin/wp-security-user-registration-menu.php:95 +msgid "Settings were successfully saved" +msgstr "" + +#: admin/wp-security-firewall-menu.php:131 +#: admin/wp-security-firewall-menu.php:651 +msgid "Firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:138 +msgid "This should not have any impact on your site's general functionality but if you wish you can take a %s of your .htaccess file before proceeding." +msgstr "" + +#: admin/wp-security-firewall-menu.php:139 +msgid "The features in this tab allow you to activate some basic firewall security protection rules for your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:140 +msgid "The firewall functionality is achieved via the insertion of special code into your currently active .htaccess file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:151 +msgid "You have enabled the \"Completely Block Access To XMLRPC\" checkbox which means all XMLRPC functionality will be blocked." +msgstr "" + +#: admin/wp-security-firewall-menu.php:152 +msgid "By leaving this feature enabled you will prevent Jetpack or Wordpress iOS or other apps which need XMLRPC from working correctly on your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:153 +msgid "If you still need XMLRPC then uncheck the \"Completely Block Access To XMLRPC\" checkbox and enable only the \"Disable Pingback Functionality From XMLRPC\" checkbox." +msgstr "" + +#: admin/wp-security-firewall-menu.php:163 +msgid "Basic firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:171 +msgid "Enable basic firewall protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:174 +msgid "Check this if you want to apply basic firewall protection to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:178 +msgid "This setting will implement the following basic firewall protection mechanisms on your site:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:179 +msgid "1) Protect your htaccess file by denying access to it." +msgstr "" + +#: admin/wp-security-firewall-menu.php:180 +msgid "2) Disable the server signature." +msgstr "" + +#: admin/wp-security-firewall-menu.php:181 +msgid "3) Limit file upload size (%sMB)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:182 +msgid "4) Protect your wp-config.php file by denying access to it." +msgstr "" + +#: admin/wp-security-firewall-menu.php:183 +msgid "The above firewall features will be applied via your .htaccess file and should not affect your site's overall functionality." +msgstr "" + +#: admin/wp-security-firewall-menu.php:184 +msgid "You are still advised to take a backup of your active .htaccess file just in case." +msgstr "" + +#: admin/wp-security-firewall-menu.php:190 +msgid "Max file upload size (MB)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:192 +msgid "The value for the maximum file upload size used in the .htaccess file. (Defaults to %sMB if left blank)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:200 +msgid "WordPress XMLRPC and pingback vulnerability protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:208 +msgid "Completely block access to XMLRPC" +msgstr "" + +#: admin/wp-security-firewall-menu.php:211 +msgid "Check this if you are not using the WP XML-RPC functionality and you want to completely block external access to XMLRPC." +msgstr "" + +#: admin/wp-security-firewall-menu.php:215 +msgid "This setting will add a directive in your .htaccess to disable access to the WordPress xmlrpc.php file which is responsible for the XML-RPC functionality in WordPress." +msgstr "" + +#: admin/wp-security-firewall-menu.php:216 +msgid "Hackers can exploit various vulnerabilities in the WordPress XML-RPC API in a number of ways such as:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:217 +msgid "1) Denial of Service (DoS) attacks" +msgstr "" + +#: admin/wp-security-firewall-menu.php:218 +msgid "2) Hacking internal routers." +msgstr "" + +#: admin/wp-security-firewall-menu.php:219 +msgid "3) Scanning ports in internal networks to get info from various hosts." +msgstr "" + +#: admin/wp-security-firewall-menu.php:220 +msgid "Apart from the security protection benefit, this feature may also help reduce load on your server, particularly if your site currently has a lot of unwanted traffic hitting the XML-RPC API on your installation." +msgstr "" + +#: admin/wp-security-firewall-menu.php:221 +msgid "NOTE: You should only enable this feature if you are not currently using the XML-RPC functionality on your WordPress installation." +msgstr "" + +#: admin/wp-security-firewall-menu.php:222 +msgid "Leave this feature disabled and use the feature below if you want pingback protection but you still need XMLRPC." +msgstr "" + +#: admin/wp-security-firewall-menu.php:228 +msgid "Disable pingback functionality from XMLRPC" +msgstr "" + +#: admin/wp-security-firewall-menu.php:231 +msgid "If you use Jetpack or WP iOS or other apps which need WP XML-RPC functionality then check this. This will enable protection against WordPress pingback vulnerabilities." +msgstr "" + +#: admin/wp-security-firewall-menu.php:235 +msgid "NOTE: If you use Jetpack or the Wordpress iOS or other apps then you should enable this feature but leave the \"Completely Block Access To XMLRPC\" checkbox unchecked." +msgstr "" + +#: admin/wp-security-firewall-menu.php:236 +msgid "The feature will still allow XMLRPC functionality on your site but will disable the pingback methods." +msgstr "" + +#: admin/wp-security-firewall-menu.php:237 +msgid "This feature will also remove the \"X-Pingback\" header if it is present." +msgstr "" + +#: admin/wp-security-firewall-menu.php:246 +msgid "Block access to debug log file" +msgstr "" + +#: admin/wp-security-firewall-menu.php:254 +msgid "Block access to debug.log file" +msgstr "" + +#: admin/wp-security-firewall-menu.php:257 +msgid "Check this if you want to block access to the debug.log file that WordPress creates when debug logging is enabled." +msgstr "" + +#: admin/wp-security-firewall-menu.php:261 +msgid "WordPress has an option to turn on the debug logging to a file located in wp-content/debug.log. This file may contain sensitive information." +msgstr "" + +#: admin/wp-security-firewall-menu.php:262 +msgid "Using this option will block external access to this file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:262 +msgid "You can still access this file by logging into your site via FTP." +msgstr "" + +#: admin/wp-security-firewall-menu.php:270 +msgid "Save basic firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:342 +msgid "You have successfully saved the Additional Firewall Protection configuration" +msgstr "" + +#: admin/wp-security-firewall-menu.php:356 +msgid "Additional firewall protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:360 +msgid "Due to the nature of the code being inserted to the .htaccess file, this feature may break some functionality for certain plugins and you are therefore advised to take a %s of .htaccess before applying this configuration." +msgstr "" + +#: admin/wp-security-firewall-menu.php:362 +msgid "This feature allows you to activate more advanced firewall settings to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:363 +msgid "The advanced firewall rules are applied via the insertion of special code to your currently active .htaccess file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:372 +msgid "Listing of directory contents" +msgstr "" + +#: admin/wp-security-firewall-menu.php:381 +#: classes/grade-system/wp-security-feature-item-manager.php:85 +msgid "Disable index views" +msgstr "" + +#: admin/wp-security-firewall-menu.php:384 +msgid "Check this if you want to disable directory and file listing." +msgstr "" + +#: admin/wp-security-firewall-menu.php:389 +msgid "By default, an Apache server will allow the listing of the contents of a directory if it doesn't contain an index.php file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:391 +msgid "This feature will prevent the listing of contents for all directories." +msgstr "" + +#: admin/wp-security-firewall-menu.php:393 +msgid "NOTE: In order for this feature to work \"AllowOverride\" of the Indexes directive must be enabled in your httpd.conf file. Ask your hosting provider to check this if you don't have access to httpd.conf" +msgstr "" + +#: admin/wp-security-firewall-menu.php:402 +msgid "Trace and track" +msgstr "" + +#: admin/wp-security-firewall-menu.php:411 +#: classes/grade-system/wp-security-feature-item-manager.php:86 +msgid "Disable trace and track" +msgstr "" + +#: admin/wp-security-firewall-menu.php:414 +msgid "Check this if you want to disable trace and track." +msgstr "" + +#: admin/wp-security-firewall-menu.php:419 +msgid "HTTP Trace attack (XST) can be used to return header requests and grab cookies and other information." +msgstr "" + +#: admin/wp-security-firewall-menu.php:421 +msgid "This hacking technique is usually used together with cross site scripting attacks (XSS)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:423 +msgid "Disabling trace and track on your site will help prevent HTTP Trace attacks." +msgstr "" + +#: admin/wp-security-firewall-menu.php:432 +msgid "Proxy comment posting" +msgstr "" + +#: admin/wp-security-firewall-menu.php:442 +msgid "Forbid proxy comment posting" +msgstr "" + +#: admin/wp-security-firewall-menu.php:445 +msgid "Check this if you want to forbid proxy comment posting." +msgstr "" + +#: admin/wp-security-firewall-menu.php:450 +msgid "This setting will deny any requests that use a proxy server when posting comments." +msgstr "" + +#: admin/wp-security-firewall-menu.php:451 +msgid "By forbidding proxy comments you are in effect eliminating some spam and other proxy requests." +msgstr "" + +#: admin/wp-security-firewall-menu.php:460 +msgid "Bad query strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:470 +msgid "Deny bad query strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:473 +msgid "This will help protect you against malicious queries via XSS." +msgstr "" + +#: admin/wp-security-firewall-menu.php:478 +msgid "This feature will write rules in your .htaccess file to prevent malicious string attacks on your site using XSS." +msgstr "" + +#: admin/wp-security-firewall-menu.php:479 +msgid "NOTE: Some of these strings might be used for plugins or themes and hence this might break some functionality." +msgstr "" + +#: admin/wp-security-firewall-menu.php:480 +#: admin/wp-security-firewall-menu.php:510 +msgid "You are therefore strongly advised to take a backup of your active .htaccess file before applying this feature." +msgstr "" + +#: admin/wp-security-firewall-menu.php:489 +#: classes/grade-system/wp-security-feature-item-manager.php:89 +msgid "Advanced character string filter" +msgstr "" + +#: admin/wp-security-firewall-menu.php:499 +msgid "Enable advanced character string filter" +msgstr "" + +#: admin/wp-security-firewall-menu.php:502 +msgid "This will block bad character matches from XSS." +msgstr "" + +#: admin/wp-security-firewall-menu.php:507 +msgid "This is an advanced character string filter to prevent malicious string attacks on your site coming from Cross Site Scripting (XSS)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:508 +msgid "This setting matches for common malicious string patterns and exploits and will produce a 403 error for the hacker attempting the query." +msgstr "" + +#: admin/wp-security-firewall-menu.php:509 +msgid "NOTE: Some strings for this setting might break some functionality." +msgstr "" + +#: admin/wp-security-firewall-menu.php:518 +msgid "Save additional firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:609 +msgid "You have successfully saved the 5G/6G Firewall Protection configuration" +msgstr "" + +#: admin/wp-security-firewall-menu.php:633 +msgid "All in One WP Security and Firewall" +msgstr "" + +#: admin/wp-security-firewall-menu.php:634 +msgid "We were unable to access the firewall's configuration file:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:636 +msgid "As a result, the firewall will be unavailable." +msgstr "" + +#: admin/wp-security-firewall-menu.php:637 +msgid "Please check your PHP error log for further information." +msgstr "" + +#: admin/wp-security-firewall-menu.php:638 +msgid "If you're unable to locate your PHP log file, please contact your web hosting company to ask them where it can be found on their setup." +msgstr "" + +#: admin/wp-security-firewall-menu.php:655 +msgid "This feature allows you to activate the %s (or legacy %s) firewall security protection rules designed and produced by %s." +msgstr "" + +#: admin/wp-security-firewall-menu.php:656 +msgid "The 6G Blacklist is updated and improved version of 5G Blacklist. If you have 5G Blacklist active, you might consider activating 6G Blacklist instead." +msgstr "" + +#: admin/wp-security-firewall-menu.php:657 +msgid "The 6G Blacklist is a simple, flexible blacklist that helps reduce the number of malicious URL requests that hit your website." +msgstr "" + +#: admin/wp-security-firewall-menu.php:658 +msgid "The added advantage of applying the 6G firewall to your site is that it has been tested and confirmed by the people at PerishablePress.com to be an optimal and least disruptive set of .htaccess security rules for general WP sites running on an Apache server or similar." +msgstr "" + +#: admin/wp-security-firewall-menu.php:659 +msgid "Therefore the 6G firewall rules should not have any impact on your site's general functionality but if you wish you can take a %s of your .htaccess file before proceeding." +msgstr "" + +#: admin/wp-security-firewall-menu.php:665 +msgid "6G blacklist/firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:677 +msgid "Enable 6G firewall protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:680 +msgid "Check this if you want to apply the 6G Blacklist firewall protection from perishablepress.com to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:684 +msgid "This setting will implement the 6G security firewall protection mechanisms on your site which include the following things:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:685 +#: admin/wp-security-firewall-menu.php:703 +msgid "1) Block forbidden characters commonly used in exploitative attacks." +msgstr "" + +#: admin/wp-security-firewall-menu.php:686 +#: admin/wp-security-firewall-menu.php:704 +msgid "2) Block malicious encoded URL characters such as the \".css(\" string." +msgstr "" + +#: admin/wp-security-firewall-menu.php:687 +#: admin/wp-security-firewall-menu.php:705 +msgid "3) Guard against the common patterns and specific exploits in the root portion of targeted URLs." +msgstr "" + +#: admin/wp-security-firewall-menu.php:688 +#: admin/wp-security-firewall-menu.php:706 +msgid "4) Stop attackers from manipulating query strings by disallowing illicit characters." +msgstr "" + +#: admin/wp-security-firewall-menu.php:689 +#: admin/wp-security-firewall-menu.php:707 +msgid "....and much more." +msgstr "" + +#: admin/wp-security-firewall-menu.php:695 +msgid "Enable legacy 5G firewall protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:698 +msgid "Check this if you want to apply the 5G Blacklist firewall protection from perishablepress.com to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:702 +msgid "This setting will implement the 5G security firewall protection mechanisms on your site which include the following things:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:713 +msgid "Save 5G/6G firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:721 +msgid "6G block request methods" +msgstr "" + +#: admin/wp-security-firewall-menu.php:725 +msgid "HTTP Request methods are used by browsers and clients to communicate with servers to get responses." +msgstr "" + +#: admin/wp-security-firewall-menu.php:726 +msgid "GET and POST are the most commonly used methods to request and submit data for specified resources of the server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:732 +msgid "Block %s method" +msgstr "" + +#: admin/wp-security-firewall-menu.php:735 +msgid "Check this to block the %s request method" +msgstr "" + +#: admin/wp-security-firewall-menu.php:740 +msgid "Some WooCommerce extensions use the PUT request method in addition to GET and POST." +msgstr "" + +#: admin/wp-security-firewall-menu.php:740 +msgid "This means WooCommerce users shouldn't block the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:741 +msgid "A few REST requests use the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:741 +msgid "If your site is communicated by the WP REST API, you should not block the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:749 +msgid "Save request methods settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:757 +msgid "6G other settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:761 +msgid "Block query strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:764 +msgid "Check this to block all query strings recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:768 +msgid "Block request strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:771 +msgid "Check this to block all request strings recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:775 +msgid "Block referrers" +msgstr "" + +#: admin/wp-security-firewall-menu.php:778 +msgid "Check this to block all referrers recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:782 +msgid "Block user-agents" +msgstr "" + +#: admin/wp-security-firewall-menu.php:785 +msgid "Check this to block all user-agents recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:789 +msgid "Save other settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:823 +msgid "The Internet bot settings were successfully saved" +msgstr "" + +#: admin/wp-security-firewall-menu.php:827 +msgid "Internet bot settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:833 +msgid "What is an Internet Bot" +msgstr "" + +#: admin/wp-security-firewall-menu.php:834 +msgid "%s?" +msgstr "" + +#: admin/wp-security-firewall-menu.php:836 +msgid "A bot is a piece of software which runs on the Internet and performs automatic tasks. For example when Google indexes your pages it uses automatic bots to achieve this task." +msgstr "" + +#: admin/wp-security-firewall-menu.php:837 +msgid "A lot of bots are legitimate and non-malicious but not all bots are good and often you will find some which try to impersonate legitimate bots such as \"Googlebot\" but in reality they have nohing to do with Google at all." +msgstr "" + +#: admin/wp-security-firewall-menu.php:838 +msgid "Although most of the bots out there are relatively harmless sometimes website owners want to have more control over which bots they allow into their site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:839 +msgid "This feature allows you to block bots which are impersonating as a Googlebot but actually aren't. (In other words they are fake Google bots)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:840 +msgid "Googlebots have a unique identity which cannot easily be forged and this feature will identify any fake Google bots and block them from reading your site's pages." +msgstr "" + +#: admin/wp-security-firewall-menu.php:846 +msgid "Attention: Sometimes non-malicious Internet organizations might have bots which impersonate as a \"Googlebot\"." +msgstr "" + +#: admin/wp-security-firewall-menu.php:847 +msgid "Just be aware that if you activate this feature the plugin will block all bots which use the \"Googlebot\" string in their User Agent information but are NOT officially from Google (irrespective whether they are malicious or not)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:848 +msgid "All other bots from other organizations such as \"Yahoo\", \"Bing\" etc will not be affected by this feature." +msgstr "" + +#: admin/wp-security-firewall-menu.php:854 +#: admin/wp-security-firewall-menu.php:864 +#: classes/grade-system/wp-security-feature-item-manager.php:93 +msgid "Block fake Googlebots" +msgstr "" + +#: admin/wp-security-firewall-menu.php:867 +msgid "Check this if you want to block all fake Googlebots." +msgstr "" + +#: admin/wp-security-firewall-menu.php:871 +msgid "This feature will check if the User Agent information of a bot contains the string \"Googlebot\"." +msgstr "" + +#: admin/wp-security-firewall-menu.php:872 +msgid "It will then perform a few tests to verify if the bot is legitimately from Google and if so it will allow the bot to proceed." +msgstr "" + +#: admin/wp-security-firewall-menu.php:873 +msgid "If the bot fails the checks then the plugin will mark it as being a fake Googlebot and it will block it" +msgstr "" + +#: admin/wp-security-firewall-menu.php:880 +msgid "Save internet bot settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:916 +#: admin/wp-security-firewall-menu.php:938 +#: classes/grade-system/wp-security-feature-item-manager.php:95 +msgid "Prevent image hotlinking" +msgstr "" + +#: admin/wp-security-firewall-menu.php:919 +msgid "A Hotlink is where someone displays an image on their site which is actually located on your site by using a direct link to the source of the image on your server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:920 +msgid "Due to the fact that the image being displayed on the other person's site is coming from your server, this can cause leaking of bandwidth and resources for you because your server has to present this image for the people viewing it on someone elses's site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:921 +msgid "This feature will prevent people from directly hotlinking images from your site's pages by writing some directives in your .htaccess file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:926 +msgid "Prevent hotlinking" +msgstr "" + +#: admin/wp-security-firewall-menu.php:941 +msgid "Check this if you want to prevent hotlinking to images on your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:961 +msgid "Nonce check failed for delete all 404 event logs operation!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:972 +msgid "404 Detection Feature - Delete all 404 event logs operation failed!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:976 +msgid "All 404 event logs were deleted from the DB successfully!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1000 +msgid "You entered a non numeric value for the lockout time length field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1006 +msgid "You entered an incorrect format for the \"Redirect URL\" field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1039 +msgid "404 detection configuration" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1042 +msgid "A 404 or Not Found error occurs when somebody tries to access a non-existent page on your website." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1043 +msgid "Typically, most 404 errors happen quite innocently when people have mis-typed a URL or used an old link to page which doesn't exist anymore." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1044 +msgid "However, in some cases you may find many repeated 404 errors which occur in a relatively short space of time and from the same IP address which are all attempting to access a variety of non-existent page URLs." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1045 +msgid "Such behaviour can mean that a hacker might be trying to find a particular page or URL for sinister reasons." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1046 +msgid "This feature allows you to monitor all 404 events which occur on your site, and it also gives you the option of blocking IP addresses for a configured length of time." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1047 +msgid "If you want to temporarily block or blacklist an IP address, simply click the \"Temp Block\" or \"Blacklist IP\" link for the applicable IP entry in the \"404 Event Logs\" table below." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1071 +msgid "404 detection options" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1083 +msgid "Enable 404 IP detection and lockout" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1086 +msgid "Check this if you want to enable the lockout of selected IP addresses." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1091 +msgid "When you enable this checkbox, all 404 events on your site will be logged in the table below. You can monitor these events and select some IP addresses listed in the table below and block them for a specified amount of time. All IP addresses you select to be blocked from the \"404 Event Logs\" table section will be unable to access your site during the time specified." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1099 +msgid "Enable 404 event logging" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1102 +msgid "Check this if you want to enable the logging of 404 events" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1107 +msgid "Time length of 404 lockout (minutes)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1109 +msgid "Set the length of time for which a blocked IP address will be prevented from visiting your site" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1114 +msgid "You can lock any IP address which is recorded in the \"404 Event Logs\" table section below." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1116 +msgid "To temporarily lock an IP address, hover over the ID column and click the \"Temp Block\" link for the applicable IP entry." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1123 +msgid "404 lockout redirect URL" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1125 +msgid "A blocked visitor will be automatically redirected to this URL." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1135 +msgid "This list displays the 404 event logs when somebody tries to access a non-existent page on your website." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1136 +msgid "404 event logs that are older than %1$d days are purged automatically." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1141 +msgid "404 event logs" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1163 +#: admin/wp-security-firewall-menu.php:1172 +#: admin/wp-security-user-login-menu.php:495 +#: admin/wp-security-user-login-menu.php:504 +#: admin/wp-security-user-login-menu.php:653 +#: admin/wp-security-user-login-menu.php:662 +msgid "Export to CSV" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1169 +#: admin/wp-security-user-login-menu.php:501 +#: admin/wp-security-user-login-menu.php:659 +msgid "Click this button if you wish to download this log in CSV format." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1176 +#: admin/wp-security-firewall-menu.php:1185 +msgid "Delete all 404 event logs" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1182 +msgid "Click this button if you wish to purge all 404 event logs from the DB." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1241 +msgid "Custom .htaccess rules settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1248 +msgid "This feature can be used to apply your own custom .htaccess rules and directives." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1249 +msgid "It is useful for when you want to tweak our existing firewall rules or when you want to add your own." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1250 +msgid "NOTE: This feature can only be used if your site is hosted in an apache or similar web server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1256 +msgid "Warning: Only use this feature if you know what you are doing." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1257 +msgid "Incorrect .htaccess rules or directives can break or prevent access to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1258 +msgid "It is your responsibility to ensure that you are entering the correct code!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1259 +msgid "If you break your site you will need to access your server via FTP or something similar and then edit your .htaccess file and delete the changes you made." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1265 +msgid "Custom .htaccess rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1269 +msgid "Enable custom .htaccess rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1272 +msgid "Check this if you want to enable custom rules entered in the text box below" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1276 +msgid "Place custom rules at the top" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1279 +msgid "Check this if you want to place your custom rules at the beginning of all the rules applied by this plugin" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1283 +msgid "Enter custom .htaccess rules:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1287 +msgid "Enter your custom .htaccess rules/directives." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1292 +msgid "Save custom rules" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:338 +#: admin/wp-security-firewall-setup-notice.php:407 +#: admin/wp-security-firewall-setup-notice.php:479 +#: admin/wp-security-firewall-setup-notice.php:595 +#: wp-security.php:43 +msgid "All In One WP Security and Firewall" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:340 +msgid "We were unable to create the file necessary to give you the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:341 +msgid "Your firewall will have reduced protection which means some of your firewall's functionality will be unavailable." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:342 +msgid "If you would like to manually set up the necessary file, please follow these steps:" +msgstr "" + +#. translators: %s Bootstrap file name. +#. translators: %s Firewall file name. +#: admin/wp-security-firewall-setup-notice.php:346 +#: admin/wp-security-firewall-setup-notice.php:453 +msgid "1. Create a file with the name %s in the same directory as your WordPress install is in, i.e.:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:350 +msgid "2. Paste in the following code:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:352 +#: admin/wp-security-firewall-setup-notice.php:462 +msgid "3. Save the file and press the 'Try again' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:372 +msgid "1. Open the following file:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:378 +msgid "2. Look for the auto_prepend_file directive." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:382 +msgid "2. Look for the following:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:388 +msgid "3. Change it to the following:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:392 +msgid "4. Save the file and press the 'Try again' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:392 +#: admin/wp-security-firewall-setup-notice.php:441 +msgid "You may have to wait up to 5 minutes before the settings take effect." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:410 +msgid "Your firewall has been installed with the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:411 +msgid "You may have to wait 5 minutes for the changes to take effect." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:434 +msgid "1. Open your php.ini file." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:437 +msgid "2. Set the auto_prepend_file directive like below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:441 +msgid "3. Restart the webserver and refresh the page" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:458 +msgid "2. Paste in the following directives:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:482 +msgid "We were unable to set up your firewall with the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:483 +msgid "Your firewall will have reduced functionality." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:487 +msgid "To give your site the highest level of protection, please follow these steps:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:500 +msgid "Note: if you're unable to perform any of the aforementioned steps, please ask your web hosting provider for further assistance." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:517 +msgid "Try again" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:539 +msgid "We have detected that your AIOS firewall is not fully installed, and therefore does not have the highest level of protection. " +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:540 +msgid "Your firewall will have reduced functionality until it has been upgraded. " +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:542 +msgid "Upgrade your protection now" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:598 +msgid "Our PHP-based firewall has been created to give you even greater protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:602 +msgid "If you already have our .htaccess-based firewall enabled, you will still need to set up the PHP-based firewall to benefit from its protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:605 +msgid "To set up the PHP-based firewall, press the 'Set up now' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:608 +msgid "Set up now" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:614 +#: templates/notices/custom-notice.php:10 +#: templates/notices/custom-notice.php:12 +#: templates/notices/horizontal-notice.php:50 +#: templates/notices/horizontal-notice.php:52 +#: templates/notices/htaccess-to-php-feature-notice.php:10 +#: templates/notices/htaccess-to-php-feature-notice.php:12 +msgid "Dismiss" +msgstr "" + +#: admin/wp-security-list-404.php:91 +msgid "Event type" +msgstr "" + +#: admin/wp-security-list-404.php:92 +#: admin/wp-security-list-logged-in-users.php:46 +#: admin/wp-security-list-registered-users.php:74 +msgid "IP address" +msgstr "" + +#: admin/wp-security-list-404.php:93 +msgid "Attempted URL" +msgstr "" + +#: admin/wp-security-list-404.php:94 +msgid "Referer" +msgstr "" + +#: admin/wp-security-list-404.php:96 +msgid "Lock status" +msgstr "" + +#: admin/wp-security-list-404.php:118 +msgid "Temp block IP" +msgstr "" + +#: admin/wp-security-list-404.php:119 +msgid "Blacklist IP" +msgstr "" + +#: admin/wp-security-list-404.php:120 +#: admin/wp-security-list-acct-activity.php:82 +#: admin/wp-security-list-locked-ip.php:37 +#: admin/wp-security-list-locked-ip.php:84 +#: admin/wp-security-list-login-fails.php:73 +#: admin/wp-security-list-registered-users.php:93 +msgid "Delete" +msgstr "" + +#: admin/wp-security-list-404.php:128 +#: admin/wp-security-list-404.php:136 +#: admin/wp-security-list-404.php:143 +#: admin/wp-security-list-acct-activity.php:92 +#: admin/wp-security-list-comment-spammer-ip.php:95 +#: admin/wp-security-list-locked-ip.php:97 +#: admin/wp-security-list-locked-ip.php:105 +#: admin/wp-security-list-login-fails.php:85 +#: admin/wp-security-list-permanent-blocked-ip.php:96 +#: admin/wp-security-list-registered-users.php:107 +#: admin/wp-security-list-registered-users.php:115 +#: admin/wp-security-list-registered-users.php:123 +msgid "Please select some records using the checkboxes" +msgstr "" + +#: admin/wp-security-list-404.php:278 +msgid "Nonce check failed for delete selected 404 event logs operation!" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:35 +msgid "Are you sure you want to delete this item?" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:46 +msgid "Login session still active" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:60 +#: admin/wp-security-list-locked-ip.php:60 +#: admin/wp-security-list-logged-in-users.php:44 +#: admin/wp-security-list-login-fails.php:54 +#: admin/wp-security-list-registered-users.php:69 +msgid "User ID" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:61 +#: admin/wp-security-list-locked-ip.php:61 +#: admin/wp-security-list-login-fails.php:55 +msgid "Username" +msgstr "Användarnamn" + +#: admin/wp-security-list-acct-activity.php:62 +msgid "Login date" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:63 +msgid "Logout date" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:136 +msgid "Nonce check failed for delete selected account activity logs operation!" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:59 +msgid "Spammer IP" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:60 +msgid "Number of spam comments from this IP" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:61 +msgid "Status" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:81 +msgid "Block" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:130 +#: admin/wp-security-list-comment-spammer-ip.php:179 +msgid "Nonce check failed for delete selected blocked IP operation!" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:137 +msgid "The selected IP addresses are now permanently blocked!" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:193 +msgid "The selected IP addresses were saved in the blacklist configuration settings." +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:201 +msgid "The .htaccess file was successfully modified to include the selected IP addresses." +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:212 +msgid "NOTE: The .htaccess file was not modified because you have disabled the \"Enable IP or User Agent Blacklisting\" check box." +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:213 +msgid "To block these IP addresses you will need to enable the above flag in the %s menu" +msgstr "" + +#: admin/wp-security-list-debug.php:47 +msgid "Level" +msgstr "" + +#: admin/wp-security-list-debug.php:48 +msgid "Message" +msgstr "" + +#: admin/wp-security-list-debug.php:49 +msgid "Type" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:36 +#: admin/wp-security-list-locked-ip.php:83 +msgid "Unlock" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:59 +msgid "Locked IP/range" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:62 +#: admin/wp-security-list-permanent-blocked-ip.php:67 +msgid "Reason" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:63 +msgid "Date locked" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:64 +msgid "Release date" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:134 +msgid "The selected IP entries were unlocked successfully." +msgstr "" + +#: admin/wp-security-list-locked-ip.php:140 +msgid "Nonce check failed for unlock IP operation!" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:147 +msgid "The selected IP entry was unlocked successfully." +msgstr "" + +#: admin/wp-security-list-logged-in-users.php:45 +#: admin/wp-security-list-registered-users.php:70 +msgid "Login name" +msgstr "" + +#: admin/wp-security-list-logged-in-users.php:87 +msgid "Nonce check failed for force user logout operation!" +msgstr "" + +#: admin/wp-security-list-logged-in-users.php:96 +msgid "The selected user was logged out successfully!" +msgstr "" + +#: admin/wp-security-list-login-fails.php:53 +msgid "Login IP range" +msgstr "" + +#: admin/wp-security-list-login-fails.php:130 +msgid "Nonce check failed for delete failed login record operation!" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:66 +msgid "Blocked IP" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:87 +msgid "Unblock" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:122 +#: admin/wp-security-list-permanent-blocked-ip.php:139 +msgid "Successfully unblocked and deleted the selected record(s)." +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:126 +#: admin/wp-security-list-permanent-blocked-ip.php:143 +msgid "Failed to unblock and delete the selected record(s)." +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:133 +msgid "Nonce check failed for unblock IP operation!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:71 +msgid "Email" +msgstr "" + +#: admin/wp-security-list-registered-users.php:72 +msgid "Register date" +msgstr "" + +#: admin/wp-security-list-registered-users.php:73 +msgid "Account status" +msgstr "" + +#: admin/wp-security-list-registered-users.php:92 +msgid "Approve" +msgstr "" + +#: admin/wp-security-list-registered-users.php:94 +msgid "Block IP" +msgstr "" + +#: admin/wp-security-list-registered-users.php:159 +msgid "The selected accounts were approved successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:163 +msgid "The following accounts failed to update successfully: " +msgstr "" + +#: admin/wp-security-list-registered-users.php:171 +msgid "The selected account was approved successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:190 +msgid "Your account is now active" +msgstr "" + +#: admin/wp-security-list-registered-users.php:191 +msgid "Your account with username: " +msgstr "" + +#: admin/wp-security-list-registered-users.php:191 +msgid " is now active" +msgstr "" + +#: admin/wp-security-list-registered-users.php:222 +msgid "The selected accounts were deleted successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:230 +msgid "Nonce check failed for delete registered user account operation!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:238 +msgid "The selected account was deleted successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:264 +msgid "The selected IP addresses were successfully added to the permanent block list!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:265 +#: admin/wp-security-list-registered-users.php:282 +msgid "View Blocked IPs" +msgstr "" + +#: admin/wp-security-list-registered-users.php:274 +msgid "Nonce check failed for block IP operation of registered user!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:281 +msgid "The selected IP was successfully added to the permanent block list!" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:25 +msgid "Visitor lockout" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:85 +msgid "Site lockout feature settings saved!" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:92 +msgid "General visitor lockout" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:98 +msgid "This feature allows you to put your site into \"maintenance mode\" by locking down the front-end to all visitors except logged in users with super admin privileges." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:99 +msgid "Locking your site down to general visitors can be useful if you are investigating some issues on your site or perhaps you might be doing some maintenance and wish to keep out all traffic for security reasons." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:104 +msgid "Enable front-end lockout" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:107 +msgid "Check this if you want all visitors except those who are logged in as administrator to be locked out of the front-end of your site." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:111 +msgid "Enter a message:" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:123 +msgid "Enter a message you wish to display to visitors when your site is in maintenance mode." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:130 +msgid "Save site lockout settings" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:28 +msgid "Copy protection" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:29 +msgid "Frames" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:30 +msgid "Users enumeration" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:31 +msgid "WP REST API" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:89 +msgid "Copy Protection feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:94 +msgid "Disable the ability to copy text" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:100 +msgid "This feature allows you to disable the ability to select and copy text from your front end." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:101 +msgid "When admin user is logged in, the feature is automatically disabled for his session." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:106 +msgid "Enable copy protection" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:109 +msgid "Check this if you want to disable the \"Right click\", \"Text selection\" and \"Copy\" option on the front end of your site." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:116 +msgid "Save copy protection settings" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:140 +msgid "Frame Display Prevention feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:145 +msgid "Prevent your site from being displayed in a frame" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:151 +msgid "This feature allows you to prevent other sites from displaying any of your content via a frame or iframe." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:152 +msgid "When enabled, this feature will set the \"X-Frame-Options\" parameter to \"sameorigin\" in the HTTP header." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:157 +msgid "Enable iFrame protection" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:160 +msgid "Check this if you want to stop other sites from displaying your content in a frame or iframe." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:191 +msgid "Users Enumeration Prevention feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:196 +msgid "Prevent users enumeration" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:202 +msgid "This feature allows you to prevent external users/bots from fetching the user info with urls like \"/?author=1\"." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:203 +msgid "When enabled, this feature will print a \"forbidden\" error rather than the user information." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:208 +msgid "Disable users enumeration" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:211 +msgid "Check this if you want to stop users enumeration." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:242 +msgid "WP REST API Security feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:253 +msgid "This feature allows you to block WordPress REST API access for unauthorized requests." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:254 +msgid "When enabled this feature will only allow REST requests to be processed if the user is logged in." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:260 +msgid "Beware that if you are using other plugins which have registered REST endpoints (eg, Contact Form 7), then this feature will also block REST requests used by these plugins if the user is not logged in. It is recommended that you leave this feature disabled if you want uninterrupted functionality for such plugins." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:268 +msgid "Disallow unauthorized REST requests" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:271 +msgid "Check this if you want to stop REST API access for non-logged in requests." +msgstr "" + +#: admin/wp-security-settings-menu.php:25 +msgid "General settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:29 +#: admin/wp-security-settings-menu.php:33 +msgid "file" +msgstr "" + +#: admin/wp-security-settings-menu.php:37 +msgid "Delete plugin settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:41 +msgid "WP version info" +msgstr "" + +#: admin/wp-security-settings-menu.php:45 +msgid "Import/Export" +msgstr "" + +#: admin/wp-security-settings-menu.php:52 +msgid "Advanced settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:128 +msgid "All the security features have been disabled successfully!" +msgstr "" + +#: admin/wp-security-settings-menu.php:132 +#: admin/wp-security-settings-menu.php:159 +msgid "Could not write to the .htaccess file. Please restore your .htaccess file manually using the restore functionality in the \".htaccess File\"." +msgstr "" + +#: admin/wp-security-settings-menu.php:137 +msgid "Could not write to the wp-config.php. Please restore your wp-config.php file manually using the restore functionality in the \"wp-config.php File\"." +msgstr "" + +#: admin/wp-security-settings-menu.php:155 +msgid "All firewall rules have been disabled successfully!" +msgstr "" + +#: admin/wp-security-settings-menu.php:177 +msgid "Deletion of aio_wp_security_configs option and .htaccess directives failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:179 +msgid "Reset of aio_wp_security_configs option failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:181 +msgid "Deletion of .htaccess directives failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:183 +msgid "All settings have been successfully reset." +msgstr "" + +#: admin/wp-security-settings-menu.php:203 +msgid "For information, updates and documentation, please visit the" +msgstr "" + +#: admin/wp-security-settings-menu.php:203 +msgid "Page" +msgstr "" + +#: admin/wp-security-settings-menu.php:204 +msgid "Follow us" +msgstr "" + +#: admin/wp-security-settings-menu.php:204 +msgid "on Twitter, Google+ or via Email to stay up to date about the new security features of this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:208 +msgid "WP Security plugin" +msgstr "" + +#: admin/wp-security-settings-menu.php:212 +msgid "Thank you for using the AIOS security plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:216 +msgid "There are a lot of security features in this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:221 +msgid "To start, go through each security option and enable the \"basic\" options." +msgstr "" + +#: admin/wp-security-settings-menu.php:225 +msgid "The more features you enable, the more security points you will achieve." +msgstr "" + +#: admin/wp-security-settings-menu.php:228 +msgid "Before doing anything we advise taking a backup of your .htaccess file, database and wp-config.php." +msgstr "" + +#: admin/wp-security-settings-menu.php:231 +msgid "Backup your database" +msgstr "" + +#: admin/wp-security-settings-menu.php:232 +#: admin/wp-security-settings-menu.php:433 +msgid "Backup .htaccess file" +msgstr "" + +#: admin/wp-security-settings-menu.php:233 +#: admin/wp-security-settings-menu.php:534 +msgid "Backup wp-config.php file" +msgstr "" + +#: admin/wp-security-settings-menu.php:240 +msgid "Disable security features" +msgstr "" + +#: admin/wp-security-settings-menu.php:246 +msgid "If you think that some plugin functionality on your site is broken due to a security feature you enabled in this plugin, then use the following option to turn off all the security features of this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:250 +msgid "Disable all security features" +msgstr "" + +#: admin/wp-security-settings-menu.php:257 +#: admin/wp-security-settings-menu.php:267 +msgid "Disable all firewall rules" +msgstr "" + +#: admin/wp-security-settings-menu.php:263 +msgid "This feature will disable all firewall rules which are currently active in this plugin and it will also delete these rules from your .htacess file. Use it if you think one of the firewall rules is causing an issue on your site." +msgstr "" + +#: admin/wp-security-settings-menu.php:274 +#: admin/wp-security-settings-menu.php:287 +msgid "Reset settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:279 +msgid "This button click will delete all of your settings related to the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:280 +msgid "This button click will reset/empty all the database tables of the security plugin also." +msgstr "" + +#: admin/wp-security-settings-menu.php:281 +msgid "Use this plugin if you were locked out by the All In One WP Security & Firewall Plugin and/or you are having issues logging in when that plugin is activated." +msgstr "" + +#: admin/wp-security-settings-menu.php:282 +msgid "In addition to the settings it will also delete any directives which were added to the .htaccess file by the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:283 +msgid "%1$sNOTE: %2$sAfter deleting the settings you will need to re-configure the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:295 +msgid "Debug settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:301 +msgid "This setting allows you to enable/disable debug for this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:307 +msgid "Enable debug" +msgstr "" + +#: admin/wp-security-settings-menu.php:310 +msgid "Check this if you want to enable debug. You should keep this option disabled after you have finished debugging the issue." +msgstr "" + +#: admin/wp-security-settings-menu.php:314 +msgid "Save debug settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:350 +msgid "Your .htaccess file was successfully backed up! Using an FTP program go to the \"/wp-content/aiowps_backups\" directory to save a copy of the file to your computer." +msgstr "" + +#: admin/wp-security-settings-menu.php:356 +msgid "htaccess file rename failed during backup. Please check your root directory for the backup file using FTP." +msgstr "" + +#: admin/wp-security-settings-menu.php:362 +msgid "htaccess backup failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:377 +msgid "Please choose a .htaccess to restore from." +msgstr "" + +#: admin/wp-security-settings-menu.php:392 +msgid "htaccess file restore failed. Please attempt to restore the .htaccess manually using FTP." +msgstr "" + +#: admin/wp-security-settings-menu.php:396 +msgid "Your .htaccess file has successfully been restored!" +msgstr "" + +#: admin/wp-security-settings-menu.php:402 +msgid "htaccess Restore operation failed! Please check the contents of the file you are trying to restore from." +msgstr "" + +#: admin/wp-security-settings-menu.php:408 +msgid ".htaccess file operations" +msgstr "" + +#: admin/wp-security-settings-menu.php:411 +msgid "Your \".htaccess\" file is a key component of your website's security and it can be modified to implement various levels of protection mechanisms." +msgstr "" + +#: admin/wp-security-settings-menu.php:412 +msgid "This feature allows you to backup and save your currently active .htaccess file should you need to re-use the the backed up file in the future." +msgstr "" + +#: admin/wp-security-settings-menu.php:413 +msgid "You can also restore your site's .htaccess settings using a backed up .htaccess file." +msgstr "" + +#: admin/wp-security-settings-menu.php:428 +msgid "Save the current .htaccess file" +msgstr "" + +#: admin/wp-security-settings-menu.php:432 +msgid "Click the button below to backup and save the currently active .htaccess file." +msgstr "" + +#: admin/wp-security-settings-menu.php:437 +msgid "Restore from a backed up .htaccess file" +msgstr "" + +#: admin/wp-security-settings-menu.php:443 +msgid ".htaccess file to restore from" +msgstr "" + +#: admin/wp-security-settings-menu.php:445 +msgid "Select Your htaccess File" +msgstr "" + +#: admin/wp-security-settings-menu.php:449 +msgid "After selecting your file, click the button below to restore your site using the backed up htaccess file (htaccess_backup.txt)." +msgstr "" + +#: admin/wp-security-settings-menu.php:455 +msgid "Restore .htaccess file" +msgstr "" + +#: admin/wp-security-settings-menu.php:477 +msgid "Please choose a wp-config.php file to restore from." +msgstr "" + +#: admin/wp-security-settings-menu.php:493 +msgid "wp-config.php file restore failed. Please attempt to restore this file manually using FTP." +msgstr "" + +#: admin/wp-security-settings-menu.php:497 +msgid "Your wp-config.php file has successfully been restored!" +msgstr "" + +#: admin/wp-security-settings-menu.php:503 +msgid "wp-config.php Restore operation failed! Please check the contents of the file you are trying to restore from." +msgstr "" + +#: admin/wp-security-settings-menu.php:509 +msgid "wp-config.php file operations" +msgstr "" + +#: admin/wp-security-settings-menu.php:512 +msgid "Your \"wp-config.php\" file is one of the most important in your WordPress installation. It is a primary configuration file and contains crucial things such as details of your database and other critical components." +msgstr "" + +#: admin/wp-security-settings-menu.php:513 +msgid "This feature allows you to backup and save your currently active wp-config.php file should you need to re-use the the backed up file in the future." +msgstr "" + +#: admin/wp-security-settings-menu.php:514 +msgid "You can also restore your site's wp-config.php settings using a backed up wp-config.php file." +msgstr "" + +#: admin/wp-security-settings-menu.php:529 +msgid "Save the current wp-config.php file" +msgstr "" + +#: admin/wp-security-settings-menu.php:533 +msgid "Click the button below to backup and download the contents of the currently active wp-config.php file." +msgstr "" + +#: admin/wp-security-settings-menu.php:539 +msgid "Restore from a backed up wp-config file" +msgstr "" + +#: admin/wp-security-settings-menu.php:545 +msgid "wp-config file to restore from" +msgstr "" + +#: admin/wp-security-settings-menu.php:547 +msgid "Select Your wp-config File" +msgstr "" + +#: admin/wp-security-settings-menu.php:551 +msgid "After selecting your file click the button below to restore your site using the backed up wp-config file (wp-config.php.backup.txt)." +msgstr "" + +#: admin/wp-security-settings-menu.php:557 +msgid "Restore wp-config file" +msgstr "" + +#: admin/wp-security-settings-menu.php:591 +msgid "Manage delete plugin settings saved." +msgstr "" + +#: admin/wp-security-settings-menu.php:596 +msgid "Manage delete plugin tasks" +msgstr "" + +#: admin/wp-security-settings-menu.php:603 +msgid "Delete database tables" +msgstr "" + +#: admin/wp-security-settings-menu.php:606 +msgid "Check this if you want to remove database tables when the plugin is uninstalled." +msgstr "" + +#: admin/wp-security-settings-menu.php:610 +msgid "Delete settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:613 +msgid "Check this if you want to remove all plugin settings when uninstalling the plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:613 +msgid "It will also remove all custom htaccess rules that were added by this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:647 +msgid "WP generator meta tag and version info" +msgstr "" + +#: admin/wp-security-settings-menu.php:650 +msgid "WordPress generator automatically adds some meta information inside the \"head\" tags of every page on your site's front end. Below is an example of this:" +msgstr "" + +#: admin/wp-security-settings-menu.php:652 +msgid "The above meta information shows which version of WordPress your site is currently running and thus can help hackers or crawlers scan your site to see if you have an older version of WordPress or one with a known exploit." +msgstr "" + +#: admin/wp-security-settings-menu.php:653 +msgid "There are also other ways wordpress reveals version info such as during style and script loading. An example of this is:" +msgstr "" + +#: admin/wp-security-settings-menu.php:655 +msgid "This feature will allow you to remove the WP generator meta info and other version info from your site's pages." +msgstr "" + +#: admin/wp-security-settings-menu.php:661 +msgid "WP generator meta info" +msgstr "" + +#: admin/wp-security-settings-menu.php:673 +msgid "Remove WP generator meta info" +msgstr "" + +#: admin/wp-security-settings-menu.php:676 +msgid "Check this if you want to remove the version and meta info produced by WP from all pages" +msgstr "" + +#: admin/wp-security-settings-menu.php:704 +msgid "Please choose a file to import your settings from." +msgstr "" + +#: admin/wp-security-settings-menu.php:736 +msgid "Import AIOS settings from " +msgstr "" + +#: admin/wp-security-settings-menu.php:742 +#: admin/wp-security-settings-menu.php:786 +msgid "The deletion of the import file failed. Please delete this file manually via the media menu for security purposes." +msgstr "" + +#: admin/wp-security-settings-menu.php:744 +#: admin/wp-security-settings-menu.php:788 +msgid "The file you uploaded was also deleted for security purposes because it contains security settings details." +msgstr "" + +#: admin/wp-security-settings-menu.php:759 +msgid "Your AIOS settings were successfully imported via file input." +msgstr "" + +#: admin/wp-security-settings-menu.php:760 +msgid "The deletion of the import file failed. Please delete this file manually via the media menu for security purposes because it contains security settings details." +msgstr "" + +#: admin/wp-security-settings-menu.php:762 +msgid "Your AIOS settings were successfully imported. The file you uploaded was also deleted for security purposes because it contains security settings details." +msgstr "" + +#: admin/wp-security-settings-menu.php:765 +msgid "Your AIOS settings were successfully imported via text entry." +msgstr "" + +#: admin/wp-security-settings-menu.php:780 +msgid "The contents of your settings file appear invalid. Please check the contents of the file you are trying to import settings from." +msgstr "" + +#: admin/wp-security-settings-menu.php:797 +msgid "Export or import your AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:800 +msgid "This section allows you to export or import your All In One WP Security & Firewall settings." +msgstr "" + +#: admin/wp-security-settings-menu.php:801 +msgid "This can be handy if you wanted to save time by applying the settings from one site to another site." +msgstr "" + +#: admin/wp-security-settings-menu.php:802 +msgid "NOTE: Before importing, it is your responsibility to know what settings you are trying to import. Importing settings blindly can cause you to be locked out of your site." +msgstr "" + +#: admin/wp-security-settings-menu.php:803 +msgid "For Example: If a settings item relies on the domain URL then it may not work correctly when imported into a site with a different domain." +msgstr "" + +#: admin/wp-security-settings-menu.php:809 +#: admin/wp-security-settings-menu.php:818 +msgid "Export AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:815 +msgid "To export your All In One WP Security & Firewall settings click the button below." +msgstr "" + +#: admin/wp-security-settings-menu.php:822 +#: admin/wp-security-settings-menu.php:851 +msgid "Import AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:828 +msgid "Use this section to import your All In One WP Security & Firewall settings from a file. Alternatively, copy/paste the contents of your import file into the textarea below." +msgstr "" + +#: admin/wp-security-settings-menu.php:830 +msgid "Import file" +msgstr "" + +#: admin/wp-security-settings-menu.php:833 +msgid "Select Your Import Settings File" +msgstr "" + +#: admin/wp-security-settings-menu.php:837 +msgid "After selecting your file, click the button below to apply the settings to your site." +msgstr "" + +#: admin/wp-security-settings-menu.php:844 +msgid "Copy/Paste import data" +msgstr "" + +#: admin/wp-security-settings-menu.php:893 +msgid "Default - if correct, then this is the best option" +msgstr "" + +#: admin/wp-security-settings-menu.php:894 +msgid "Only use if you're using Cloudflare." +msgstr "" + +#: admin/wp-security-settings-menu.php:902 +msgid "(current value: %s)" +msgstr "" + +#: admin/wp-security-settings-menu.php:905 +msgid "no value (i.e. empty) on your server" +msgstr "" + +#: admin/wp-security-spam-menu.php:28 +msgid "Comment spam" +msgstr "" + +#: admin/wp-security-spam-menu.php:29 +msgid "Comment spam IP monitoring" +msgstr "" + +#: admin/wp-security-spam-menu.php:30 +msgid "BuddyPress" +msgstr "" + +#: admin/wp-security-spam-menu.php:31 +msgid "bbPress" +msgstr "" + +#: admin/wp-security-spam-menu.php:57 +msgid "Spam prevention" +msgstr "" + +#: admin/wp-security-spam-menu.php:99 +msgid "You entered a non numeric value for the \"move spam comments to trash after number of days\" field." +msgstr "" + +#: admin/wp-security-spam-menu.php:99 +#: admin/wp-security-spam-menu.php:297 +#: admin/wp-security-user-login-menu.php:118 +#: admin/wp-security-user-login-menu.php:124 +#: admin/wp-security-user-login-menu.php:130 +#: admin/wp-security-user-login-menu.php:136 +msgid "It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:129 +msgid "Comment spam settings" +msgstr "" + +#: admin/wp-security-spam-menu.php:134 +msgid "Add CAPTCHA to comments form" +msgstr "" + +#: admin/wp-security-spam-menu.php:138 +msgid "This feature will add a CAPTCHA field in the WordPress comments form." +msgstr "" + +#: admin/wp-security-spam-menu.php:139 +msgid "Adding a CAPTCHA field in the comment form is a simple way of greatly reducing spam comments from bots without using .htaccess rules." +msgstr "" + +#: admin/wp-security-spam-menu.php:148 +msgid "Enable CAPTCHA on comment forms" +msgstr "" + +#: admin/wp-security-spam-menu.php:151 +msgid "Check this if you want to insert a CAPTCHA field on the comment forms." +msgstr "" + +#: admin/wp-security-spam-menu.php:158 +msgid "Block spambot comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:162 +msgid "A large portion of WordPress blog comment spam is mainly produced by automated bots and not necessarily by humans." +msgstr "" + +#: admin/wp-security-spam-menu.php:163 +msgid "This feature will greatly minimize the useless and unnecessary traffic and load on your server resulting from spam comments by blocking all comment requests which do not originate from your domain." +msgstr "" + +#: admin/wp-security-spam-menu.php:164 +msgid "In other words, if the comment was not submitted by a human who physically submitted the comment on your site, the request will be blocked." +msgstr "" + +#: admin/wp-security-spam-menu.php:182 +msgid "Block spambots from posting comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:185 +msgid "Check this if you want to apply a firewall rule which will block comments originating from spambots." +msgstr "" + +#: admin/wp-security-spam-menu.php:189 +msgid "This feature will implement a firewall rule to block all comment attempts which do not originate from your domain." +msgstr "" + +#: admin/wp-security-spam-menu.php:190 +msgid "A legitimate comment is one which is submitted by a human who physically fills out the comment form and clicks the submit button. For such events, the HTTP_REFERRER is always set to your own domain." +msgstr "" + +#: admin/wp-security-spam-menu.php:191 +msgid "A comment submitted by a spambot is done by directly calling the comments.php file, which usually means that the HTTP_REFERRER value is not your domain and often times empty." +msgstr "" + +#: admin/wp-security-spam-menu.php:192 +msgid "This feature will check and block comment requests which are not referred by your domain thus greatly reducing your overall blog spam and PHP requests done by the server to process these comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:202 +msgid "Comment processing" +msgstr "" + +#: admin/wp-security-spam-menu.php:207 +msgid "Trash spam comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:216 +msgid "Move spam comments to trash after %s days." +msgstr "" + +#: admin/wp-security-spam-menu.php:224 +msgid "Enable this feature in order to move the spam comments to trash after given number of days." +msgstr "" + +#: admin/wp-security-spam-menu.php:262 +msgid "You entered a non numeric value for the minimum number of spam comments field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:265 +msgid "You must enter an integer greater than zero for minimum number of spam comments field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:292 +msgid "Nonce check failed for list spam comment IPs." +msgstr "" + +#: admin/wp-security-spam-menu.php:297 +msgid "You entered a non numeric value for the minimum spam comments per IP field." +msgstr "" + +#: admin/wp-security-spam-menu.php:308 +msgid "Displaying results for IP addresses which have posted a minimum of %s spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:323 +msgid "Auto block spammer IPs" +msgstr "" + +#: admin/wp-security-spam-menu.php:328 +msgid "This feature has detected that %s is not active. It is highly recommended that you activate the Akismet plugin to make the most of this feature." +msgstr "" + +#: admin/wp-security-spam-menu.php:337 +msgid "This feature allows you to automatically and permanently block IP addresses which have exceeded a certain number of comments labelled as spam." +msgstr "" + +#: admin/wp-security-spam-menu.php:338 +msgid "Comments are usually labelled as spam either by the Akismet plugin or manually by the WP administrator when they mark a comment as \"spam\" from the WordPress Comments menu." +msgstr "" + +#: admin/wp-security-spam-menu.php:352 +msgid "You currently have no IP addresses permanently blocked due to spam." +msgstr "" + +#: admin/wp-security-spam-menu.php:365 +msgid "Spammer IPs added to permanent block list today: " +msgstr "" + +#: admin/wp-security-spam-menu.php:366 +msgid "All time total: " +msgstr "" + +#: admin/wp-security-spam-menu.php:367 +msgid "View blocked IPs" +msgstr "" + +#: admin/wp-security-spam-menu.php:380 +msgid "Enable auto block of spam comment IPs" +msgstr "" + +#: admin/wp-security-spam-menu.php:383 +msgid "Check this box if you want this plugin to automatically block IP addresses which submit spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:387 +msgid "Minimum number of spam comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:389 +msgid "Specify the minimum number of spam comments for an IP address before it is permanently blocked." +msgstr "" + +#: admin/wp-security-spam-menu.php:393 +msgid "Example 1: Setting this value to \"1\" will block ALL IP addresses which were used to submit at least one spam comment." +msgstr "" + +#: admin/wp-security-spam-menu.php:394 +msgid "Example 2: Setting this value to \"5\" will block only those IP addresses which were used to submit 5 spam comments or more on your site." +msgstr "" + +#: admin/wp-security-spam-menu.php:412 +msgid "List spammer IP addresses" +msgstr "" + +#: admin/wp-security-spam-menu.php:416 +msgid "This section displays a list of the IP addresses of the people or bots who have left spam comments on your site." +msgstr "" + +#: admin/wp-security-spam-menu.php:417 +msgid "This information can be handy for identifying the most persistent IP addresses or ranges used by spammers." +msgstr "" + +#: admin/wp-security-spam-menu.php:418 +msgid "By inspecting the IP address data coming from spammers you will be in a better position to determine which addresses or address ranges you should block by adding them to the permanent block list." +msgstr "" + +#: admin/wp-security-spam-menu.php:419 +msgid "To add one or more of the IP addresses displayed in the table below to your blacklist, simply click the \"Block\" link for the individual row or select more than one address using the checkboxes and then choose the \"block\" option from the Bulk Actions dropdown list and click the \"Apply\" button." +msgstr "" + +#: admin/wp-security-spam-menu.php:427 +msgid "Minimum number of spam comments per IP" +msgstr "" + +#: admin/wp-security-spam-menu.php:429 +msgid "This field allows you to list only those IP addresses which have been used to post X or more spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:433 +msgid "Example 1: Setting this value to \"0\" or \"1\" will list ALL IP addresses which were used to submit spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:434 +msgid "Example 2: Setting this value to \"5\" will list only those IP addresses which were used to submit 5 spam comments or more on your site." +msgstr "" + +#: admin/wp-security-spam-menu.php:441 +msgid "Find IP addresses" +msgstr "" + +#: admin/wp-security-spam-menu.php:445 +msgid "Spammer IP address results" +msgstr "" + +#: admin/wp-security-spam-menu.php:451 +#: classes/wp-security-utility.php:253 +msgid "The plugin has detected that you are using a Multi-Site WordPress installation." +msgstr "" + +#: admin/wp-security-spam-menu.php:452 +msgid "Only the \"superadmin\" can block IP addresses from the main site." +msgstr "" + +#: admin/wp-security-spam-menu.php:453 +msgid "Take note of the IP addresses you want blocked and ask the superadmin to add these to the blacklist using the \"Blacklist Manager\" on the main site." +msgstr "" + +#: admin/wp-security-spam-menu.php:498 +msgid "BuddyPress spam settings" +msgstr "" + +#: admin/wp-security-spam-menu.php:503 +msgid "Add CAPTCHA to BuddyPress registration form" +msgstr "" + +#: admin/wp-security-spam-menu.php:507 +msgid "This feature will add a simple math CAPTCHA field in the BuddyPress registration form." +msgstr "" + +#: admin/wp-security-spam-menu.php:508 +msgid "Adding a CAPTCHA field in the registration form is a simple way of greatly reducing spam signups from bots without using .htaccess rules." +msgstr "" + +#: admin/wp-security-spam-menu.php:518 +msgid "Enable CAPTCHA on BuddyPress registration form" +msgstr "" + +#: admin/wp-security-spam-menu.php:521 +msgid "Check this if you want to insert a CAPTCHA field on the BuddyPress registration forms." +msgstr "" + +#: admin/wp-security-spam-menu.php:530 +msgid "BuddyPress is not active! In order to use this feature you will need to have BuddyPress installed and activated." +msgstr "" + +#: admin/wp-security-spam-menu.php:560 +msgid "bbPress spam settings" +msgstr "" + +#: admin/wp-security-spam-menu.php:565 +msgid "Add CAPTCHA to bbPress new topic form" +msgstr "" + +#: admin/wp-security-spam-menu.php:569 +msgid "This feature will add a simple math CAPTCHA field in the bbPress new topic form." +msgstr "" + +#: admin/wp-security-spam-menu.php:570 +msgid "Adding a CAPTCHA field in this form is a simple way of greatly reducing spam submitted from bots." +msgstr "" + +#: admin/wp-security-spam-menu.php:580 +msgid "Enable CAPTCHA on bbPress new topic form" +msgstr "" + +#: admin/wp-security-spam-menu.php:583 +msgid "Check this if you want to insert a CAPTCHA field on the bbPress new topic forms." +msgstr "" + +#: admin/wp-security-spam-menu.php:592 +msgid "bbPress is not active. In order to use this feature you will need to have bbPress installed and activated." +msgstr "" + +#: admin/wp-security-tools-menu.php:34 +msgid "WHOIS lookup" +msgstr "" + +#: admin/wp-security-tools-menu.php:95 +#: admin/wp-security-tools-menu.php:136 +msgid "Querying %s: %s" +msgstr "" + +#: admin/wp-security-tools-menu.php:103 +#: admin/wp-security-tools-menu.php:112 +#: admin/wp-security-tools-menu.php:151 +msgid "Redirected to %s" +msgstr "" + +#: admin/wp-security-tools-menu.php:173 +msgid "The WHOIS lookup feature gives you a way to look up who owns an IP address or domain name." +msgstr "" + +#: admin/wp-security-tools-menu.php:173 +msgid "You can use this to investigate users engaging in malicious activity on your site." +msgstr "" + +#: admin/wp-security-tools-menu.php:176 +msgid "WHOIS lookup on IP or domain" +msgstr "" + +#: admin/wp-security-tools-menu.php:183 +msgid "IP address or domain name:" +msgstr "" + +#: admin/wp-security-tools-menu.php:190 +msgid "Look up IP or domain" +msgstr "" + +#: admin/wp-security-tools-menu.php:219 +msgid "Please enter a valid IP address or domain name to look up." +msgstr "" + +#: admin/wp-security-tools-menu.php:220 +#: admin/wp-security-tools-menu.php:226 +msgid "Nothing to show." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:32 +msgid "WP username" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:33 +msgid "Display name" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:34 +msgid "Password" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:60 +msgid "User accounts" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:82 +msgid "Admin user security" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:85 +msgid "By default, WordPress sets the administrator username to \"admin\" at installation time." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:86 +msgid "A lot of hackers try to take advantage of this information by attempting \"Brute force login attacks\" where they repeatedly try to guess the password by using \"admin\" for username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:87 +msgid "From a security perspective, changing the default \"admin\" user name is one of the first and smartest things you should do on your site." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:88 +msgid "This feature will allow you to change your default \"admin\" user name to a more secure name of your choosing." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:95 +msgid "List of administrator accounts" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:104 +#: classes/grade-system/wp-security-feature-item-manager.php:43 +msgid "Change admin username" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:112 +msgid "Your site currently has an account which uses the default \"admin\" username. It is highly recommended that you change this name to something else. Use the following field to change the admin username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:118 +msgid "New admin username" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:120 +msgid "Choose a new username for admin." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:124 +msgid "Change username" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:126 +msgid "NOTE: If you are currently logged in as \"admin\" you will be automatically logged out after changing your username and will be required to log back in." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:133 +msgid "No action required! " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:135 +msgid "Your site does not have any account which uses the default \"admin\" username. " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:136 +msgid "This is good security practice." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:148 +msgid "Display name security" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:151 +msgid "When you submit a post or answer a comment, WordPress will usually display your \"nickname\"." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:152 +msgid "By default the nickname is set to the login (or user) name of your account." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:153 +msgid "From a security perspective, leaving your nickname the same as your user name is bad practice because it gives a hacker at least half of your account's login credentials." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:154 +msgid "Therefore to further tighten your site's security you are advised to change your nickname and Display name to be different from your Username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:160 +msgid "Modify accounts with identical login name and display name" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:169 +msgid "Your site currently has the following accounts which have an identical login name and display name." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:170 +msgid "Follow the link to edit the user profile of that particular user account, change Nickname, choose a different Display name compared to Username, and press the \"Update User\" button.)" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:185 +msgid "No action required." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:186 +msgid "Your site does not have a user account where the display name is identical to the username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:197 +msgid "Password tool" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:200 +msgid "Poor password selection is one of the most common weak points of many sites and is usually the first thing a hacker will try to exploit when attempting to break into your site." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:201 +msgid "Many people fall into the trap of using a simple word or series of numbers as their password. Such a predictable and simple password would take a competent hacker merely minutes to guess your password by using a simple script which cycles through the easy and most common combinations." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:202 +msgid "The longer and more complex your password is the harder it is for hackers to \"crack\" because more complex passwords require much greater computing power and time." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:203 +msgid "This section contains a useful password strength tool which you can use to check whether your password is sufficiently strong enough." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:208 +msgid "Password strength tool" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:210 +msgid "This password tool uses an algorithm which calculates how long it would take for your password to be cracked using the computing power of an off-the-shelf current model desktop PC with high end processor, graphics card and appropriate password cracking software." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:213 +msgid "Start typing a password." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:216 +msgid "It would take a desktop PC approximately" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:217 +msgid "1 sec" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:217 +msgid "to crack your password!" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:222 +msgid "Password Strength" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:245 +msgid "Username " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:245 +msgid " already exists. Please enter another value. " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:262 +msgid "The database update operation of the user account failed!" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:291 +msgid "You entered an invalid username. Please enter another value. " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:295 +msgid "Please enter a value for your username. " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:302 +msgid "Username successfully changed." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:322 +msgid "Account login name" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:331 +msgid "Edit user" +msgstr "" + +#: admin/wp-security-user-login-menu.php:54 +#: admin/wp-security-user-login-menu.php:474 +msgid "Failed login records" +msgstr "" + +#: admin/wp-security-user-login-menu.php:55 +#: classes/grade-system/wp-security-feature-item-manager.php:51 +msgid "Force logout" +msgstr "" + +#: admin/wp-security-user-login-menu.php:56 +#: admin/wp-security-user-login-menu.php:632 +msgid "Account activity logs" +msgstr "" + +#: admin/wp-security-user-login-menu.php:58 +#: admin/wp-security-user-login-menu.php:769 +msgid "Additional settings" +msgstr "" + +#: admin/wp-security-user-login-menu.php:81 +msgid "User login" +msgstr "" + +#: admin/wp-security-user-login-menu.php:118 +msgid "You entered a non-numeric value for the max login attempts field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:124 +msgid "You entered a non numeric value for the login retry time period field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:130 +msgid "You entered a non numeric value for the lockout time length field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:136 +msgid "You entered a non numeric value for the maximum lockout time length field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:141 +msgid "You entered an invalid minimum lockout time length, it must be less than the maximum lockout time length value." +msgstr "" + +#: admin/wp-security-user-login-menu.php:141 +msgid "Both have been set to the default values." +msgstr "" + +#: admin/wp-security-user-login-menu.php:160 +msgid "Please fill in one or more email addresses to notify." +msgstr "" + +#: admin/wp-security-user-login-menu.php:162 +msgid "You have entered one or more invalid email addresses." +msgstr "" + +#: admin/wp-security-user-login-menu.php:165 +msgid "It has been set to your WordPress admin email as default." +msgstr "" + +#: admin/wp-security-user-login-menu.php:250 +msgid "Login lockout configuration" +msgstr "" + +#: admin/wp-security-user-login-menu.php:254 +msgid "One of the ways hackers try to compromise sites is via a " +msgstr "" + +#: admin/wp-security-user-login-menu.php:254 +msgid "Brute force login attack" +msgstr "" + +#: admin/wp-security-user-login-menu.php:254 +msgid "This is where attackers use repeated login attempts until they guess the password." +msgstr "" + +#: admin/wp-security-user-login-menu.php:255 +msgid "Apart from choosing strong passwords, monitoring and blocking IP addresses which are involved in repeated login failures in a short period of time is a very effective way to stop these types of attacks." +msgstr "" + +#: admin/wp-security-user-login-menu.php:256 +msgid "You may also want to checkout our %s feature for another secure way to protect against these types of attacks." +msgstr "" + +#: admin/wp-security-user-login-menu.php:261 +msgid "Login lockout options" +msgstr "" + +#: admin/wp-security-user-login-menu.php:272 +msgid "Enable login lockout feature" +msgstr "" + +#: admin/wp-security-user-login-menu.php:275 +msgid "Check this if you want to enable the login lockout feature and apply the settings below" +msgstr "" + +#: admin/wp-security-user-login-menu.php:279 +msgid "Allow unlock requests" +msgstr "" + +#: admin/wp-security-user-login-menu.php:282 +msgid "Check this if you want to allow users to generate an automated unlock request link which will unlock their account" +msgstr "" + +#: admin/wp-security-user-login-menu.php:286 +msgid "Max login attempts" +msgstr "" + +#: admin/wp-security-user-login-menu.php:288 +msgid "Set the value for the maximum login retries before IP address is locked out" +msgstr "" + +#: admin/wp-security-user-login-menu.php:292 +msgid "Login retry time period (min)" +msgstr "" + +#: admin/wp-security-user-login-menu.php:294 +msgid "If the maximum number of failed login attempts for a particular IP address occur within this time period the plugin will lock out that address" +msgstr "" + +#: admin/wp-security-user-login-menu.php:299 +msgid "Minimum lockout time length" +msgstr "" + +#: admin/wp-security-user-login-menu.php:305 +msgid "Set the minimum time period in minutes of lockout." +msgstr "" + +#: admin/wp-security-user-login-menu.php:306 +msgid "This failed login lockout time will be tripled on each failed login." +msgstr "" + +#: admin/wp-security-user-login-menu.php:313 +msgid "Maximum lockout time length" +msgstr "" + +#: admin/wp-security-user-login-menu.php:318 +msgid "Set the maximum time period in minutes of lockout." +msgstr "" + +#: admin/wp-security-user-login-menu.php:319 +msgid "No IP address will be blocked for more than this time period after making a failed login attempt." +msgstr "" + +#: admin/wp-security-user-login-menu.php:324 +msgid "Display generic error message" +msgstr "" + +#: admin/wp-security-user-login-menu.php:327 +msgid "Check this if you want to show a generic error message when a login attempt fails" +msgstr "" + +#: admin/wp-security-user-login-menu.php:331 +msgid "Instantly lockout invalid usernames" +msgstr "" + +#: admin/wp-security-user-login-menu.php:334 +msgid "Check this if you want to instantly lockout login attempts with usernames which do not exist on your system" +msgstr "" + +#: admin/wp-security-user-login-menu.php:339 +msgid "Instantly lockout specific usernames" +msgstr "" + +#: admin/wp-security-user-login-menu.php:349 +msgid "Insert one username per line. Existing usernames are not blocked even if present in the list." +msgstr "" + +#: admin/wp-security-user-login-menu.php:354 +msgid "Notify by email" +msgstr "" + +#: admin/wp-security-user-login-menu.php:358 +msgid "Check this if you want to receive an email when someone has been locked out due to maximum failed login attempts" +msgstr "" + +#: admin/wp-security-user-login-menu.php:361 +msgid "Fill in one email address per line." +msgstr "" + +#: admin/wp-security-user-login-menu.php:365 +msgid "Each email address must be on a new line." +msgstr "" + +#: admin/wp-security-user-login-menu.php:366 +msgid "If a valid email address has not been filled in, it will not be saved." +msgstr "" + +#: admin/wp-security-user-login-menu.php:367 +msgid "The valid email address format is userid@example.com" +msgstr "" + +#: admin/wp-security-user-login-menu.php:368 +msgid "Example: %s" +msgstr "" + +#: admin/wp-security-user-login-menu.php:375 +msgid "Enable PHP backtrace in email" +msgstr "" + +#: admin/wp-security-user-login-menu.php:379 +msgid "Check this if you want to include the PHP backtrace in notification emails." +msgstr "" + +#: admin/wp-security-user-login-menu.php:379 +msgid "This is internal coding information which makes it easier to investigate where an issued occurred." +msgstr "" + +#: admin/wp-security-user-login-menu.php:389 +msgid "Currently locked out IP address ranges" +msgstr "" + +#: admin/wp-security-user-login-menu.php:394 +msgid "To see a list of all locked IP addresses and ranges go to the %s tab in the dashboard menu." +msgstr "" + +#: admin/wp-security-user-login-menu.php:399 +msgid "Login lockout IP whitelist settings" +msgstr "" + +#: admin/wp-security-user-login-menu.php:405 +msgid "Enable login lockout IP whitelist" +msgstr "" + +#: admin/wp-security-user-login-menu.php:416 +msgid "The addresses specified here will never be blocked by the login lockout feature." +msgstr "" + +#: admin/wp-security-user-login-menu.php:450 +msgid "User login feature - Delete all failed login records operation failed." +msgstr "" + +#: admin/wp-security-user-login-menu.php:452 +msgid "All records from the failed logins table were deleted successfully." +msgstr "" + +#: admin/wp-security-user-login-menu.php:467 +msgid "This tab displays the failed login attempts for your site." +msgstr "" + +#: admin/wp-security-user-login-menu.php:468 +msgid "The information below can be handy if you need to do security investigations because it will show you the IP range, username and ID (if applicable) and the time/date of the failed login attempt." +msgstr "" + +#: admin/wp-security-user-login-menu.php:469 +msgid "Failed login records that are older than %1$d days are purged automatically." +msgstr "" + +#: admin/wp-security-user-login-menu.php:508 +#: admin/wp-security-user-login-menu.php:517 +msgid "Delete all failed login records" +msgstr "" + +#: admin/wp-security-user-login-menu.php:514 +msgid "Click this button if you wish to delete all failed login records in one go." +msgstr "" + +#: admin/wp-security-user-login-menu.php:544 +msgid "You entered a non numeric value for the logout time period field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-user-login-menu.php:569 +msgid "Setting an expiry period for your WP administration session is a simple way to protect against unauthorized access to your site from your computer." +msgstr "" + +#: admin/wp-security-user-login-menu.php:570 +msgid "This feature allows you to specify a time period in minutes after which the admin session will expire and the user will be forced to log back in." +msgstr "" + +#: admin/wp-security-user-login-menu.php:575 +msgid "Force user logout options" +msgstr "" + +#: admin/wp-security-user-login-menu.php:587 +msgid "Enable force WP user logout" +msgstr "" + +#: admin/wp-security-user-login-menu.php:590 +msgid "Check this if you want to force a wp user to be logged out after a configured amount of time" +msgstr "" + +#: admin/wp-security-user-login-menu.php:594 +msgid "Logout the WP user after XX minutes" +msgstr "" + +#: admin/wp-security-user-login-menu.php:596 +msgid "(Minutes) The user will be forced to log back in after this time period has elapased." +msgstr "" + +#: admin/wp-security-user-login-menu.php:625 +msgid "This tab displays the activity for accounts registered with your site that have logged in using the WordPress login form." +msgstr "" + +#: admin/wp-security-user-login-menu.php:626 +msgid "The information below can be handy if you need to do security investigations because it will show you the last 100 recent login events by username, IP address and time/date." +msgstr "" + +#: admin/wp-security-user-login-menu.php:627 +msgid "Account activity logs that are older than %1$d days are purged automatically." +msgstr "" + +#: admin/wp-security-user-login-menu.php:697 +msgid "Refresh logged in user data" +msgstr "" + +#: admin/wp-security-user-login-menu.php:701 +msgid "Refresh data" +msgstr "" + +#: admin/wp-security-user-login-menu.php:706 +msgid "This tab displays all users who are currently logged into your site." +msgstr "" + +#: admin/wp-security-user-login-menu.php:707 +msgid "If you suspect there is a user or users who are logged in which should not be, you can block them by inspecting the IP addresses from the data below and adding them to your blacklist." +msgstr "" + +#: admin/wp-security-user-login-menu.php:708 +msgid "You can also instantly log them out by clicking on the \"Force logout\" link when you hover over the row in the user id column." +msgstr "" + +#: admin/wp-security-user-login-menu.php:713 +msgid "Currently logged in users" +msgstr "" + +#: admin/wp-security-user-login-menu.php:761 +msgid "WordPress 5.6 introduced a new feature called \"Application passwords\"." +msgstr "" + +#: admin/wp-security-user-login-menu.php:762 +msgid "This allows you to create a token from the WordPress dashboard which then can be used in the authorization header." +msgstr "" + +#: admin/wp-security-user-login-menu.php:763 +msgid "This feature allows you to disable application passwords as they can leave your site vulnerable to social engineering and phishing scams." +msgstr "" + +#: admin/wp-security-user-login-menu.php:780 +#: classes/grade-system/wp-security-feature-item-manager.php:53 +msgid "Disable application password" +msgstr "" + +#: admin/wp-security-user-login-menu.php:783 +msgid "Check this if you want to disable the application password." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:27 +msgid "Manual approval" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:28 +#: classes/grade-system/wp-security-feature-item-manager.php:59 +msgid "Registration CAPTCHA" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:29 +msgid "Registration honeypot" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:55 +msgid "User registration" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:115 +msgid "User registration settings" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:119 +msgid "Manually approve new registrations" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:123 +msgid "If your site allows people to create their own accounts via the WordPress registration form, then you can minimize spam or bogus registrations by manually approving each registration." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:124 +msgid "This feature will automatically set a newly registered account to \"pending\" until the administrator activates it. Therefore undesirable registrants will be unable to log in without your express approval." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:125 +msgid "You can view all accounts which have been newly registered via the handy table below and you can also perform bulk activation/deactivation/deletion tasks on each account." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:142 +msgid "Enable manual approval of new registrations" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:145 +msgid "Check this if you want to automatically disable all newly registered accounts so that you can approve them manually." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:154 +msgid "Approve registered users" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:206 +msgid "This feature allows you to add a CAPTCHA form on the WordPress registration page." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:207 +msgid "Users who attempt to register will also need to enter the answer to a simple mathematical question - if they enter the wrong answer, the plugin will not allow them to register." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:208 +msgid "Therefore, adding a CAPTCHA form on the registration page is another effective yet simple spam registration prevention technique." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:212 +msgid "Registration page CAPTCHA settings" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:219 +msgid "The core default behaviour for WordPress Multi Site regarding user registration is that all users are registered via the main site." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:220 +msgid "Therefore, if you would like to add a CAPTCHA form to the registration page for a Multi Site, please go to \"Registration CAPTCHA\" settings on the main site." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:235 +msgid "Enable CAPTCHA on registration page" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:238 +msgid "Check this if you want to insert a CAPTCHA form on the WordPress user registration page (if you allow user registration)." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:276 +msgid "This feature allows you to add a special hidden \"honeypot\" field on the WordPress registration page. This will only be visible to robots and not humans." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:277 +msgid "Since robots usually fill in every input field from a registration form, they will also submit a value for the special hidden honeypot field." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:279 +msgid "Therefore, if the plugin detects that this field has a value when the registration form is submitted, then the robot which is attempting to register on your site will be redirected to its localhost address - http://127.0.0.1." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:285 +msgid "Registration form honeypot settings" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:296 +msgid "Enable honeypot on registration page" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:299 +msgid "Check this if you want to enable the honeypot feature for the registration page" +msgstr "" + +#: classes/aios-ajax.php:89 +msgid "Invalid IP retrieve method." +msgstr "" + +#: classes/aios-ajax.php:131 +#: wp-security-core.php:258 +msgid "The security check failed; try refreshing the page." +msgstr "" + +#: classes/aios-ajax.php:152 +#: wp-security-core.php:268 +msgid "You are not allowed to run this command." +msgstr "" + +#: classes/aios-ajax.php:173 +#: wp-security-core.php:282 +msgid "Options can only be saved by network admin" +msgstr "" + +#: classes/aios-ajax.php:202 +msgid "The command \"%s\" was not found" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:39 +msgid "Remove WP generator meta tag" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:45 +msgid "Change display name" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:57 +msgid "Registration approval" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:61 +msgid "Enable registration honeypot" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:73 +msgid "WordPress files access" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:77 +msgid "IP and user agent blacklisting" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:81 +msgid "Enable basic firewall" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:82 +msgid "Enable pingback vulnerability protection" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:83 +msgid "Block access to debug log file" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:87 +msgid "Forbid proxy comments" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:88 +msgid "Deny bad queries" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:91 +msgid "5G/6G blacklist" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:97 +msgid "Enable IP blocking for 404 detection" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:101 +msgid "Enable rename login page" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:106 +msgid "Lost password CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:107 +msgid "Custom login CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:108 +msgid "Woo login CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:109 +msgid "Woo lost password CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:110 +msgid "Woo register CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:112 +msgid "Login IP whitelisting" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:114 +msgid "Enable login honeypot" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:118 +msgid "Comment CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:119 +msgid "Block spambots" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:121 +msgid "BuddyPress registration CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:123 +msgid "bbPress new topic CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item.php:29 +msgid "Basic" +msgstr "" + +#: classes/grade-system/wp-security-feature-item.php:31 +msgid "Intermediate" +msgstr "" + +#: classes/grade-system/wp-security-feature-item.php:33 +msgid "Advanced" +msgstr "" + +#: classes/wp-security-captcha.php:47 +#: classes/wp-security-general-init-tasks.php:407 +msgid "Please enter an answer in digits:" +msgstr "Vänligen svara med siffror:" + +#: classes/wp-security-captcha.php:127 +msgid "one" +msgstr "ett" + +#: classes/wp-security-captcha.php:128 +msgid "two" +msgstr "två" + +#: classes/wp-security-captcha.php:129 +msgid "three" +msgstr "tree" + +#: classes/wp-security-captcha.php:130 +msgid "four" +msgstr "fyra" + +#: classes/wp-security-captcha.php:131 +msgid "five" +msgstr "fem" + +#: classes/wp-security-captcha.php:132 +msgid "six" +msgstr "sex" + +#: classes/wp-security-captcha.php:133 +msgid "seven" +msgstr "sju" + +#: classes/wp-security-captcha.php:134 +msgid "eight" +msgstr "åtta" + +#: classes/wp-security-captcha.php:135 +msgid "nine" +msgstr "nio" + +#: classes/wp-security-captcha.php:136 +msgid "ten" +msgstr "tio" + +#: classes/wp-security-captcha.php:137 +msgid "eleven" +msgstr "elva" + +#: classes/wp-security-captcha.php:138 +msgid "twelve" +msgstr "tolv" + +#: classes/wp-security-captcha.php:139 +msgid "thirteen" +msgstr "tretton" + +#: classes/wp-security-captcha.php:140 +msgid "fourteen" +msgstr "fjorton" + +#: classes/wp-security-captcha.php:141 +msgid "fifteen" +msgstr "femton" + +#: classes/wp-security-captcha.php:142 +msgid "sixteen" +msgstr "sexton" + +#: classes/wp-security-captcha.php:143 +msgid "seventeen" +msgstr "sjutton" + +#: classes/wp-security-captcha.php:144 +msgid "eighteen" +msgstr "arton" + +#: classes/wp-security-captcha.php:145 +msgid "nineteen" +msgstr "nitton" + +#: classes/wp-security-captcha.php:146 +msgid "twenty" +msgstr "tjugo" + +#: classes/wp-security-cronjob-handler.php:34 +msgid "Every 15 minutes" +msgstr "" + +#: classes/wp-security-debug-logger.php:46 +msgid "Unable to get the reason why" +msgstr "" + +#: classes/wp-security-debug-logger.php:47 +msgid "Unable to clear the logs" +msgstr "" + +#: classes/wp-security-file-scan.php:85 +msgid "All In One WP Security - File change detected!" +msgstr "" + +#: classes/wp-security-file-scan.php:87 +msgid "A file change was detected on your system for site URL" +msgstr "" + +#: classes/wp-security-file-scan.php:87 +msgid ". Scan was generated on" +msgstr "" + +#: classes/wp-security-file-scan.php:88 +msgid "A summary of the scan results is shown below:" +msgstr "" + +#: classes/wp-security-file-scan.php:91 +msgid "Login to your site to view the scan details." +msgstr "" + +#: classes/wp-security-file-scan.php:313 +msgid "The following files were added to your host" +msgstr "" + +#: classes/wp-security-file-scan.php:315 +#: classes/wp-security-file-scan.php:323 +#: classes/wp-security-file-scan.php:332 +msgid "modified on: " +msgstr "" + +#: classes/wp-security-file-scan.php:321 +msgid "The following files were removed from your host" +msgstr "" + +#: classes/wp-security-file-scan.php:330 +msgid "The following files were changed on your host" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:212 +#: classes/wp-security-general-init-tasks.php:481 +msgid "Application passwords have been disabled by All In One WP Security & Firewall plugin." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:428 +#: classes/wp-security-general-init-tasks.php:541 +#: classes/wp-security-general-init-tasks.php:574 +#: classes/wp-security-user-login.php:137 +#: classes/wp-security-user-registration.php:74 +msgid "ERROR: Your answer was incorrect - please try again." +msgstr "FEL: Ditt svar var fel. Försök igen." + +#: classes/wp-security-general-init-tasks.php:463 +msgid "Enter something special:" +msgstr "Skriv någonting här om du inte är människa:" + +#: classes/wp-security-general-init-tasks.php:476 +msgid "Application passwords" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:485 +msgid "Change setting" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:487 +msgid "Site admin can only change this setting." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:516 +msgid "Error: You entered an incorrect CAPTCHA answer. Please go back and try again." +msgstr "Fel: Du angav fel svar i CAPTCHA-fältet. Gå tillbaka och prova en gång till." + +#: classes/wp-security-general-init-tasks.php:558 +msgid "Your CAPTCHA answer was incorrect - please try again." +msgstr "Ditt CAPTCHA-svar var fel. Försök igen!" + +#: classes/wp-security-general-init-tasks.php:567 +msgid "ERROR: Your IP address is currently locked please contact the administrator!" +msgstr "" + +#. translators: %s: Admin Dashboard > WP Security > Brute Force > Login CAPTCHA Tab Link +#: classes/wp-security-general-init-tasks.php:642 +msgid "Your Google reCAPTCHA site key is wrong. Please fill the correct reCAPTCHA keys %s to use the Google reCAPTCHA feature." +msgstr "" + +#. translators: %s: Admin Dashboard > WP Security > Brute Force > Login CAPTCHA Tab Link +#: classes/wp-security-general-init-tasks.php:642 +#: classes/wp-security-notices.php:99 +msgid "here" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +msgid "Would you like All In One WP Security & Firewall to re-insert the security rules in your .htaccess file which were cleared when you deactivated the plugin?" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +#: templates/may-also-like.php:40 +#: templates/may-also-like.php:43 +#: templates/may-also-like.php:54 +#: templates/may-also-like.php:57 +#: templates/may-also-like.php:68 +#: templates/may-also-like.php:71 +#: templates/may-also-like.php:91 +#: templates/may-also-like.php:103 +#: templates/may-also-like.php:115 +#: templates/may-also-like.php:127 +#: templates/may-also-like.php:139 +#: templates/may-also-like.php:151 +#: templates/may-also-like.php:168 +#: templates/may-also-like.php:171 +#: templates/may-also-like.php:183 +#: templates/may-also-like.php:195 +#: templates/may-also-like.php:207 +#: templates/may-also-like.php:219 +#: templates/may-also-like.php:231 +#: templates/may-also-like.php:243 +#: templates/may-also-like.php:252 +#: templates/may-also-like.php:255 +#: templates/may-also-like.php:264 +#: templates/may-also-like.php:267 +#: templates/may-also-like.php:279 +#: templates/may-also-like.php:297 +#: templates/may-also-like.php:309 +#: templates/may-also-like.php:327 +#: templates/may-also-like.php:339 +#: templates/may-also-like.php:351 +#: templates/may-also-like.php:368 +#: templates/may-also-like.php:380 +msgid "Yes" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +#: templates/may-also-like.php:88 +#: templates/may-also-like.php:100 +#: templates/may-also-like.php:112 +#: templates/may-also-like.php:124 +#: templates/may-also-like.php:136 +#: templates/may-also-like.php:148 +#: templates/may-also-like.php:180 +#: templates/may-also-like.php:192 +#: templates/may-also-like.php:204 +#: templates/may-also-like.php:216 +#: templates/may-also-like.php:228 +#: templates/may-also-like.php:240 +#: templates/may-also-like.php:276 +#: templates/may-also-like.php:294 +#: templates/may-also-like.php:306 +#: templates/may-also-like.php:324 +#: templates/may-also-like.php:336 +#: templates/may-also-like.php:348 +#: templates/may-also-like.php:365 +#: templates/may-also-like.php:377 +#: templates/notices/custom-notice.php:27 +msgid "No" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:674 +msgid "Your registration is pending approval." +msgstr "" + +#: classes/wp-security-notices.php:25 +msgid "The All in One Security plugin has disabled the login whitelist setting that you have enabled in the past." +msgstr "" + +#: classes/wp-security-notices.php:29 +msgid "Your website is running on an Apache webserver, the login whitelisting might not be functional until the recent update of AIOS (because it relied upon Apache-specific module features)." +msgstr "" + +#: classes/wp-security-notices.php:31 +msgid "Your website is running on a non-Apache webserver, so the login whitelisting was not functional until the recent update of AIOS (because it relied upon Apache-specific features)." +msgstr "" + +#: classes/wp-security-notices.php:33 +msgid "It began working with AIOS version 5.0.8." +msgstr "" + +#: classes/wp-security-notices.php:33 +msgid "We have disabled it so that your login page will not be blocked unexpectedly." +msgstr "" + +#: classes/wp-security-notices.php:42 +msgid "Would you like to re-enable login whitelisting?" +msgstr "" + +#: classes/wp-security-notices.php:48 +msgid "Removed database backup feature from the All In One WP Security & Firewall plugin" +msgstr "" + +#: classes/wp-security-notices.php:50 +msgid "Beginning with version 5.0.0, AIOS has replaced the AIOS backup method with the superior UpdraftPlus method." +msgstr "" + +#: classes/wp-security-notices.php:51 +msgid "It remains free and is fully supported by the UpdraftPlus team." +msgstr "" + +#: classes/wp-security-notices.php:54 +msgid "You are seeing this notice because you have previously set up automated database backups in AIOS." +msgstr "" + +#: classes/wp-security-notices.php:55 +msgid "Would you like to set up scheduled backups with UpdraftPlus?" +msgstr "" + +#: classes/wp-security-notices.php:61 +msgid "Setup UpdraftPlus backup plugin" +msgstr "" + +#: classes/wp-security-notices.php:67 +msgid "Important: set up your IP address detection settings" +msgstr "" + +#: classes/wp-security-notices.php:69 +msgid "The All in One Security plugin couldn't be certain about the correct method to detect the IP address for your site visitors with your currently-configured IP address detection settings." +msgstr "" + +#: classes/wp-security-notices.php:70 +msgid "It is important for your security to set the IP address detection settings properly." +msgstr "" + +#: classes/wp-security-notices.php:73 +msgid "Please go to the settings and set them now." +msgstr "" + +#: classes/wp-security-notices.php:79 +msgid "Setup IP address detection settings" +msgstr "" + +#: classes/wp-security-notices.php:85 +msgid "Important: Disabled login whitelist setting" +msgstr "" + +#: classes/wp-security-notices.php:91 +msgid "Turn it back on" +msgstr "" + +#: classes/wp-security-notices.php:92 +msgid "Edit the settings" +msgstr "" + +#: classes/wp-security-notices.php:95 +msgid "Keep it off" +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Hey - We noticed All In One WP Security & Firewall has kept your site safe for a while. If you like us, please consider leaving a positive review to spread the word. Or if you have any issues or questions please leave us a support message %s." +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Thank you so much!" +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Team All In One WP Security & Firewall" +msgstr "" + +#: classes/wp-security-notices.php:109 +msgid "Enhance your security even more by backing up your site" +msgstr "" + +#: classes/wp-security-notices.php:110 +msgid "UpdraftPlus is the world's most trusted backup plugin from the owners of All In One WP Security & Firewall" +msgstr "" + +#: classes/wp-security-notices.php:121 +msgid "After you've secured your site, we recommend you install our WP-Optimize plugin to streamline it for better website performance." +msgstr "" + +#: classes/wp-security-process-renamed-login-page.php:152 +msgid "Not available." +msgstr "" + +#: classes/wp-security-two-factor-login.php:34 +msgid "Two factor authentication - Admin settings" +msgstr "" + +#: classes/wp-security-two-factor-login.php:97 +msgid "Two Factor Auth" +msgstr "" + +#: classes/wp-security-two-factor-login.php:153 +msgid "PHP OpenSSL or mcrypt module required" +msgstr "" + +#: classes/wp-security-two-factor-login.php:153 +msgid "The All In One WP Security plugin's Two Factor Authentication module requires either the PHP openssl (preferred) or mcrypt module to be installed. Please ask your web hosting company to install one of them." +msgstr "" + +#: classes/wp-security-user-login.php:71 +msgid "You have disabled login lockout by defining the AIOS_DISABLE_LOGIN_LOCKOUT constant value as true, and the login lockout setting has enabled it." +msgstr "" + +#. translators: 1: Locked IP Addresses admin page link +#: classes/wp-security-user-login.php:73 +msgid "Delete your login lockout IP from %s and define the AIOS_DISABLE_LOGIN_LOCKOUT constant value as false." +msgstr "" + +#: classes/wp-security-user-login.php:100 +msgid "ERROR: Access from your IP address has been blocked for security reasons. Please contact the administrator." +msgstr "" + +#: classes/wp-security-user-login.php:108 +msgid "Service temporarily unavailable" +msgstr "" + +#: classes/wp-security-user-login.php:163 +msgid "ACCOUNT PENDING: Your account is currently not active. An administrator needs to activate your account before you can login." +msgstr "KONTOT AVVAKTAR: Ditt konto är ännu inte aktivt. Innan du kan logga in, behöver en administratör aktivera kontot." + +#: classes/wp-security-user-login.php:242 +msgid "ERROR: Invalid login credentials." +msgstr "FEL: Inloggningsuppgifterna är felaktiga." + +#: classes/wp-security-user-login.php:392 +msgid "Site Lockout Notification" +msgstr "Blockerad från sajten" + +#: classes/wp-security-user-login.php:393 +msgid "User login lockout events had occurred due to too many failed login attempts or invalid username:" +msgstr "" + +#: classes/wp-security-user-login.php:396 +msgid "Username:" +msgstr "" + +#: classes/wp-security-user-login.php:397 +msgid "IP address:" +msgstr "" + +#: classes/wp-security-user-login.php:399 +msgid "IP range:" +msgstr "" + +#: classes/wp-security-user-login.php:404 +msgid "Log into your site WordPress administration panel to see the duration of the lockout or to unlock the user." +msgstr "" + +#: classes/wp-security-user-login.php:515 +msgid "Unlock request notification" +msgstr "Begäran att häva blockering" + +#: classes/wp-security-user-login.php:516 +msgid "You have requested for the account with email address %s to be unlocked. Please click the link below to unlock your account:" +msgstr "" + +#: classes/wp-security-user-login.php:516 +msgid "Unlock link: %s" +msgstr "" + +#: classes/wp-security-user-login.php:516 +msgid "After clicking the above link you will be able to login to the WordPress administration panel." +msgstr "När du klickat på denna länk så kan du logga in i WordPress administrationspanel." + +#: classes/wp-security-user-login.php:739 +msgid "Your session has expired because it has been over %d minutes since your last login." +msgstr "Din session har avslutets eftersom det gått mer än %d minuter sedan senaste inloggning." + +#: classes/wp-security-user-login.php:740 +#: classes/wp-security-user-login.php:744 +msgid "Please log back in to continue." +msgstr "Var vänlig logga in igen för att fortsätta." + +#: classes/wp-security-user-login.php:743 +msgid "You were logged out because you just changed the \"admin\" username." +msgstr "Du loggades ut eftersom du just bytte användarnamnet \"admin\"." + +#: classes/wp-security-user-login.php:773 +msgid "Request unlock" +msgstr "Begär upplåsning" + +#: classes/wp-security-user-registration.php:68 +msgid "ERROR: You are not allowed to register because your IP address is currently locked!" +msgstr "" + +#: classes/wp-security-utility-ip-address.php:217 +#: classes/wp-security-utility-ip-address.php:231 +#: classes/wp-security-utility-ip-address.php:245 +#: classes/wp-security-utility-ip-address.php:257 +#: classes/wp-security-utility-ip-address.php:269 +msgid " is not a valid ip address format." +msgstr "" + +#: classes/wp-security-utility-ip-address.php:274 +msgid "You cannot ban your own IP address: " +msgstr "" + +#: classes/wp-security-utility.php:254 +msgid "This feature can only be configured by the \"superadmin\" on the main site." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:32 +msgid "ERROR: Unable to process your request!" +msgstr "" + +#: other-includes/wp-security-unlock-request.php:45 +msgid "Please enter a valid email address" +msgstr "Skriv in en giltig e-postadress" + +#: other-includes/wp-security-unlock-request.php:57 +msgid "User account not found!" +msgstr "Användarkonto kunde inte hittas!" + +#: other-includes/wp-security-unlock-request.php:71 +msgid "Error: No locked entry was found in the database with your IP address range." +msgstr "Fel: Databasen innehåller inget låst adressblock med din IP-address!" + +#: other-includes/wp-security-unlock-request.php:76 +msgid "An email has been sent to you with the unlock instructions." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:93 +msgid "You are here because you have been locked out due to too many incorrect login attempts." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:94 +msgid "Please enter your email address and you will receive an email with instructions on how to unlock yourself." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:104 +msgid "Email Address" +msgstr "Mejladress" + +#: other-includes/wp-security-unlock-request.php:108 +msgid "Send unlock request" +msgstr "" + +#: templates/admin/incompatible-plugin.php:6 +msgid "Two Factor Authentication" +msgstr "" + +#: templates/admin/incompatible-plugin.php:10 +msgid "Two Factor Authentication currently disabled" +msgstr "" + +#: templates/admin/incompatible-plugin.php:12 +#: templates/admin/incompatible-plugin.php:16 +msgid "Two factor authentication in All In One WP Security is currently disabled because the incompatible plugin %s is active." +msgstr "" + +#: templates/automated-database-backup.php:4 +msgid "Automated scheduled backups" +msgstr "" + +#: templates/automated-database-backup.php:9 +msgid "Automate backup in the UpdraftPlus plugin" +msgstr "" + +#: templates/automated-database-backup.php:19 +msgid "The AIOS 5.0.0 version release has removed the automated backup feature." +msgstr "" + +#: templates/automated-database-backup.php:20 +msgid "The AIOS automated backup had issues that made it less robust than we could be happy with." +msgstr "" + +#: templates/automated-database-backup.php:21 +msgid "Follow this link to automate backups in the superior UpdraftPlus backup plugin." +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:5 +msgid "Each IP address must be on a new line." +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:6 +msgid "To specify an IPv4 range use a wildcard \"*\" character. Acceptable ways to use wildcards is shown in the examples below:" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:7 +msgid "Example 1: 195.47.89.*" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:8 +msgid "Example 2: 195.47.*.*" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:9 +msgid "Example 3: 195.*.*.*" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:10 +msgid "To specify an IPv6 range use CIDR format as shown in the examples below:" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:11 +msgid "Example 4: 2401:4900:54c3:af15:2:2:5dc0:0/112" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:12 +msgid "Example 5: 2001:db8:1263::/48" +msgstr "" + +#: templates/may-also-like.php:5 +msgid "All-In-One Security (AIOS) Free vs Premium Comparison Chart" +msgstr "" + +#: templates/may-also-like.php:7 +msgid "FAQs" +msgstr "" + +#: templates/may-also-like.php:9 +msgid "Ask a pre-sales question" +msgstr "" + +#: templates/may-also-like.php:17 +msgid "All In One WP Security & Firewall Free" +msgstr "" + +#: templates/may-also-like.php:26 +#: templates/may-also-like.php:386 +msgid "Installed" +msgstr "" + +#: templates/may-also-like.php:29 +#: templates/may-also-like.php:389 +msgid "Upgrade now" +msgstr "" + +#: templates/may-also-like.php:34 +msgid "Login security feature suite" +msgstr "" + +#: templates/may-also-like.php:35 +msgid "Protect against brute-force attacks and keep bots at bay." +msgstr "" + +#: templates/may-also-like.php:35 +msgid "AIOS takes WordPress' default login security features to a whole new level." +msgstr "" + +#: templates/may-also-like.php:37 +msgid "To see all login security features, visit %s" +msgstr "" + +#: templates/may-also-like.php:48 +msgid "Firewall and file protection feature suite" +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Protection from the latest exploits." +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Activate firewall settings ranging from basic, intermediate and advanced." +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Get comprehensive, instant protection with All-in-One Security." +msgstr "" + +#: templates/may-also-like.php:51 +msgid "To see all firewall and file protection features, visit %s" +msgstr "" + +#: templates/may-also-like.php:62 +msgid "Content protection feature suite" +msgstr "" + +#: templates/may-also-like.php:63 +msgid "Eliminate spam and protect your content to dramatically improve your website's interactions with search engines." +msgstr "" + +#: templates/may-also-like.php:65 +msgid "To see all content protection features, visit %s" +msgstr "" + +#: templates/may-also-like.php:76 +msgid "Malware scanning" +msgstr "" + +#: templates/may-also-like.php:77 +msgid "Finding out by accident that your site has been infected with malware is too late." +msgstr "" + +#: templates/may-also-like.php:79 +msgid "Malware can have a dramatic effect on your site's search rankings and you may not even know about it." +msgstr "" + +#: templates/may-also-like.php:79 +msgid "It can slow your website down, access customer data, send unsolicited emails, change your content or prevent users from accessing it." +msgstr "" + +#: templates/may-also-like.php:84 +msgid "Automatic malware scanning" +msgstr "" + +#: templates/may-also-like.php:85 +msgid "Best-in-class scanning for the latest malware, trojans and spyware 24/7." +msgstr "" + +#: templates/may-also-like.php:96 +msgid "Response time monitoring" +msgstr "" + +#: templates/may-also-like.php:97 +msgid "You'll know immediately if your website's response time is negatively affected." +msgstr "" + +#: templates/may-also-like.php:108 +msgid "Up-time monitoring" +msgstr "" + +#: templates/may-also-like.php:109 +msgid "AIOS checks your website's uptime every 5 minutes." +msgstr "" + +#: templates/may-also-like.php:109 +msgid "We'll notify you straight away if your site/server goes down." +msgstr "" + +#: templates/may-also-like.php:120 +msgid "Prevents blacklisting by search engines" +msgstr "" + +#: templates/may-also-like.php:121 +msgid "AIOS monitors your site's blacklist status daily." +msgstr "" + +#: templates/may-also-like.php:121 +msgid "We'll notify you within 24 hours if something's amiss so you can take action, before it's too late." +msgstr "" + +#: templates/may-also-like.php:132 +msgid "Flexible assignment" +msgstr "" + +#: templates/may-also-like.php:133 +msgid "Register and remove websites from the scanning service at any time." +msgstr "" + +#: templates/may-also-like.php:144 +msgid "Malware reports" +msgstr "" + +#: templates/may-also-like.php:145 +msgid "Reports are available via the 'My Account' page and directly via email." +msgstr "" + +#: templates/may-also-like.php:156 +msgid "Flexible two-factor authentication" +msgstr "" + +#: templates/may-also-like.php:157 +msgid "With Two-Factor Authentication (TFA) users enter their username and password and a one-time code sent to a device to login." +msgstr "" + +#: templates/may-also-like.php:159 +msgid "TFA is a feature in both our free and premium packages, but AIOS Premium affords whole new levels of control over how TFA is implemented." +msgstr "" + +#: templates/may-also-like.php:164 +msgid "Authenticator apps" +msgstr "" + +#: templates/may-also-like.php:165 +msgid "Supports TOTP and HOTP protocols." +msgstr "" + +#: templates/may-also-like.php:165 +msgid "TFA Can be used with Google Authenticator, Microsoft Authenticator, Authy and many more." +msgstr "" + +#: templates/may-also-like.php:176 +msgid "Role specific configuration" +msgstr "" + +#: templates/may-also-like.php:177 +msgid "Make it compulsory for certain roles e.g. for admin and editor roles." +msgstr "" + +#: templates/may-also-like.php:188 +msgid "Require TFA after a set time period" +msgstr "" + +#: templates/may-also-like.php:189 +msgid "For example you could require all admins to have TFA once their accounts are a week old." +msgstr "" + +#: templates/may-also-like.php:200 +msgid "Trusted devices - control how often TFA is required" +msgstr "" + +#: templates/may-also-like.php:201 +msgid "Ask for TFA after a chosen number of days for trusted devices instead of on every login." +msgstr "" + +#: templates/may-also-like.php:212 +msgid "Anti-bot protection" +msgstr "" + +#: templates/may-also-like.php:213 +msgid "Option to hide the existence of forms on WooCommerce login pages unless JavaScript is active." +msgstr "" + +#: templates/may-also-like.php:224 +msgid "Customise TFA design layout" +msgstr "" + +#: templates/may-also-like.php:225 +msgid "Customise the design of TFA so it aligns with your existing web design." +msgstr "" + +#: templates/may-also-like.php:236 +msgid "TFA emergency codes" +msgstr "" + +#: templates/may-also-like.php:237 +msgid "Generate a one-time use emergency code to allow access if your device is lost." +msgstr "" + +#: templates/may-also-like.php:248 +msgid "TFA multisite compatibility" +msgstr "" + +#: templates/may-also-like.php:249 +msgid "TFA is Compatible with multisite networks and sub-sites." +msgstr "" + +#: templates/may-also-like.php:260 +msgid "TFA support for common login forms" +msgstr "" + +#: templates/may-also-like.php:261 +msgid "Supports WooCommerce, Affiliates-WP and Theme my Login login forms." +msgstr "" + +#: templates/may-also-like.php:272 +msgid "TFA support for other login forms" +msgstr "" + +#: templates/may-also-like.php:273 +msgid "Supports Elementor Pro, bbPress and all third-party login forms without any further coding needed." +msgstr "" + +#: templates/may-also-like.php:284 +msgid "Smart 404 blocking" +msgstr "" + +#: templates/may-also-like.php:285 +msgid "404 errors can occur when someone legitimately mistypes a URL, but they're also generated by hackers searching for weaknesses in your site." +msgstr "" + +#: templates/may-also-like.php:290 +msgid "Automatically and permanently blocks bots producing 404s" +msgstr "" + +#: templates/may-also-like.php:291 +msgid "AIOS Premium provides more protection than the competition by automatically and permanently blocking IP addresses of bots and hackers based on how many 404 errors they generate." +msgstr "" + +#: templates/may-also-like.php:302 +msgid "404 error charts" +msgstr "" + +#: templates/may-also-like.php:303 +msgid "Handy charts keep you informed of how many 404s have occurred and which IP address or country is producing them." +msgstr "" + +#: templates/may-also-like.php:314 +msgid "Country blocking" +msgstr "" + +#: templates/may-also-like.php:315 +msgid "Most malicious attacks come from a handful of countries and so it's possible to prevent most attacks with our country blocking tool." +msgstr "" + +#: templates/may-also-like.php:320 +msgid "Block traffic based on country of origin" +msgstr "" + +#: templates/may-also-like.php:321 +msgid "AIOS Premium utilises an IP database that promises 99.5% accuracy." +msgstr "" + +#: templates/may-also-like.php:332 +msgid "Block traffic to specific pages based on country of origin" +msgstr "" + +#: templates/may-also-like.php:333 +msgid "Block access to your whole site or on a page-by-page basis." +msgstr "" + +#: templates/may-also-like.php:344 +msgid "Whitelist some users from blocked countries" +msgstr "" + +#: templates/may-also-like.php:345 +msgid "Whitelist IP addresses or IP ranges even if they are part of a blocked country." +msgstr "" + +#: templates/may-also-like.php:356 +msgid "Premium support" +msgstr "" + +#: templates/may-also-like.php:361 +msgid "Unlimited support" +msgstr "" + +#: templates/may-also-like.php:362 +msgid "Personalised, email support from our team of Security experts, as and when you need it." +msgstr "" + +#: templates/may-also-like.php:373 +msgid "Guaranteed response time" +msgstr "" + +#: templates/may-also-like.php:374 +msgid "We offer a guaranteed response time of three days." +msgstr "" + +#: templates/may-also-like.php:374 +msgid "99% of our Premium customers receive a response to their enquiry within 24 hours during the working week." +msgstr "" + +#: templates/may-also-like.php:397 +msgid "Our other plugins" +msgstr "" + +#: templates/may-also-like.php:411 +msgid "UpdraftPlus – the ultimate protection for your site, hard work and business" +msgstr "" + +#: templates/may-also-like.php:412 +msgid "Simplifies backups and restoration." +msgstr "" + +#: templates/may-also-like.php:412 +msgid "It is the world's highest ranking and most popular scheduled backup plugin, with over three million currently-active installs." +msgstr "" + +#: templates/may-also-like.php:413 +#: templates/may-also-like.php:419 +#: templates/may-also-like.php:425 +#: templates/may-also-like.php:431 +msgid "Try for free" +msgstr "" + +#: templates/may-also-like.php:417 +msgid "WP-Optimize – keep your database fast and efficient" +msgstr "" + +#: templates/may-also-like.php:418 +msgid "Makes your site fast and efficient." +msgstr "" + +#: templates/may-also-like.php:418 +msgid "It cleans the database, compresses images and caches pages for ultimate speed." +msgstr "" + +#: templates/may-also-like.php:423 +msgid "UpdraftCentral – save hours managing multiple WP sites from one place" +msgstr "" + +#: templates/may-also-like.php:424 +msgid "Highly efficient way to manage, optimize, update and backup multiple websites from one place." +msgstr "" + +#: templates/may-also-like.php:429 +msgid "Easy Updates Manager" +msgstr "" + +#: templates/may-also-like.php:430 +msgid "Keeps your WordPress site up to date and bug free." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:2 +msgid "IP address detection settings" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:6 +msgid "The IP address detection settings allow you to specify how visitors' IP addresses are made known to PHP (and hence to WordPress and its plugins)." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:7 +msgid "Usually, this is automatic and there is only one choice." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:8 +msgid "However in some setups, such as those using proxies (including load-balancers and security firewalls like Cloudflare), it may be necessary to set this manually." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "Attention" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "It is important to set this correctly - otherwise you may make it possible for a hacker to ban all your visitors (e.g. via banning Cloudflare from connecting to you) instead of being banned himself." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "The default is to use the REMOTE_ADDR PHP server variable. If this variable does not contain the visitor's IP address, then whilst you can make a different selection below, it is better to ask your web hosting company to have it correctly set." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:10 +msgid "This is the most secure setup, because when set correctly it is immune from being spoofed by an attacker." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:16 +msgid "You have no available IP address detection method(s); you must contact your web hosting company." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:22 +#: templates/menus/settings/advanced-settings.php:27 +#: templates/menus/settings/advanced-settings.php:32 +msgid "Your detected IP address according to %s:" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:38 +msgid "If your site is setup on localhost, you won't see your external IP address using your server's IP detection setting; but on a localhost-served site (not available to the outside world), the setting is irrelevant and can be ignored." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:61 +msgid "Choose a $_SERVER variable you would like to detect visitors' IP address using." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:67 +msgid "If your chosen server variable fails the plugin will automatically fall back to retrieving the IP address from $_SERVER[\"REMOTE_ADDR\"]" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:73 +msgid "Your IP address if using this setting:" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:75 +msgid "fetching..." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:81 +#: templates/menus/settings/advanced-settings.php:190 +msgid "getting..." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:89 +msgid "look-up possibly blocked by an ad-blocker or similar tool" +msgstr "" + +#: templates/notices/cookie-based-brute-force-prevention-disabled.php:4 +msgid "Cookie based brute force login prevention currently disabled" +msgstr "" + +#: templates/notices/cookie-based-brute-force-prevention-disabled.php:6 +msgid "Cookie based brute force login prevention is currently disabled via the AIOS_DISABLE_COOKIE_BRUTE_FORCE_PREVENTION constant (which is mostly likely to be defined in your wp-config.php)" +msgstr "" + +#: templates/notices/disable-login-whitelist.php:4 +msgid "Login whitelisting currently disabled" +msgstr "" + +#: templates/notices/disable-login-whitelist.php:6 +msgid "Login whitelisting is currently disabled via the AIOS_DISABLE_LOGIN_WHITELIST constant (which is mostly likely to be defined in your wp-config.php)" +msgstr "" + +#: templates/notices/horizontal-notice.php:8 +#: templates/notices/horizontal-notice.php:40 +msgid "notice image" +msgstr "" + +#: templates/notices/horizontal-notice.php:18 +msgid "Ok, you deserve it" +msgstr "" + +#: templates/notices/horizontal-notice.php:22 +msgid "Maybe later" +msgstr "" + +#: templates/notices/horizontal-notice.php:26 +msgid "Never" +msgstr "" + +#: templates/notices/horizontal-notice.php:66 +msgid "Get UpdraftCentral" +msgstr "" + +#: templates/notices/horizontal-notice.php:68 +msgid "Get UpdraftPlus" +msgstr "" + +#: templates/notices/horizontal-notice.php:70 +msgid "Get WP-Optimize" +msgstr "" + +#: templates/notices/horizontal-notice.php:72 +msgid "Find out more." +msgstr "" + +#: templates/notices/horizontal-notice.php:74 +msgid "Sign up" +msgstr "" + +#: templates/notices/horizontal-notice.php:76 +msgid "Go there" +msgstr "" + +#: templates/notices/horizontal-notice.php:78 +msgid "Read more" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:4 +msgid "Dismiss (for %s months)" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:6 +msgid "Thank you for installing All In One WP Security & Firewall!" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:13 +msgid "Super-charge and secure your WordPress site even more with our other top plugins:" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:17 +msgid "%s makes your site fast and efficient. It cleans the database, compresses images and caches pages for ultimate speed." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:21 +msgid "%s simplifies backups and restoration. It is the world's highest ranking and most popular scheduled backup plugin, with over three million currently-active installs." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:25 +msgid "%s is a highly efficient way to manage, optimize, update and backup multiple websites from one place." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:29 +msgid "%s is a WordPress subscription extension for WooCommerce store owners." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:33 +msgid "More quality plugins" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:33 +msgid "Premium WooCommerce plugins" +msgstr "" + +#: templates/partials/non-apache-feature-notice.php:9 +msgid "This feature works only on the Apache server." +msgstr "" + +#: templates/partials/non-apache-feature-notice.php:10 +msgid "You are using the non-apache server %s, so this feature won't work on your site." +msgstr "" + +#: wp-security-core.php:236 +#: wp-security.php:45 +msgid "This plugin requires PHP version %s." +msgstr "" + +#: wp-security-core.php:237 +msgid "Current site PHP version is %s." +msgstr "" + +#: wp-security-core.php:238 +#: wp-security.php:47 +msgid "You will need to ask your web hosting company to upgrade." +msgstr "" + +#: wp-security-core.php:397 +msgid "Error:" +msgstr "" + +#: wp-security-core.php:397 +msgid "template not found" +msgstr "" + +#: wp-security.php:44 +msgid "All In One WP Security and Firewall plugin has been deactivated." +msgstr "" + +#: wp-security.php:46 +msgid "Your current PHP version is %s." +msgstr "" diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-zh_CN.mo b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-zh_CN.mo new file mode 100755 index 0000000000000000000000000000000000000000..6207d690586e3dc1ed17733c9261f877a563f993 GIT binary patch literal 27377 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 aVD>Ejg9mZW5qegd#f-ZXpU3#G>;5kV67EF+ literal 0 HcmV?d00001 diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-zh_CN.po b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-zh_CN.po new file mode 100755 index 00000000..d4fc42e7 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall-zh_CN.po @@ -0,0 +1,6152 @@ +msgid "" +msgstr "" +"Project-Id-Version: All In One WP Security vv2.5\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-04-18 18:26+0800\n" +"PO-Revision-Date: 2017-04-18 18:26+0800\n" +"Last-Translator: 言午一郎 \n" +"Language-Team: \n" +"Language: zh\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=1;\n" +"X-Generator: Poedit 1.8.1\n" +"X-Poedit-Basepath: ../\n" +"X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n" +"X-Poedit-SearchPath-0: .\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Textdomain-Support: yes\n" + +#. Plugin Name of the plugin +msgid "All In One WP Security" +msgstr "" + +#. Plugin URI of the plugin +msgid "https://wordpress.org/plugins/all-in-one-wp-security-and-firewall/" +msgstr "" + +#. Description of the plugin +msgid "All round best WordPress security plugin!" +msgstr "" + +#. Author of the plugin +msgid "All In One WP Security & Firewall Team" +msgstr "" + +#. Author URI of the plugin +msgid "https://teamupdraft.com/" +msgstr "" + +#: admin/general/wp-security-list-table.php:483 +msgid "Are you sure you want to perform this bulk action?" +msgstr "" + +#: admin/wp-security-admin-init.php:259 +msgid "Unexpected response:" +msgstr "" + +#: admin/wp-security-admin-init.php:290 +msgid "Enjoyed %1$s? Please leave us a %2$s rating. We really appreciate your support!" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:414 +#: classes/wp-security-two-factor-login.php:95 +msgid "WP Security" +msgstr "WP 安全" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:415 +#: admin/wp-security-dashboard-menu.php:26 +#: admin/wp-security-dashboard-menu.php:76 +msgid "Dashboard" +msgstr "控制板" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:416 +#: admin/wp-security-settings-menu.php:95 +msgid "Settings" +msgstr "设置" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:417 +msgid "User Accounts" +msgstr "用户账户" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:418 +msgid "User Login" +msgstr "用户登录" + +#: admin/wp-security-admin-init.php:419 +msgid "User Registration" +msgstr "用户注册" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:420 +msgid "Database Security" +msgstr "数据库安全" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:424 +msgid "Filesystem Security" +msgstr "文件系统安全" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:429 +msgid "Blacklist Manager" +msgstr "黑名单管理器" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:434 +#: admin/wp-security-firewall-menu.php:60 +msgid "Firewall" +msgstr "防火墙" + +#: admin/wp-security-admin-init.php:436 +msgid "Brute Force" +msgstr "暴力破解" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:437 +msgid "Spam Prevention" +msgstr "垃圾防护" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:441 +#: admin/wp-security-filescan-menu.php:53 +msgid "Scanner" +msgstr "扫描器" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-init.php:443 +#: admin/wp-security-maintenance-menu.php:51 +msgid "Maintenance" +msgstr "网站维护" + +#: admin/wp-security-admin-init.php:444 +#: admin/wp-security-misc-options-menu.php:57 +msgid "Miscellaneous" +msgstr "其他" + +#: admin/wp-security-admin-init.php:445 +#: admin/wp-security-tools-menu.php:64 +msgid "Tools" +msgstr "" + +#: admin/wp-security-admin-init.php:457 +msgid "Premium Upgrade" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-admin-menu.php:67 +msgid "Settings successfully updated." +msgstr "设置已成功更新" + +#: admin/wp-security-admin-menu.php:77 +msgid "Successfully deleted the selected record(s)." +msgstr "" + +#: admin/wp-security-admin-menu.php:86 +msgid "Failed to delete the selected record(s)." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:25 +msgid "Ban users" +msgstr "禁止用户" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:51 +msgid "Blacklist manager" +msgstr "黑名单管理器" + +#: admin/wp-security-blacklist-menu.php:132 +#: admin/wp-security-firewall-menu.php:1233 +#: admin/wp-security-list-404.php:234 +#: admin/wp-security-list-comment-spammer-ip.php:205 +msgid "The plugin was unable to write to the .htaccess file. Please edit file manually." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:139 +msgid "Ban IPs or user agents" +msgstr "禁止IP地址或用户代理" + +#: admin/wp-security-blacklist-menu.php:142 +msgid "The All In One WP Security Blacklist feature gives you the option of banning certain host IP addresses or ranges and also user agents." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:143 +msgid "This feature will deny total site access for users which have IP addresses or user agents matching those which you have configured in the settings below." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:144 +msgid "The plugin achieves this by making appropriate modifications to your .htaccess file." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:145 +msgid "By blocking people, you are using the most secure first line of defence, which denies all access to blacklisted visitors as soon as they hit your hosting server." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:154 +#: admin/wp-security-firewall-menu.php:1055 +#: templates/may-also-like.php:20 +msgid "All In One WP Security & Firewall Premium" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:155 +#: admin/wp-security-firewall-menu.php:1056 +msgid "You may also be interested in %s." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "This plugin adds a number of extra features including %s and %s." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "smart 404 blocking" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:156 +#: admin/wp-security-firewall-menu.php:1057 +msgid "country IP blocking" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:170 +msgid "IP hosts and user agent blacklist settings" +msgstr "IP和用户代理黑名单设置" + +#: admin/wp-security-blacklist-menu.php:182 +#: admin/wp-security-brute-force-menu.php:193 +#: admin/wp-security-brute-force-menu.php:331 +msgid "must read this message" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:183 +#: admin/wp-security-brute-force-menu.php:194 +msgid "This feature can lock you out of admin if it doesn't work correctly on your site. You %s before activating this feature." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:189 +msgid "Enable IP or user agent blacklisting" +msgstr "启用IP和用户代理黑名单" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:192 +msgid "Check this if you want to enable the banning (or blacklisting) of selected IP addresses and/or user agents specified in the settings below" +msgstr "如果你想禁止(或黑名单)指定IP地址或用户代理,请在下面设定。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:196 +msgid "Enter IP addresses:" +msgstr "输入IP地址:" + +#: admin/wp-security-blacklist-menu.php:200 +msgid "Enter one or more IP addresses or IP ranges." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:205 +msgid "Enter user agents:" +msgstr "输入用户代理:" + +#: admin/wp-security-blacklist-menu.php:210 +msgid "Enter one or more user agent strings." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:211 +#: admin/wp-security-brute-force-menu.php:374 +#: admin/wp-security-brute-force-menu.php:408 +#: admin/wp-security-brute-force-menu.php:431 +#: admin/wp-security-brute-force-menu.php:452 +#: admin/wp-security-filescan-menu.php:309 +#: admin/wp-security-filescan-menu.php:326 +#: admin/wp-security-firewall-menu.php:175 +#: admin/wp-security-firewall-menu.php:212 +#: admin/wp-security-firewall-menu.php:232 +#: admin/wp-security-firewall-menu.php:258 +#: admin/wp-security-firewall-menu.php:385 +#: admin/wp-security-firewall-menu.php:415 +#: admin/wp-security-firewall-menu.php:446 +#: admin/wp-security-firewall-menu.php:474 +#: admin/wp-security-firewall-menu.php:503 +#: admin/wp-security-firewall-menu.php:681 +#: admin/wp-security-firewall-menu.php:699 +#: admin/wp-security-firewall-menu.php:737 +#: admin/wp-security-firewall-menu.php:868 +#: admin/wp-security-firewall-menu.php:1087 +#: admin/wp-security-firewall-menu.php:1110 +#: admin/wp-security-spam-menu.php:186 +#: admin/wp-security-spam-menu.php:221 +#: admin/wp-security-spam-menu.php:390 +#: admin/wp-security-spam-menu.php:430 +#: admin/wp-security-user-login-menu.php:362 +#: templates/info/ip-address-ip-range-info.php:2 +#: templates/menus/settings/advanced-settings.php:63 +msgid "More info" +msgstr "更多信息" + +#: admin/wp-security-blacklist-menu.php:214 +msgid "Each user agent string must be on a new line." +msgstr "" + +#: admin/wp-security-blacklist-menu.php:215 +msgid "Example 1 - A single user agent string to block:" +msgstr "" + +#: admin/wp-security-blacklist-menu.php:217 +msgid "Example 2 - A list of more than 1 user agent strings to block" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-blacklist-menu.php:225 +#: admin/wp-security-brute-force-menu.php:213 +#: admin/wp-security-brute-force-menu.php:686 +#: admin/wp-security-brute-force-menu.php:806 +#: admin/wp-security-brute-force-menu.php:868 +#: admin/wp-security-filescan-menu.php:351 +#: admin/wp-security-filesystem-menu.php:242 +#: admin/wp-security-firewall-menu.php:945 +#: admin/wp-security-firewall-menu.php:1129 +#: admin/wp-security-misc-options-menu.php:167 +#: admin/wp-security-misc-options-menu.php:218 +#: admin/wp-security-misc-options-menu.php:278 +#: admin/wp-security-settings-menu.php:619 +#: admin/wp-security-settings-menu.php:680 +#: admin/wp-security-spam-menu.php:233 +#: admin/wp-security-spam-menu.php:407 +#: admin/wp-security-spam-menu.php:526 +#: admin/wp-security-spam-menu.php:588 +#: admin/wp-security-user-login-menu.php:384 +#: admin/wp-security-user-login-menu.php:422 +#: admin/wp-security-user-login-menu.php:601 +#: admin/wp-security-user-login-menu.php:788 +#: admin/wp-security-user-registration-menu.php:150 +#: admin/wp-security-user-registration-menu.php:242 +#: admin/wp-security-user-registration-menu.php:305 +#: templates/menus/settings/advanced-settings.php:217 +msgid "Save settings" +msgstr "保存设置" + +#: admin/wp-security-brute-force-menu.php:33 +#: admin/wp-security-brute-force-menu.php:759 +#: admin/wp-security-dashboard-menu.php:651 +msgid "Rename login page" +msgstr "重命名登录页面" + +#: admin/wp-security-brute-force-menu.php:34 +#: admin/wp-security-brute-force-menu.php:154 +msgid "Cookie based brute force prevention" +msgstr "基于 Cookie 的强力预防" + +#: admin/wp-security-brute-force-menu.php:35 +#: classes/grade-system/wp-security-feature-item-manager.php:105 +msgid "Login CAPTCHA" +msgstr "登录验证码" + +#: admin/wp-security-brute-force-menu.php:36 +#: admin/wp-security-brute-force-menu.php:746 +msgid "Login whitelist" +msgstr "登录白名单" + +#: admin/wp-security-brute-force-menu.php:37 +msgid "Honeypot" +msgstr "蜜罐" + +#: admin/wp-security-brute-force-menu.php:67 +msgid "Brute force" +msgstr "暴力破解" + +#: admin/wp-security-brute-force-menu.php:105 +msgid "Please enter a value for your login page slug." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:109 +msgid "You cannot use the value \"wp-admin\" for your login page slug." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:111 +msgid "You must use alpha numeric characters for your login page slug." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:116 +#: admin/wp-security-filescan-menu.php:174 +#: admin/wp-security-firewall-menu.php:151 +#: admin/wp-security-firewall-menu.php:1011 +#: admin/wp-security-spam-menu.php:101 +#: admin/wp-security-spam-menu.php:270 +#: admin/wp-security-spam-menu.php:302 +#: admin/wp-security-user-login-menu.php:184 +#: admin/wp-security-user-login-menu.php:553 +#: templates/partials/non-apache-feature-notice.php:9 +msgid "Attention:" +msgstr "注意:" + +#: admin/wp-security-brute-force-menu.php:133 +msgid "Could not delete the Cookie-based directives from the .htaccess file. Please check the file permissions." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:155 +msgid "Login page white list" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:156 +msgid "An effective Brute Force prevention technique is to change the default WordPress login page URL." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:157 +msgid "Normally if you wanted to login to WordPress you would type your site's home URL followed by wp-login.php." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:158 +msgid "This feature allows you to change the login URL by setting your own slug and renaming the last portion of the login URL which contains the wp-login.php to any string that you like." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:159 +msgid "By doing this, malicious bots and hackers will not be able to access your login page because they will not know the correct login page URL." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:161 +msgid "You may also be interested in the following alternative brute force prevention features:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:172 +msgid "Your WordPress login page URL has been renamed." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:173 +msgid "Your current login URL is:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:181 +msgid "Rename login page settings" +msgstr "重命名登录页面设置" + +#: admin/wp-security-brute-force-menu.php:195 +msgid "NOTE: If you are hosting your site on WPEngine or a provider which performs server caching, you will need to ask the host support people to NOT cache your renamed login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:200 +msgid "Enable rename login page feature" +msgstr "启用重命名登录页面功能" + +#: admin/wp-security-brute-force-menu.php:203 +msgid "Check this if you want to enable the rename login page feature" +msgstr "如果要启用重命名登录页功能,请选中此项" + +#: admin/wp-security-brute-force-menu.php:207 +msgid "Login page URL" +msgstr "登陆页链接" + +#: admin/wp-security-brute-force-menu.php:209 +msgid "Enter a string which will represent your secure login page slug. You are encouraged to choose something which is hard to guess and only you will remember." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:243 +msgid "Settings have not been saved - your secret word must consist only of alphanumeric characters, ie, letters and/or numbers only." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:257 +msgid "You have successfully enabled the cookie based brute force prevention feature" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:258 +msgid "From now on you will need to log into your WP Admin using the following URL:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:260 +msgid "It is important that you save this URL value somewhere in case you forget it, OR," +msgstr "" + +#: admin/wp-security-brute-force-menu.php:261 +msgid "simply remember to add a \"?%s=1\" to your current site URL address." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:265 +msgid "You have successfully saved cookie based brute force prevention feature settings." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-brute-force-menu.php:295 +msgid "Brute force prevention firewall settings" +msgstr "强力预防防火墙设置" + +#: admin/wp-security-brute-force-menu.php:300 +msgid "A Brute Force Attack is when a hacker tries many combinations of usernames and passwords until they succeed in guessing the right combination." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:301 +msgid "Due to the fact that at any one time there may be many concurrent login attempts occurring on your site via malicious automated robots, this also has a negative impact on your server's memory and performance." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:302 +msgid "The features in this tab will stop the majority of brute force login attacks thus providing even better protection for your WP login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:307 +#: admin/wp-security-firewall-menu.php:654 +msgid "backup" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:308 +msgid "video tutorial" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:309 +msgid "To learn more about how to use this feature, please watch the following %s." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:310 +#: admin/wp-security-brute-force-menu.php:758 +msgid "Cookie-Based Brute Force Login Prevention" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:320 +#: admin/wp-security-user-login-menu.php:253 +msgid "Cookie based brute force login prevention" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:331 +msgid "This feature can lock you out of admin if it doesn't work correctly on your site. You " +msgstr "" + +#: admin/wp-security-brute-force-menu.php:342 +msgid "The cookie test was successful. You can now enable this feature." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:350 +msgid "The cookie test failed on this server. Consequently, this feature cannot be used on this site." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:357 +msgid "Before using this feature, you must perform a cookie test first." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:359 +msgid "This ensures that your browser cookie is working correctly and that you won't lock yourself out." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:364 +msgid "Perform cookie test" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:370 +#: classes/grade-system/wp-security-feature-item-manager.php:103 +msgid "Enable brute force attack prevention" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:373 +msgid "Check this if you want to protect your login page from Brute Force Attack." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:378 +msgid "This feature will deny access to your WordPress login page for all people except those who have a special cookie in their browser." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:380 +msgid "To use this feature do the following:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:382 +msgid "1) Enable the checkbox." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:384 +msgid "2) Enter a secret word consisting of alphanumeric characters which will be difficult to guess. This secret word will be useful whenever you need to know the special URL which you will use to access the login page (see point below)." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:386 +msgid "3) You will then be provided with a special login URL. You will need to use this URL to login to your WordPress site instead of the usual login URL. NOTE: The system will deposit a special cookie in your browser which will allow you access to the WordPress administration login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:388 +msgid "Any person trying to access your login page who does not have the special cookie in their browser will be automatically blocked." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:395 +msgid "Secret word" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:397 +msgid "Choose a secret word consisting of alphanumeric characters which you can use to access your special URL. Your are highly encouraged to choose a word which will be difficult to guess." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:401 +msgid "Re-direct URL" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:405 +msgid "Specify a URL to redirect a hacker to when they try to access your WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:412 +msgid "The URL specified here can be any site's URL and does not have to be your own. For example you can be as creative as you like and send hackers to the CIA or NSA home page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:414 +msgid "This field will default to: http://127.0.0.1 if you do not enter a value." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:416 +msgid "Useful Tip:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:418 +msgid "It's a good idea to not redirect attempted brute force login attempts to your site because it increases the load on your server." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:420 +msgid "Redirecting a hacker or malicious bot back to \"http://127.0.0.1\" is ideal because it deflects them back to their own local host and puts the load on their server instead of yours." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:427 +msgid "My site has posts or pages which are password protected" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:430 +msgid "Check this if you are using the native WordPress password protection feature for some or all of your blog posts or pages." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:435 +msgid "In the cases where you are protecting some of your posts or pages using the in-built WordPress password protection feature, a few extra lines of directives and exceptions need to be added so that people trying to access pages are not automatically blocked." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:437 +msgid "By enabling this checkbox, the plugin will add the necessary rules and exceptions so that people trying to access these pages are not automatically blocked." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:439 +msgid "Helpful Tip:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:441 +msgid "If you do not use the WordPress password protection feature for your posts or pages then it is highly recommended that you leave this checkbox disabled." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:448 +msgid "My site has a theme or plugins which use AJAX" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:451 +msgid "Check this if your site uses AJAX functionality." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:456 +msgid "In the cases where your WordPress installation has a theme or plugin that uses AJAX, a few extra lines of directives and exceptions need to be added to prevent AJAX requests from being automatically blocked by the brute force prevention feature." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:458 +msgid "By enabling this checkbox, the plugin will add the necessary rules and exceptions so that AJAX operations will work as expected." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:467 +msgid "Save feature settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:525 +msgid "This feature allows you to add a CAPTCHA form on various WordPress login pages and forms." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:526 +msgid "Adding a CAPTCHA form on a login page or form is another effective yet simple \"Brute Force\" prevention technique." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:527 +msgid "You have the option of using either %s or a plain maths CAPTCHA form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:528 +msgid "If you enable Google reCAPTCHA the reCAPTCHA widget will be displayed for all forms the CAPTCHA settings below." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:529 +msgid "If Google reCAPTCHA is disabled the simple maths CAPTCHA form will apply and users will need to enter the answer to a simple mathematical question." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:535 +msgid "Google reCAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:540 +msgid "By enabling these settings the Google reCAPTCHA v2 widget will be applied by default for all forms with CAPTCHA enabled." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:549 +msgid "reCAPTCHA will not work because you have disabled login lockout by activating the AIOS_DISABLE_LOGIN_LOCKOUT constant value in a configuration file." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:550 +msgid "To enable it, define AIOS_DISABLE_LOGIN_LOCKOUT constant value as false, or remove it." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:558 +msgid "Use Google reCAPTCHA as default" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:561 +msgid "Check this if you want to default to Google reCAPTCHA for all settings below. (If this is left unchecked, all CAPTCHA forms will revert to the plain maths CAPTCHA)" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:565 +msgid "Site key" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:571 +msgid "Secret key" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:580 +msgid "Login form CAPTCHA settings" +msgstr "登录表单验证码设置" + +#: admin/wp-security-brute-force-menu.php:589 +msgid "Enable CAPTCHA on login page" +msgstr "在登录页面上启用验证码" + +#: admin/wp-security-brute-force-menu.php:592 +msgid "Check this if you want to insert a CAPTCHA form on the login page." +msgstr "如果您要在登录页面上插入验证码表格,请选中此项" + +#: admin/wp-security-brute-force-menu.php:598 +msgid "Lost password form CAPTCHA settings" +msgstr "忘记密码表单验证码设置" + +#: admin/wp-security-brute-force-menu.php:608 +msgid "Enable CAPTCHA on lost password page" +msgstr "启用忘记密码表单验证码" + +#: admin/wp-security-brute-force-menu.php:611 +msgid "Check this if you want to insert a CAPTCHA form on the lost password page." +msgstr "如果要在忘记密码页面上插入验证码表格,请选中此项" + +#: admin/wp-security-brute-force-menu.php:617 +msgid "Custom login form CAPTCHA settings" +msgstr "自定义登录表单验证码设置" + +#: admin/wp-security-brute-force-menu.php:626 +msgid "Enable CAPTCHA on custom login form" +msgstr "启用自定义登录表单的验证码" + +#: admin/wp-security-brute-force-menu.php:629 +msgid "Check this if you want to insert CAPTCHA on a custom login form generated by the following WP function: wp_login_form()" +msgstr "如果要在由WP函数wp_login_form()生成的自定义登录表单上插入验证码,请选中此项:" + +#: admin/wp-security-brute-force-menu.php:639 +msgid "WooCommerce forms CAPTCHA settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:648 +msgid "Enable CAPTCHA on WooCommerce login form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:651 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce login form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:661 +msgid "Enable CAPTCHA on WooCommerce lost password form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:664 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce lost password form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:674 +msgid "Enable CAPTCHA on WooCommerce registration form" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:677 +msgid "Check this if you want to insert CAPTCHA on a WooCommerce registration form." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:749 +msgid "The All In One WP Security Whitelist feature gives you the option of only allowing certain IP addresses or ranges to have access to your WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:750 +msgid "This feature will deny login access for all IP addresses which are not in your whitelist as configured in the settings below." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:751 +msgid "The plugin achieves this by writing the appropriate directives to your .htaccess file." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:752 +msgid "By allowing/blocking IP addresses, you are using the most secure first line of defence because login access will only be granted to whitelisted IP addresses and other addresses will be blocked as soon as they try to access your login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:760 +msgid "Attention: If in addition to enabling the white list feature, you also have one of the %s or %s features enabled, you will still need to use your secret word or special slug in the URL when trying to access your WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:761 +msgid "These features are NOT functionally related. Having both of them enabled on your site means you are creating 2 layers of security." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:772 +msgid "Login IP whitelist settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:783 +msgid "Enable IP whitelisting" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:786 +#: admin/wp-security-user-login-menu.php:408 +msgid "Check this if you want to enable the whitelisting of selected IP addresses specified in the settings below" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:790 +msgid "Your current IP address" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:793 +msgid "You can copy and paste this address in the text box below if you want to include it in your login whitelist." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:797 +#: admin/wp-security-user-login-menu.php:412 +msgid "Enter whitelisted IP addresses:" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:801 +#: admin/wp-security-user-login-menu.php:416 +msgid "Enter one or more IP addresses or IP ranges you wish to include in your whitelist." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:801 +msgid "Only the addresses specified here will have access to the WordPress login page." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:839 +msgid "This feature allows you to add a special hidden \"honeypot\" field on the WordPress login page. This will only be visible to robots and not humans." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:840 +msgid "Since robots usually fill in every input field from a login form, they will also submit a value for the special hidden honeypot field." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:841 +#: admin/wp-security-user-registration-menu.php:278 +msgid "The way honeypots work is that a hidden field is placed somewhere inside a form which only robots will submit. If that field contains a value when the form is submitted then a robot has most likely submitted the form and it is consequently dealt with." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:842 +msgid "Therefore, if the plugin detects that this field has a value when the login form is submitted, then the robot which is attempting to login to your site will be redirected to its localhost address - http://127.0.0.1." +msgstr "" + +#: admin/wp-security-brute-force-menu.php:848 +msgid "Login form honeypot settings" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:859 +msgid "Enable honeypot on login page" +msgstr "" + +#: admin/wp-security-brute-force-menu.php:862 +msgid "Check this if you want to enable the honeypot feature for the login page" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:27 +#: admin/wp-security-dashboard-menu.php:374 +#: classes/wp-security-user-login.php:74 +msgid "Locked IP addresses" +msgstr "已锁定的IP地址" + +#: admin/wp-security-dashboard-menu.php:28 +msgid "Permanent block list" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:29 +msgid "Logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:33 +msgid "Premium upgrade" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:131 +#: admin/wp-security-dashboard-menu.php:518 +#: admin/wp-security-user-login-menu.php:53 +#: classes/grade-system/wp-security-feature-item-manager.php:49 +msgid "Login lockout" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:132 +msgid "This tab displays the list of all IP addresses which are currently temporarily locked out due to the login lockout feature:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:138 +msgid "Currently locked out IP addresses and ranges" +msgstr "当前被锁定的 IP 地址和范围" + +#: admin/wp-security-dashboard-menu.php:183 +msgid "This tab displays the list of all permanently blocked IP addresses." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:184 +#: admin/wp-security-spam-menu.php:339 +msgid "NOTE: This feature does NOT use the .htaccess file to permanently block the IP addresses so it should be compatible with all web servers running WordPress." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:189 +msgid "Permanently blocked IP addresses" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:200 +#: admin/wp-security-firewall-menu.php:1151 +#: admin/wp-security-user-login-menu.php:485 +#: admin/wp-security-user-login-menu.php:643 +#: admin/wp-security-user-registration-menu.php:164 +msgid "Search" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:238 +#: admin/wp-security-dashboard-menu.php:249 +#: admin/wp-security-dashboard-menu.php:260 +msgid "All In One WP Security & Firewall" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:250 +msgid "Debug logs have been cleared." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:261 +msgid "Unable to clear the logs; an invalid nonce was provided" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:274 +msgid "Debug log options" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:281 +msgid "Clear logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:289 +msgid "Debug logs" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:362 +msgid "Security strength meter" +msgstr "安全强度计" + +#: admin/wp-security-dashboard-menu.php:363 +msgid "Security points breakdown" +msgstr "安全点分析" + +#: admin/wp-security-dashboard-menu.php:364 +msgid "Spread the word" +msgstr "宣传我们" + +#: admin/wp-security-dashboard-menu.php:365 +msgid "Get to know the developers" +msgstr "了解开发人员" + +#: admin/wp-security-dashboard-menu.php:366 +msgid "Critical feature status" +msgstr "关键功能状态" + +#: admin/wp-security-dashboard-menu.php:367 +msgid "Last 5 logins" +msgstr "最近5次登录" + +#: admin/wp-security-dashboard-menu.php:368 +msgid "Maintenance mode status" +msgstr "维护模式状态" + +#: admin/wp-security-dashboard-menu.php:373 +#: admin/wp-security-dashboard-menu.php:664 +#: admin/wp-security-user-login-menu.php:57 +msgid "Logged in users" +msgstr "已登录用户" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:417 +msgid "Total Achievable Points: " +msgstr "总计可得点数:" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:419 +msgid "Current Score of Your Site: " +msgstr "网站当前分数:" + +#: admin/wp-security-dashboard-menu.php:472 +msgid "We are working hard to make your WordPress site more secure. Please support us, here is how:" +msgstr "我们正在努力使你的 WordPress 网站更安全。请用下列方式支持我们:" + +#: admin/wp-security-dashboard-menu.php:473 +msgid "Follow us on" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:477 +msgid "Post to Twitter" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:481 +msgid "Give us a good rating" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:488 +msgid "Wanna know more about the developers behind this plugin?" +msgstr "想知道更多关于这个插件背后的开发人员?" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:499 +msgid "Below is the current status of the critical features that you should activate on your site to achieve a minimum level of recommended security" +msgstr "为保证您的网站达到最低安全水平,建议激活以下关键功能。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:503 +msgid "Admin username" +msgstr "管理员用户名" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:533 +msgid "File permission" +msgstr "文件权限" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:548 +msgid "Basic firewall" +msgstr "基本防火墙" + +#: admin/wp-security-dashboard-menu.php:577 +msgid "No data found." +msgstr "未找到数据!" + +#: admin/wp-security-dashboard-menu.php:581 +msgid "Last 5 logins summary:" +msgstr "最后5次登录摘要:" + +#: admin/wp-security-dashboard-menu.php:585 +msgid "User" +msgstr "用户" + +#: admin/wp-security-dashboard-menu.php:586 +#: admin/wp-security-list-404.php:95 +#: admin/wp-security-list-login-fails.php:56 +#: admin/wp-security-list-permanent-blocked-ip.php:68 +msgid "Date" +msgstr "日期" + +#: admin/wp-security-dashboard-menu.php:587 +msgid "IP" +msgstr "IP地址" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:608 +msgid "Maintenance mode is currently enabled. Remember to turn it off when you are done" +msgstr "维护模式目前已启用。当您完成维护后,请关闭它。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:610 +msgid "Maintenance mode is currently off." +msgstr "维护模式目前已关闭。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:614 +msgid "Maintenance mode" +msgstr "维护模式" + +#: admin/wp-security-dashboard-menu.php:632 +msgid "Cookie based brute force" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:636 +#: admin/wp-security-dashboard-menu.php:654 +msgid "The %s feature is currently active." +msgstr "" + +#: admin/wp-security-dashboard-menu.php:637 +#: admin/wp-security-dashboard-menu.php:655 +msgid "Your new WordPress login URL is now:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:666 +msgid "Number of users currently logged into your site (including you) is:" +msgstr "当前登录您的网站 (包括您) 的用户数量为:" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:667 +msgid "There are no other users currently logged in." +msgstr "目前没有其他用户登陆。" + +#: admin/wp-security-dashboard-menu.php:680 +msgid "Number of users currently logged in site-wide (including you) is:" +msgstr "" + +#: admin/wp-security-dashboard-menu.php:681 +msgid "There are no other site-wide users currently logged in." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-dashboard-menu.php:694 +#: admin/wp-security-dashboard-menu.php:711 +msgid "Go to the %s menu to see more details" +msgstr "单击 %s 菜单,查看更多详细信息" + +#: admin/wp-security-dashboard-menu.php:707 +msgid "There are no IP addresses currently locked out." +msgstr "目前没有锁定的IP地址。" + +#: admin/wp-security-dashboard-menu.php:710 +msgid "Number of temporarily locked out IP addresses: " +msgstr "暂时锁定的 IP 地址数:" + +#: admin/wp-security-database-menu.php:52 +msgid "UpdraftPlus is installed but currently not active." +msgstr "" + +#: admin/wp-security-database-menu.php:52 +msgid "Follow this link to activate UpdraftPlus, to take a backup." +msgstr "" + +#: admin/wp-security-database-menu.php:57 +msgid "Follow this link to install UpdraftPlus, to take a database backup." +msgstr "" + +#: admin/wp-security-database-menu.php:87 +#: admin/wp-security-database-menu.php:92 +msgid "Database backup" +msgstr "数据备份" + +#: admin/wp-security-database-menu.php:91 +#: classes/grade-system/wp-security-feature-item-manager.php:65 +msgid "Database prefix" +msgstr "数据库前缀" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:119 +msgid "Database security" +msgstr "数据库安全" + +#: admin/wp-security-database-menu.php:147 +msgid "Nonce check failed for DB prefix change operation!" +msgstr "" + +#: admin/wp-security-database-menu.php:155 +msgid "The plugin has detected that it cannot write to the wp-config.php file. This feature can only be used if the plugin can successfully write to the wp-config.php file." +msgstr "" + +#: admin/wp-security-database-menu.php:168 +msgid "Please enter a value for the DB prefix." +msgstr "" + +#: admin/wp-security-database-menu.php:177 +msgid "ERROR: The table prefix can only contain numbers, letters, and underscores." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:186 +#: admin/wp-security-database-menu.php:245 +msgid "Change database prefix" +msgstr "更改数据库前缀" + +#: admin/wp-security-database-menu.php:189 +msgid "Your WordPress database is the most important asset of your website because it contains a lot of your site's precious information." +msgstr "" + +#: admin/wp-security-database-menu.php:190 +msgid "The database is also a target for hackers via methods such as SQL injections and malicious and automated code which targets certain tables." +msgstr "" + +#: admin/wp-security-database-menu.php:191 +msgid "One way to add a layer of protection for your DB is to change the default WordPress table prefix from \"wp_\" to something else which will be difficult for hackers to guess." +msgstr "" + +#: admin/wp-security-database-menu.php:192 +msgid "This feature allows you to easily change the prefix to a value of your choice or to a random value set by this plugin." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:198 +msgid "Database prefix options" +msgstr "数据库前缀选项" + +#: admin/wp-security-database-menu.php:210 +msgid "database backup" +msgstr "数据备份" + +#: admin/wp-security-database-menu.php:211 +msgid "It is recommended that you perform a %s before using this feature" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:221 +msgid "Current database table prefix" +msgstr "当前数据库表前缀" + +#: admin/wp-security-database-menu.php:227 +msgid "Your site is currently using the default WordPress database prefix value of \"wp_\"." +msgstr "" + +#: admin/wp-security-database-menu.php:227 +msgid "To increase your site's security you should consider changing the database prefix value to another value." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:234 +msgid "Generate new database table prefix" +msgstr "生成新的数据库表前缀" + +#: admin/wp-security-database-menu.php:238 +msgid "Check this if you want the plugin to generate a random 6 character string for the table prefix" +msgstr "" + +#: admin/wp-security-database-menu.php:239 +msgid "OR" +msgstr "" + +#: admin/wp-security-database-menu.php:241 +msgid "Choose your own database prefix by specifying a string which contains letters and/or numbers and/or underscores. Example: xyz_" +msgstr "" + +#: admin/wp-security-database-menu.php:265 +msgid "Take a database backup using UpdraftPlus" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-database-menu.php:270 +msgid "Manual backup" +msgstr "手动备份" + +#: admin/wp-security-database-menu.php:274 +msgid "UpdraftPlus Backup/Restore" +msgstr "" + +#: admin/wp-security-database-menu.php:274 +msgid "Your backups are on the UpdraftPlus Backup/Restore admin page." +msgstr "" + +#: admin/wp-security-database-menu.php:276 +msgid "Create database backup now" +msgstr "" + +#: admin/wp-security-database-menu.php:308 +msgid "Error - Could not get tables or no tables found!" +msgstr "" + +#: admin/wp-security-database-menu.php:312 +msgid "Starting DB prefix change operations....." +msgstr "" + +#: admin/wp-security-database-menu.php:314 +msgid "Your WordPress system has a total of %s tables and your new DB prefix will be: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:320 +#: classes/wp-security-utility.php:306 +msgid "Failed to make a backup of the wp-config.php file. This operation will not go ahead." +msgstr "" + +#: admin/wp-security-database-menu.php:324 +msgid "A backup copy of your wp-config.php file was created successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:351 +msgid "%s table name update failed" +msgstr "" + +#: admin/wp-security-database-menu.php:363 +msgid "Please change the prefix manually for the above tables to: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:366 +msgid "%s tables had their prefix updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:387 +msgid "wp-config.php file was updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:390 +msgid "The \"wp-config.php\" file was not able to be modified." +msgstr "" + +#: admin/wp-security-database-menu.php:390 +msgid "Please modify this file manually using your favourite editor and search for variable \"$table_prefix\" and assign the following value to that variable: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:401 +#: admin/wp-security-database-menu.php:420 +msgid "Update of table %s failed: unable to change %s to %s" +msgstr "" + +#: admin/wp-security-database-menu.php:405 +msgid "The options table records which had references to the old DB prefix were updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:424 +msgid "The %s table records which had references to the old DB prefix were updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:452 +msgid "Error updating user_meta table where new meta_key = %s, old meta_key = %s and user_id = %s." +msgstr "" + +#: admin/wp-security-database-menu.php:457 +msgid "The usermeta table records which had references to the old DB prefix were updated successfully!" +msgstr "" + +#: admin/wp-security-database-menu.php:459 +msgid "The database prefix change tasks have been completed." +msgstr "" + +#: admin/wp-security-database-menu.php:503 +msgid "Checking for MySQL tables of type \"view\"....." +msgstr "" + +#: admin/wp-security-database-menu.php:520 +msgid "Update of the following MySQL view definition failed: %s" +msgstr "" + +#: admin/wp-security-database-menu.php:527 +msgid "%s view definitions were updated successfully!" +msgstr "" + +#: admin/wp-security-filescan-menu.php:26 +#: classes/grade-system/wp-security-feature-item-manager.php:127 +msgid "File change detection" +msgstr "文件更改检测" + +#: admin/wp-security-filescan-menu.php:27 +msgid "Malware scan" +msgstr "" + +#: admin/wp-security-filescan-menu.php:88 +msgid "There have been no file changes since the last scan." +msgstr "自上次扫描以来,没有文件更改。" + +#: admin/wp-security-filescan-menu.php:98 +msgid "Nonce check failed for manual file change detection scan operation!" +msgstr "" + +#: admin/wp-security-filescan-menu.php:104 +msgid "There was an error during the file change detection scan. Please check the AIOS logs." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:110 +msgid "The plugin has detected that this is your first file change detection scan. The file details from this scan will be used to detect file changes for future scans." +msgstr "该插件检测到,这是您第一次进行文件更改检测扫描。此次扫描的详细信息将用于比对未来执行检测扫描。" + +#: admin/wp-security-filescan-menu.php:112 +msgid "Scan complete - There were no file changes detected!" +msgstr "" + +#: admin/wp-security-filescan-menu.php:133 +msgid "You entered a non numeric value for the \"backup time interval\" field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-filescan-menu.php:167 +msgid "The following address was removed because it is not a valid email address: " +msgstr "" + +#: admin/wp-security-filescan-menu.php:206 +msgid "NEW SCAN COMPLETED: The plugin has detected that you have made changes to the \"File Types To Ignore\" or \"Files To Ignore\" fields." +msgstr "" + +#: admin/wp-security-filescan-menu.php:206 +msgid "In order to ensure that future scan results are accurate, the old scan data has been refreshed." +msgstr "" + +#: admin/wp-security-filescan-menu.php:215 +msgid "All In One WP Security & Firewall has detected that there was a change in your host's files." +msgstr "" + +#: admin/wp-security-filescan-menu.php:217 +msgid "View scan details and clear this message" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:226 +msgid "If given an opportunity hackers can insert their code or files into your system which they can then use to carry out malicious acts on your site." +msgstr "如果有机会黑客可以传送他们的代码或文件到您的系统,那么他们就可以在您的网站进行恶意行为。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:227 +msgid "Being informed of any changes in your files can be a good way to quickly prevent a hacker from causing damage to your website." +msgstr "告知你的文件的任何更改是一个很好的方式,防止黑客伤害你的网站。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:228 +msgid "In general, WordPress core and plugin files and file types such as \".php\" or \".js\" should not change often and when they do, it is important that you are made aware when a change occurs and which file was affected." +msgstr "在一般情况下,WordPress 的核心和插件文件和文件类型,如 “.php” 或 “.js” 不应该经常改变,当他们发生变化后,你应该知道文件什么时候发生更改和哪个文件受到影响" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:229 +msgid "The \"File Change Detection Feature\" will notify you of any file change which occurs on your system, including the addition and deletion of files by performing a regular automated or manual scan of your system's files." +msgstr "“文件更改检测功能”将通知您系统上发生的任何文件更改,通过系统文件定期自动或手动扫描,发现添加和删除的任何文件。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:230 +msgid "This feature also allows you to exclude certain files or folders from the scan in cases where you know that they change often as part of their normal operation. (For example log files and certain caching plugin files may change often and hence you may choose to exclude such files from the file change detection scan)" +msgstr "某些特定的文件或文件夹正常运行时会自动改变,此功能允许您排除这些文件或文件夹扫描。(例如:日志文件和某些插件的缓存,可能经常发生更改,因此您可以将这些文件或文件夹从扫描中排除掉。)" + +#: admin/wp-security-filescan-menu.php:241 +msgid "It appears that your server is using an old PHP version which is missing the %s. The file scanner feature needs this class in order to work. If you would like to use this feature please upgrade your server PHP version to 5.3 or greater." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:249 +msgid "Manual file change detection scan" +msgstr "手动文件更改检测扫描" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:255 +msgid "To perform a manual file change detection scan click on the button below." +msgstr "要手动执行文件更改检测扫描,点击下面的按钮。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:258 +msgid "Perform scan now" +msgstr "立即执行扫描" + +#: admin/wp-security-filescan-menu.php:262 +msgid "View last saved file change results" +msgstr "查看上次保存的文件更改结果" + +#: admin/wp-security-filescan-menu.php:268 +msgid "Click the button below to view the saved file change results from the last scan." +msgstr "点击下面的按钮来查看从上次扫描保存的文件变化的结果。" + +#: admin/wp-security-filescan-menu.php:271 +msgid "View last file change" +msgstr "查看上次更改文件" + +#: admin/wp-security-filescan-menu.php:275 +msgid "File change detection settings" +msgstr "文件更改检测设置" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:287 +msgid "Enable automated file change detection scan" +msgstr "启用自动文件更改检测扫描" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:290 +msgid "Check this if you want the system to automatically/periodically scan your files to check for file changes based on the settings below" +msgstr "如果您希望系统根据以下设置自动/定期扫描文件以检查文件更改,请选中此项" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:294 +msgid "Scan time interval" +msgstr "扫描时间间隔" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:297 +msgid "Hours" +msgstr "小时" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:298 +msgid "Days" +msgstr "天" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:299 +msgid "Weeks" +msgstr "周" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:301 +msgid "Set the value for how often you would like a scan to occur" +msgstr "设置您希望扫描发生的频率的值" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:305 +msgid "File types to ignore" +msgstr "要忽略的文件类型" + +#: admin/wp-security-filescan-menu.php:308 +msgid "Enter each file type or extension on a new line which you wish to exclude from the file change detection scan." +msgstr "" + +#: admin/wp-security-filescan-menu.php:312 +msgid "You can exclude file types from the scan which would not normally pose any security threat if they were changed. These can include things such as image files." +msgstr "" + +#: admin/wp-security-filescan-menu.php:313 +msgid "Example: If you want the scanner to ignore files of type jpg, png, and bmp, then you would enter the following:" +msgstr "" + +#: admin/wp-security-filescan-menu.php:314 +msgid "jpg" +msgstr "" + +#: admin/wp-security-filescan-menu.php:315 +msgid "png" +msgstr "" + +#: admin/wp-security-filescan-menu.php:316 +msgid "bmp" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:322 +msgid "Files/Directories to ignore" +msgstr "要忽略的文件/目录" + +#: admin/wp-security-filescan-menu.php:325 +msgid "Enter each file or directory on a new line which you wish to exclude from the file change detection scan." +msgstr "" + +#: admin/wp-security-filescan-menu.php:329 +msgid "You can exclude specific files/directories from the scan which would not normally pose any security threat if they were changed. These can include things such as log files." +msgstr "" + +#: admin/wp-security-filescan-menu.php:330 +msgid "Example: If you want the scanner to ignore certain files in different directories or whole directories, then you would enter the following:" +msgstr "" + +#: admin/wp-security-filescan-menu.php:331 +msgid "cache/config/master.php" +msgstr "" + +#: admin/wp-security-filescan-menu.php:332 +msgid "somedirectory" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:339 +msgid "Send email when change detected" +msgstr "在检测到更改时发送邮件" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filescan-menu.php:343 +msgid "Check this if you want the system to email you if a file change was detected" +msgstr "如果您希望系统在检测到文件更改时向您发送电子邮件,请选中此项" + +#: admin/wp-security-filescan-menu.php:347 +msgid "Enter one or more email addresses on a new line." +msgstr "每个电子邮件单独一行" + +#: admin/wp-security-filescan-menu.php:364 +msgid "What is malware?" +msgstr "" + +#: admin/wp-security-filescan-menu.php:365 +msgid "The word malware stands for Malicious Software. It can consist of things like trojan horses, adware, worms, spyware and any other undesirable code which a hacker will try to inject into your website." +msgstr "" + +#: admin/wp-security-filescan-menu.php:366 +msgid "Often when malware code has been inserted into your site you will normally not notice anything out of the ordinary based on appearances, but it can have a dramatic effect on your site's search ranking." +msgstr "" + +#: admin/wp-security-filescan-menu.php:367 +msgid "This is because the bots and spiders from search engines such as Google have the capability to detect malware when they are indexing the pages on your site, and consequently they can blacklist your website which will in turn affect your search rankings." +msgstr "" + +#: admin/wp-security-filescan-menu.php:369 +msgid "CLICK HERE" +msgstr "" + +#: admin/wp-security-filescan-menu.php:371 +msgid "Scanning for malware" +msgstr "" + +#: admin/wp-security-filescan-menu.php:372 +msgid "Due to the constantly changing and complex nature of Malware, scanning for such things using a standalone plugin will not work reliably. This is something best done via an external scan of your site regularly." +msgstr "" + +#: admin/wp-security-filescan-menu.php:373 +msgid "This is why we have created an easy-to-use scanning service which is hosted off our own server which will scan your site for malware once every day and notify you if it finds anything." +msgstr "" + +#: admin/wp-security-filescan-menu.php:374 +msgid "When you sign up for this service you will get the following:" +msgstr "" + +#: admin/wp-security-filescan-menu.php:376 +msgid "Automatic daily scan of 1 website" +msgstr "" + +#: admin/wp-security-filescan-menu.php:377 +msgid "Automatic malware and blacklist monitoring" +msgstr "" + +#: admin/wp-security-filescan-menu.php:378 +msgid "Automatic email alerting" +msgstr "" + +#: admin/wp-security-filescan-menu.php:379 +msgid "Site uptime monitoring" +msgstr "" + +#: admin/wp-security-filescan-menu.php:380 +msgid "Site response time monitoring" +msgstr "" + +#: admin/wp-security-filescan-menu.php:381 +msgid "We provide advice for malware cleanup" +msgstr "" + +#: admin/wp-security-filescan-menu.php:382 +msgid "Blacklist removal" +msgstr "" + +#: admin/wp-security-filescan-menu.php:383 +msgid "No contract (cancel anytime)" +msgstr "" + +#: admin/wp-security-filescan-menu.php:385 +msgid "To learn more please %s." +msgstr "" + +#: admin/wp-security-filescan-menu.php:406 +msgid "Latest file change scan results" +msgstr "" + +#: admin/wp-security-filescan-menu.php:416 +msgid "The following files were added to your host." +msgstr "" + +#: admin/wp-security-filescan-menu.php:419 +#: admin/wp-security-filescan-menu.php:440 +#: admin/wp-security-filescan-menu.php:464 +msgid "File" +msgstr "" + +#: admin/wp-security-filescan-menu.php:420 +#: admin/wp-security-filescan-menu.php:441 +#: admin/wp-security-filescan-menu.php:465 +msgid "File size" +msgstr "" + +#: admin/wp-security-filescan-menu.php:421 +#: admin/wp-security-filescan-menu.php:442 +#: admin/wp-security-filescan-menu.php:466 +msgid "File modified" +msgstr "" + +#: admin/wp-security-filescan-menu.php:437 +msgid "The following files were removed from your host." +msgstr "" + +#: admin/wp-security-filescan-menu.php:461 +msgid "The following files were changed on your host." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:26 +#: classes/grade-system/wp-security-feature-item-manager.php:69 +msgid "File permissions" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:27 +msgid "PHP file editing" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:28 +msgid "WP file access" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:29 +msgid "Host system logs" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filesystem-menu.php:55 +msgid "Filesystem security" +msgstr "文件系统安全" + +#: admin/wp-security-filesystem-menu.php:80 +msgid "Nonce check failed for manual DB backup operation!" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:90 +msgid "The permissions for %s were successfully changed to %s" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:94 +msgid "Unable to change permissions for %s!" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:100 +msgid "File permissions scan" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:103 +msgid "Your WordPress file and folder permission settings govern the accessibility and read/write privileges of the files and folders which make up your WP installation." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:104 +msgid "Your WP installation already comes with reasonably secure file permission settings for the filesystem." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:105 +msgid "However, sometimes people or other plugins modify the various permission settings of certain core WP folders or files such that they end up making their site less secure because they chose the wrong permission values." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:106 +msgid "This feature will scan the critical WP core folders and files and will highlight any permission settings which are insecure." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:114 +msgid "This plugin has detected that your site is running on a Windows server." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:115 +msgid "This feature is not applicable for Windows server installations." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:121 +msgid "WP directory and file permissions scan results" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filesystem-menu.php:133 +#: admin/wp-security-filesystem-menu.php:152 +msgid "Name" +msgstr "名称" + +#: admin/wp-security-filesystem-menu.php:134 +#: admin/wp-security-filesystem-menu.php:153 +msgid "File/Folder" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:135 +#: admin/wp-security-filesystem-menu.php:154 +msgid "Current permissions" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:136 +#: admin/wp-security-filesystem-menu.php:155 +msgid "Recommended permissions" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:137 +#: admin/wp-security-filesystem-menu.php:156 +msgid "Recommended action" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:195 +msgid "Your PHP file editing settings were saved successfully." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:199 +msgid "Operation failed! Unable to modify or make a backup of wp-config.php file!" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:212 +#: classes/grade-system/wp-security-feature-item-manager.php:71 +msgid "File editing" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:215 +msgid "The WordPress Dashboard by default allows administrators to edit PHP files, such as plugin and theme files." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:216 +msgid "This is often the first tool an attacker will use if able to login, since it allows code execution." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:217 +msgid "This feature will disable the ability for people to edit PHP files via the dashboard." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:223 +msgid "Disable PHP file editing" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:235 +msgid "Disable ability to edit PHP files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:238 +msgid "Check this if you want to remove the ability for people to edit PHP files via the WP dashboard" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:282 +msgid "You have successfully saved the Prevent Access to Default WP Files configuration." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:286 +#: admin/wp-security-firewall-menu.php:126 +#: admin/wp-security-firewall-menu.php:346 +#: admin/wp-security-firewall-menu.php:613 +#: admin/wp-security-firewall-menu.php:912 +#: admin/wp-security-settings-menu.php:772 +#: admin/wp-security-spam-menu.php:124 +msgid "Could not write to the .htaccess file. Please check the file permissions." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:291 +msgid "WordPress files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:294 +msgid "This feature allows you to prevent access to files such as %s, %s and %s which are delivered with all WP installations." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:295 +msgid "By preventing access to these files you are hiding some key pieces of information (such as WordPress version info) from potential hackers." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:300 +msgid "Prevent access to default WP files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:311 +msgid "Prevent access to WP default install files" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:314 +msgid "Check this if you want to prevent access to readme.html, license.txt and wp-config-sample.php." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:318 +msgid "Save setting" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:342 +msgid "System logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:345 +msgid "Sometimes your hosting platform will produce error or warning logs in a file called \"error_log\"." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:346 +msgid "Depending on the nature and cause of the error or warning, your hosting server can create multiple instances of this file in numerous directory locations of your WordPress installation." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:347 +msgid "By occasionally viewing the contents of these logs files you can keep informed of any underlying problems on your system which you might need to address." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:353 +msgid "View system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:355 +msgid "Please click the button below to view the latest system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:358 +msgid "Enter System Log File Name" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:360 +msgid "Enter your system log file name. (Defaults to error_log)" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:363 +msgid "View latest system logs" +msgstr "" + +#: admin/wp-security-filesystem-menu.php:365 +msgid "Loading..." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:382 +msgid "No system logs were found." +msgstr "" + +#: admin/wp-security-filesystem-menu.php:435 +msgid "Set recommended permissions" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-filesystem-menu.php:441 +msgid "No action required" +msgstr "无需执行任何操作。" + +#: admin/wp-security-filesystem-menu.php:481 +msgid "Showing latest entries of error_log file: %s" +msgstr "" + +#: admin/wp-security-firewall-menu.php:28 +msgid "Basic firewall rules" +msgstr "基本防火墙规则" + +#: admin/wp-security-firewall-menu.php:29 +msgid "Additional firewall rules" +msgstr "其他防火墙规则" + +#: admin/wp-security-firewall-menu.php:30 +msgid "6G Blacklist firewall rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:31 +msgid "Internet bots" +msgstr "网络机器人" + +#: admin/wp-security-firewall-menu.php:32 +msgid "Prevent hotlinks" +msgstr "防止热链接" + +#: admin/wp-security-firewall-menu.php:33 +msgid "404 detection" +msgstr "404检测" + +#: admin/wp-security-firewall-menu.php:34 +msgid "Custom rules" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:122 +#: admin/wp-security-firewall-menu.php:908 +#: admin/wp-security-spam-menu.php:120 +#: admin/wp-security-spam-menu.php:494 +#: admin/wp-security-spam-menu.php:556 +#: admin/wp-security-user-registration-menu.php:95 +msgid "Settings were successfully saved" +msgstr "设置已成功保存" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:131 +#: admin/wp-security-firewall-menu.php:651 +msgid "Firewall settings" +msgstr "防火墙设置" + +#: admin/wp-security-firewall-menu.php:138 +msgid "This should not have any impact on your site's general functionality but if you wish you can take a %s of your .htaccess file before proceeding." +msgstr "" + +#: admin/wp-security-firewall-menu.php:139 +msgid "The features in this tab allow you to activate some basic firewall security protection rules for your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:140 +msgid "The firewall functionality is achieved via the insertion of special code into your currently active .htaccess file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:151 +msgid "You have enabled the \"Completely Block Access To XMLRPC\" checkbox which means all XMLRPC functionality will be blocked." +msgstr "" + +#: admin/wp-security-firewall-menu.php:152 +msgid "By leaving this feature enabled you will prevent Jetpack or Wordpress iOS or other apps which need XMLRPC from working correctly on your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:153 +msgid "If you still need XMLRPC then uncheck the \"Completely Block Access To XMLRPC\" checkbox and enable only the \"Disable Pingback Functionality From XMLRPC\" checkbox." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:163 +msgid "Basic firewall settings" +msgstr "基本防火墙设置" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:171 +msgid "Enable basic firewall protection" +msgstr "启用基本防火墙保护" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:174 +msgid "Check this if you want to apply basic firewall protection to your site." +msgstr "如果你想对网站采用基本防火墙保护,请选中此项。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:178 +msgid "This setting will implement the following basic firewall protection mechanisms on your site:" +msgstr "此设置将在您的网站上实施以下基本防火墙保护机制:" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:179 +msgid "1) Protect your htaccess file by denying access to it." +msgstr "1)通过拒绝访问,保护你的 htaccess 文件。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:180 +msgid "2) Disable the server signature." +msgstr "2) 禁用服务器签名." + +#: admin/wp-security-firewall-menu.php:181 +msgid "3) Limit file upload size (%sMB)." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:182 +msgid "4) Protect your wp-config.php file by denying access to it." +msgstr "4)通过拒绝访问,保护你的 wp-config.php 文件。" + +#: admin/wp-security-firewall-menu.php:183 +msgid "The above firewall features will be applied via your .htaccess file and should not affect your site's overall functionality." +msgstr "" + +#: admin/wp-security-firewall-menu.php:184 +msgid "You are still advised to take a backup of your active .htaccess file just in case." +msgstr "" + +#: admin/wp-security-firewall-menu.php:190 +msgid "Max file upload size (MB)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:192 +msgid "The value for the maximum file upload size used in the .htaccess file. (Defaults to %sMB if left blank)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:200 +msgid "WordPress XMLRPC and pingback vulnerability protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:208 +msgid "Completely block access to XMLRPC" +msgstr "" + +#: admin/wp-security-firewall-menu.php:211 +msgid "Check this if you are not using the WP XML-RPC functionality and you want to completely block external access to XMLRPC." +msgstr "" + +#: admin/wp-security-firewall-menu.php:215 +msgid "This setting will add a directive in your .htaccess to disable access to the WordPress xmlrpc.php file which is responsible for the XML-RPC functionality in WordPress." +msgstr "" + +#: admin/wp-security-firewall-menu.php:216 +msgid "Hackers can exploit various vulnerabilities in the WordPress XML-RPC API in a number of ways such as:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:217 +msgid "1) Denial of Service (DoS) attacks" +msgstr "" + +#: admin/wp-security-firewall-menu.php:218 +msgid "2) Hacking internal routers." +msgstr "" + +#: admin/wp-security-firewall-menu.php:219 +msgid "3) Scanning ports in internal networks to get info from various hosts." +msgstr "" + +#: admin/wp-security-firewall-menu.php:220 +msgid "Apart from the security protection benefit, this feature may also help reduce load on your server, particularly if your site currently has a lot of unwanted traffic hitting the XML-RPC API on your installation." +msgstr "" + +#: admin/wp-security-firewall-menu.php:221 +msgid "NOTE: You should only enable this feature if you are not currently using the XML-RPC functionality on your WordPress installation." +msgstr "" + +#: admin/wp-security-firewall-menu.php:222 +msgid "Leave this feature disabled and use the feature below if you want pingback protection but you still need XMLRPC." +msgstr "" + +#: admin/wp-security-firewall-menu.php:228 +msgid "Disable pingback functionality from XMLRPC" +msgstr "" + +#: admin/wp-security-firewall-menu.php:231 +msgid "If you use Jetpack or WP iOS or other apps which need WP XML-RPC functionality then check this. This will enable protection against WordPress pingback vulnerabilities." +msgstr "" + +#: admin/wp-security-firewall-menu.php:235 +msgid "NOTE: If you use Jetpack or the Wordpress iOS or other apps then you should enable this feature but leave the \"Completely Block Access To XMLRPC\" checkbox unchecked." +msgstr "" + +#: admin/wp-security-firewall-menu.php:236 +msgid "The feature will still allow XMLRPC functionality on your site but will disable the pingback methods." +msgstr "" + +#: admin/wp-security-firewall-menu.php:237 +msgid "This feature will also remove the \"X-Pingback\" header if it is present." +msgstr "" + +#: admin/wp-security-firewall-menu.php:246 +msgid "Block access to debug log file" +msgstr "" + +#: admin/wp-security-firewall-menu.php:254 +msgid "Block access to debug.log file" +msgstr "" + +#: admin/wp-security-firewall-menu.php:257 +msgid "Check this if you want to block access to the debug.log file that WordPress creates when debug logging is enabled." +msgstr "" + +#: admin/wp-security-firewall-menu.php:261 +msgid "WordPress has an option to turn on the debug logging to a file located in wp-content/debug.log. This file may contain sensitive information." +msgstr "" + +#: admin/wp-security-firewall-menu.php:262 +msgid "Using this option will block external access to this file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:262 +msgid "You can still access this file by logging into your site via FTP." +msgstr "" + +#: admin/wp-security-firewall-menu.php:270 +msgid "Save basic firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:342 +msgid "You have successfully saved the Additional Firewall Protection configuration" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-firewall-menu.php:356 +msgid "Additional firewall protection" +msgstr "其他防火墙保护" + +#: admin/wp-security-firewall-menu.php:360 +msgid "Due to the nature of the code being inserted to the .htaccess file, this feature may break some functionality for certain plugins and you are therefore advised to take a %s of .htaccess before applying this configuration." +msgstr "" + +#: admin/wp-security-firewall-menu.php:362 +msgid "This feature allows you to activate more advanced firewall settings to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:363 +msgid "The advanced firewall rules are applied via the insertion of special code to your currently active .htaccess file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:372 +msgid "Listing of directory contents" +msgstr "" + +#: admin/wp-security-firewall-menu.php:381 +#: classes/grade-system/wp-security-feature-item-manager.php:85 +msgid "Disable index views" +msgstr "" + +#: admin/wp-security-firewall-menu.php:384 +msgid "Check this if you want to disable directory and file listing." +msgstr "" + +#: admin/wp-security-firewall-menu.php:389 +msgid "By default, an Apache server will allow the listing of the contents of a directory if it doesn't contain an index.php file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:391 +msgid "This feature will prevent the listing of contents for all directories." +msgstr "" + +#: admin/wp-security-firewall-menu.php:393 +msgid "NOTE: In order for this feature to work \"AllowOverride\" of the Indexes directive must be enabled in your httpd.conf file. Ask your hosting provider to check this if you don't have access to httpd.conf" +msgstr "" + +#: admin/wp-security-firewall-menu.php:402 +msgid "Trace and track" +msgstr "" + +#: admin/wp-security-firewall-menu.php:411 +#: classes/grade-system/wp-security-feature-item-manager.php:86 +msgid "Disable trace and track" +msgstr "" + +#: admin/wp-security-firewall-menu.php:414 +msgid "Check this if you want to disable trace and track." +msgstr "" + +#: admin/wp-security-firewall-menu.php:419 +msgid "HTTP Trace attack (XST) can be used to return header requests and grab cookies and other information." +msgstr "" + +#: admin/wp-security-firewall-menu.php:421 +msgid "This hacking technique is usually used together with cross site scripting attacks (XSS)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:423 +msgid "Disabling trace and track on your site will help prevent HTTP Trace attacks." +msgstr "" + +#: admin/wp-security-firewall-menu.php:432 +msgid "Proxy comment posting" +msgstr "" + +#: admin/wp-security-firewall-menu.php:442 +msgid "Forbid proxy comment posting" +msgstr "" + +#: admin/wp-security-firewall-menu.php:445 +msgid "Check this if you want to forbid proxy comment posting." +msgstr "" + +#: admin/wp-security-firewall-menu.php:450 +msgid "This setting will deny any requests that use a proxy server when posting comments." +msgstr "" + +#: admin/wp-security-firewall-menu.php:451 +msgid "By forbidding proxy comments you are in effect eliminating some spam and other proxy requests." +msgstr "" + +#: admin/wp-security-firewall-menu.php:460 +msgid "Bad query strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:470 +msgid "Deny bad query strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:473 +msgid "This will help protect you against malicious queries via XSS." +msgstr "" + +#: admin/wp-security-firewall-menu.php:478 +msgid "This feature will write rules in your .htaccess file to prevent malicious string attacks on your site using XSS." +msgstr "" + +#: admin/wp-security-firewall-menu.php:479 +msgid "NOTE: Some of these strings might be used for plugins or themes and hence this might break some functionality." +msgstr "" + +#: admin/wp-security-firewall-menu.php:480 +#: admin/wp-security-firewall-menu.php:510 +msgid "You are therefore strongly advised to take a backup of your active .htaccess file before applying this feature." +msgstr "" + +#: admin/wp-security-firewall-menu.php:489 +#: classes/grade-system/wp-security-feature-item-manager.php:89 +msgid "Advanced character string filter" +msgstr "" + +#: admin/wp-security-firewall-menu.php:499 +msgid "Enable advanced character string filter" +msgstr "" + +#: admin/wp-security-firewall-menu.php:502 +msgid "This will block bad character matches from XSS." +msgstr "" + +#: admin/wp-security-firewall-menu.php:507 +msgid "This is an advanced character string filter to prevent malicious string attacks on your site coming from Cross Site Scripting (XSS)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:508 +msgid "This setting matches for common malicious string patterns and exploits and will produce a 403 error for the hacker attempting the query." +msgstr "" + +#: admin/wp-security-firewall-menu.php:509 +msgid "NOTE: Some strings for this setting might break some functionality." +msgstr "" + +#: admin/wp-security-firewall-menu.php:518 +msgid "Save additional firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:609 +msgid "You have successfully saved the 5G/6G Firewall Protection configuration" +msgstr "" + +#: admin/wp-security-firewall-menu.php:633 +msgid "All in One WP Security and Firewall" +msgstr "" + +#: admin/wp-security-firewall-menu.php:634 +msgid "We were unable to access the firewall's configuration file:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:636 +msgid "As a result, the firewall will be unavailable." +msgstr "" + +#: admin/wp-security-firewall-menu.php:637 +msgid "Please check your PHP error log for further information." +msgstr "" + +#: admin/wp-security-firewall-menu.php:638 +msgid "If you're unable to locate your PHP log file, please contact your web hosting company to ask them where it can be found on their setup." +msgstr "" + +#: admin/wp-security-firewall-menu.php:655 +msgid "This feature allows you to activate the %s (or legacy %s) firewall security protection rules designed and produced by %s." +msgstr "" + +#: admin/wp-security-firewall-menu.php:656 +msgid "The 6G Blacklist is updated and improved version of 5G Blacklist. If you have 5G Blacklist active, you might consider activating 6G Blacklist instead." +msgstr "" + +#: admin/wp-security-firewall-menu.php:657 +msgid "The 6G Blacklist is a simple, flexible blacklist that helps reduce the number of malicious URL requests that hit your website." +msgstr "" + +#: admin/wp-security-firewall-menu.php:658 +msgid "The added advantage of applying the 6G firewall to your site is that it has been tested and confirmed by the people at PerishablePress.com to be an optimal and least disruptive set of .htaccess security rules for general WP sites running on an Apache server or similar." +msgstr "" + +#: admin/wp-security-firewall-menu.php:659 +msgid "Therefore the 6G firewall rules should not have any impact on your site's general functionality but if you wish you can take a %s of your .htaccess file before proceeding." +msgstr "" + +#: admin/wp-security-firewall-menu.php:665 +msgid "6G blacklist/firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:677 +msgid "Enable 6G firewall protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:680 +msgid "Check this if you want to apply the 6G Blacklist firewall protection from perishablepress.com to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:684 +msgid "This setting will implement the 6G security firewall protection mechanisms on your site which include the following things:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:685 +#: admin/wp-security-firewall-menu.php:703 +msgid "1) Block forbidden characters commonly used in exploitative attacks." +msgstr "" + +#: admin/wp-security-firewall-menu.php:686 +#: admin/wp-security-firewall-menu.php:704 +msgid "2) Block malicious encoded URL characters such as the \".css(\" string." +msgstr "" + +#: admin/wp-security-firewall-menu.php:687 +#: admin/wp-security-firewall-menu.php:705 +msgid "3) Guard against the common patterns and specific exploits in the root portion of targeted URLs." +msgstr "" + +#: admin/wp-security-firewall-menu.php:688 +#: admin/wp-security-firewall-menu.php:706 +msgid "4) Stop attackers from manipulating query strings by disallowing illicit characters." +msgstr "" + +#: admin/wp-security-firewall-menu.php:689 +#: admin/wp-security-firewall-menu.php:707 +msgid "....and much more." +msgstr "" + +#: admin/wp-security-firewall-menu.php:695 +msgid "Enable legacy 5G firewall protection" +msgstr "" + +#: admin/wp-security-firewall-menu.php:698 +msgid "Check this if you want to apply the 5G Blacklist firewall protection from perishablepress.com to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:702 +msgid "This setting will implement the 5G security firewall protection mechanisms on your site which include the following things:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:713 +msgid "Save 5G/6G firewall settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:721 +msgid "6G block request methods" +msgstr "" + +#: admin/wp-security-firewall-menu.php:725 +msgid "HTTP Request methods are used by browsers and clients to communicate with servers to get responses." +msgstr "" + +#: admin/wp-security-firewall-menu.php:726 +msgid "GET and POST are the most commonly used methods to request and submit data for specified resources of the server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:732 +msgid "Block %s method" +msgstr "" + +#: admin/wp-security-firewall-menu.php:735 +msgid "Check this to block the %s request method" +msgstr "" + +#: admin/wp-security-firewall-menu.php:740 +msgid "Some WooCommerce extensions use the PUT request method in addition to GET and POST." +msgstr "" + +#: admin/wp-security-firewall-menu.php:740 +msgid "This means WooCommerce users shouldn't block the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:741 +msgid "A few REST requests use the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:741 +msgid "If your site is communicated by the WP REST API, you should not block the PUT request method." +msgstr "" + +#: admin/wp-security-firewall-menu.php:749 +msgid "Save request methods settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:757 +msgid "6G other settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:761 +msgid "Block query strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:764 +msgid "Check this to block all query strings recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:768 +msgid "Block request strings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:771 +msgid "Check this to block all request strings recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:775 +msgid "Block referrers" +msgstr "" + +#: admin/wp-security-firewall-menu.php:778 +msgid "Check this to block all referrers recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:782 +msgid "Block user-agents" +msgstr "" + +#: admin/wp-security-firewall-menu.php:785 +msgid "Check this to block all user-agents recommended by 6G" +msgstr "" + +#: admin/wp-security-firewall-menu.php:789 +msgid "Save other settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:823 +msgid "The Internet bot settings were successfully saved" +msgstr "" + +#: admin/wp-security-firewall-menu.php:827 +msgid "Internet bot settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:833 +msgid "What is an Internet Bot" +msgstr "" + +#: admin/wp-security-firewall-menu.php:834 +msgid "%s?" +msgstr "" + +#: admin/wp-security-firewall-menu.php:836 +msgid "A bot is a piece of software which runs on the Internet and performs automatic tasks. For example when Google indexes your pages it uses automatic bots to achieve this task." +msgstr "" + +#: admin/wp-security-firewall-menu.php:837 +msgid "A lot of bots are legitimate and non-malicious but not all bots are good and often you will find some which try to impersonate legitimate bots such as \"Googlebot\" but in reality they have nohing to do with Google at all." +msgstr "" + +#: admin/wp-security-firewall-menu.php:838 +msgid "Although most of the bots out there are relatively harmless sometimes website owners want to have more control over which bots they allow into their site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:839 +msgid "This feature allows you to block bots which are impersonating as a Googlebot but actually aren't. (In other words they are fake Google bots)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:840 +msgid "Googlebots have a unique identity which cannot easily be forged and this feature will identify any fake Google bots and block them from reading your site's pages." +msgstr "" + +#: admin/wp-security-firewall-menu.php:846 +msgid "Attention: Sometimes non-malicious Internet organizations might have bots which impersonate as a \"Googlebot\"." +msgstr "" + +#: admin/wp-security-firewall-menu.php:847 +msgid "Just be aware that if you activate this feature the plugin will block all bots which use the \"Googlebot\" string in their User Agent information but are NOT officially from Google (irrespective whether they are malicious or not)." +msgstr "" + +#: admin/wp-security-firewall-menu.php:848 +msgid "All other bots from other organizations such as \"Yahoo\", \"Bing\" etc will not be affected by this feature." +msgstr "" + +#: admin/wp-security-firewall-menu.php:854 +#: admin/wp-security-firewall-menu.php:864 +#: classes/grade-system/wp-security-feature-item-manager.php:93 +msgid "Block fake Googlebots" +msgstr "" + +#: admin/wp-security-firewall-menu.php:867 +msgid "Check this if you want to block all fake Googlebots." +msgstr "" + +#: admin/wp-security-firewall-menu.php:871 +msgid "This feature will check if the User Agent information of a bot contains the string \"Googlebot\"." +msgstr "" + +#: admin/wp-security-firewall-menu.php:872 +msgid "It will then perform a few tests to verify if the bot is legitimately from Google and if so it will allow the bot to proceed." +msgstr "" + +#: admin/wp-security-firewall-menu.php:873 +msgid "If the bot fails the checks then the plugin will mark it as being a fake Googlebot and it will block it" +msgstr "" + +#: admin/wp-security-firewall-menu.php:880 +msgid "Save internet bot settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:916 +#: admin/wp-security-firewall-menu.php:938 +#: classes/grade-system/wp-security-feature-item-manager.php:95 +msgid "Prevent image hotlinking" +msgstr "" + +#: admin/wp-security-firewall-menu.php:919 +msgid "A Hotlink is where someone displays an image on their site which is actually located on your site by using a direct link to the source of the image on your server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:920 +msgid "Due to the fact that the image being displayed on the other person's site is coming from your server, this can cause leaking of bandwidth and resources for you because your server has to present this image for the people viewing it on someone elses's site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:921 +msgid "This feature will prevent people from directly hotlinking images from your site's pages by writing some directives in your .htaccess file." +msgstr "" + +#: admin/wp-security-firewall-menu.php:926 +msgid "Prevent hotlinking" +msgstr "" + +#: admin/wp-security-firewall-menu.php:941 +msgid "Check this if you want to prevent hotlinking to images on your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:961 +msgid "Nonce check failed for delete all 404 event logs operation!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:972 +msgid "404 Detection Feature - Delete all 404 event logs operation failed!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:976 +msgid "All 404 event logs were deleted from the DB successfully!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1000 +msgid "You entered a non numeric value for the lockout time length field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1006 +msgid "You entered an incorrect format for the \"Redirect URL\" field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1039 +msgid "404 detection configuration" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1042 +msgid "A 404 or Not Found error occurs when somebody tries to access a non-existent page on your website." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1043 +msgid "Typically, most 404 errors happen quite innocently when people have mis-typed a URL or used an old link to page which doesn't exist anymore." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1044 +msgid "However, in some cases you may find many repeated 404 errors which occur in a relatively short space of time and from the same IP address which are all attempting to access a variety of non-existent page URLs." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1045 +msgid "Such behaviour can mean that a hacker might be trying to find a particular page or URL for sinister reasons." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1046 +msgid "This feature allows you to monitor all 404 events which occur on your site, and it also gives you the option of blocking IP addresses for a configured length of time." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1047 +msgid "If you want to temporarily block or blacklist an IP address, simply click the \"Temp Block\" or \"Blacklist IP\" link for the applicable IP entry in the \"404 Event Logs\" table below." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1071 +msgid "404 detection options" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1083 +msgid "Enable 404 IP detection and lockout" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1086 +msgid "Check this if you want to enable the lockout of selected IP addresses." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1091 +msgid "When you enable this checkbox, all 404 events on your site will be logged in the table below. You can monitor these events and select some IP addresses listed in the table below and block them for a specified amount of time. All IP addresses you select to be blocked from the \"404 Event Logs\" table section will be unable to access your site during the time specified." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1099 +msgid "Enable 404 event logging" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1102 +msgid "Check this if you want to enable the logging of 404 events" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1107 +msgid "Time length of 404 lockout (minutes)" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1109 +msgid "Set the length of time for which a blocked IP address will be prevented from visiting your site" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1114 +msgid "You can lock any IP address which is recorded in the \"404 Event Logs\" table section below." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1116 +msgid "To temporarily lock an IP address, hover over the ID column and click the \"Temp Block\" link for the applicable IP entry." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1123 +msgid "404 lockout redirect URL" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1125 +msgid "A blocked visitor will be automatically redirected to this URL." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1135 +msgid "This list displays the 404 event logs when somebody tries to access a non-existent page on your website." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1136 +msgid "404 event logs that are older than %1$d days are purged automatically." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1141 +msgid "404 event logs" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1163 +#: admin/wp-security-firewall-menu.php:1172 +#: admin/wp-security-user-login-menu.php:495 +#: admin/wp-security-user-login-menu.php:504 +#: admin/wp-security-user-login-menu.php:653 +#: admin/wp-security-user-login-menu.php:662 +msgid "Export to CSV" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1169 +#: admin/wp-security-user-login-menu.php:501 +#: admin/wp-security-user-login-menu.php:659 +msgid "Click this button if you wish to download this log in CSV format." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1176 +#: admin/wp-security-firewall-menu.php:1185 +msgid "Delete all 404 event logs" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1182 +msgid "Click this button if you wish to purge all 404 event logs from the DB." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1241 +msgid "Custom .htaccess rules settings" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1248 +msgid "This feature can be used to apply your own custom .htaccess rules and directives." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1249 +msgid "It is useful for when you want to tweak our existing firewall rules or when you want to add your own." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1250 +msgid "NOTE: This feature can only be used if your site is hosted in an apache or similar web server." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1256 +msgid "Warning: Only use this feature if you know what you are doing." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1257 +msgid "Incorrect .htaccess rules or directives can break or prevent access to your site." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1258 +msgid "It is your responsibility to ensure that you are entering the correct code!" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1259 +msgid "If you break your site you will need to access your server via FTP or something similar and then edit your .htaccess file and delete the changes you made." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1265 +msgid "Custom .htaccess rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1269 +msgid "Enable custom .htaccess rules" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1272 +msgid "Check this if you want to enable custom rules entered in the text box below" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1276 +msgid "Place custom rules at the top" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1279 +msgid "Check this if you want to place your custom rules at the beginning of all the rules applied by this plugin" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1283 +msgid "Enter custom .htaccess rules:" +msgstr "" + +#: admin/wp-security-firewall-menu.php:1287 +msgid "Enter your custom .htaccess rules/directives." +msgstr "" + +#: admin/wp-security-firewall-menu.php:1292 +msgid "Save custom rules" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:338 +#: admin/wp-security-firewall-setup-notice.php:407 +#: admin/wp-security-firewall-setup-notice.php:479 +#: admin/wp-security-firewall-setup-notice.php:595 +#: wp-security.php:43 +msgid "All In One WP Security and Firewall" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:340 +msgid "We were unable to create the file necessary to give you the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:341 +msgid "Your firewall will have reduced protection which means some of your firewall's functionality will be unavailable." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:342 +msgid "If you would like to manually set up the necessary file, please follow these steps:" +msgstr "" + +#. translators: %s Bootstrap file name. +#. translators: %s Firewall file name. +#: admin/wp-security-firewall-setup-notice.php:346 +#: admin/wp-security-firewall-setup-notice.php:453 +msgid "1. Create a file with the name %s in the same directory as your WordPress install is in, i.e.:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:350 +msgid "2. Paste in the following code:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:352 +#: admin/wp-security-firewall-setup-notice.php:462 +msgid "3. Save the file and press the 'Try again' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:372 +msgid "1. Open the following file:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:378 +msgid "2. Look for the auto_prepend_file directive." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:382 +msgid "2. Look for the following:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:388 +msgid "3. Change it to the following:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:392 +msgid "4. Save the file and press the 'Try again' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:392 +#: admin/wp-security-firewall-setup-notice.php:441 +msgid "You may have to wait up to 5 minutes before the settings take effect." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:410 +msgid "Your firewall has been installed with the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:411 +msgid "You may have to wait 5 minutes for the changes to take effect." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:434 +msgid "1. Open your php.ini file." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:437 +msgid "2. Set the auto_prepend_file directive like below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:441 +msgid "3. Restart the webserver and refresh the page" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:458 +msgid "2. Paste in the following directives:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:482 +msgid "We were unable to set up your firewall with the highest level of protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:483 +msgid "Your firewall will have reduced functionality." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:487 +msgid "To give your site the highest level of protection, please follow these steps:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:500 +msgid "Note: if you're unable to perform any of the aforementioned steps, please ask your web hosting provider for further assistance." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:517 +msgid "Try again" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:539 +msgid "We have detected that your AIOS firewall is not fully installed, and therefore does not have the highest level of protection. " +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:540 +msgid "Your firewall will have reduced functionality until it has been upgraded. " +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:542 +msgid "Upgrade your protection now" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:598 +msgid "Our PHP-based firewall has been created to give you even greater protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:602 +msgid "If you already have our .htaccess-based firewall enabled, you will still need to set up the PHP-based firewall to benefit from its protection." +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:605 +msgid "To set up the PHP-based firewall, press the 'Set up now' button below:" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:608 +msgid "Set up now" +msgstr "" + +#: admin/wp-security-firewall-setup-notice.php:614 +#: templates/notices/custom-notice.php:10 +#: templates/notices/custom-notice.php:12 +#: templates/notices/horizontal-notice.php:50 +#: templates/notices/horizontal-notice.php:52 +#: templates/notices/htaccess-to-php-feature-notice.php:10 +#: templates/notices/htaccess-to-php-feature-notice.php:12 +msgid "Dismiss" +msgstr "" + +#: admin/wp-security-list-404.php:91 +msgid "Event type" +msgstr "" + +#: admin/wp-security-list-404.php:92 +#: admin/wp-security-list-logged-in-users.php:46 +#: admin/wp-security-list-registered-users.php:74 +msgid "IP address" +msgstr "" + +#: admin/wp-security-list-404.php:93 +msgid "Attempted URL" +msgstr "" + +#: admin/wp-security-list-404.php:94 +msgid "Referer" +msgstr "" + +#: admin/wp-security-list-404.php:96 +msgid "Lock status" +msgstr "" + +#: admin/wp-security-list-404.php:118 +msgid "Temp block IP" +msgstr "" + +#: admin/wp-security-list-404.php:119 +msgid "Blacklist IP" +msgstr "" + +#: admin/wp-security-list-404.php:120 +#: admin/wp-security-list-acct-activity.php:82 +#: admin/wp-security-list-locked-ip.php:37 +#: admin/wp-security-list-locked-ip.php:84 +#: admin/wp-security-list-login-fails.php:73 +#: admin/wp-security-list-registered-users.php:93 +msgid "Delete" +msgstr "" + +#: admin/wp-security-list-404.php:128 +#: admin/wp-security-list-404.php:136 +#: admin/wp-security-list-404.php:143 +#: admin/wp-security-list-acct-activity.php:92 +#: admin/wp-security-list-comment-spammer-ip.php:95 +#: admin/wp-security-list-locked-ip.php:97 +#: admin/wp-security-list-locked-ip.php:105 +#: admin/wp-security-list-login-fails.php:85 +#: admin/wp-security-list-permanent-blocked-ip.php:96 +#: admin/wp-security-list-registered-users.php:107 +#: admin/wp-security-list-registered-users.php:115 +#: admin/wp-security-list-registered-users.php:123 +msgid "Please select some records using the checkboxes" +msgstr "" + +#: admin/wp-security-list-404.php:278 +msgid "Nonce check failed for delete selected 404 event logs operation!" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:35 +msgid "Are you sure you want to delete this item?" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:46 +msgid "Login session still active" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:60 +#: admin/wp-security-list-locked-ip.php:60 +#: admin/wp-security-list-logged-in-users.php:44 +#: admin/wp-security-list-login-fails.php:54 +#: admin/wp-security-list-registered-users.php:69 +msgid "User ID" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:61 +#: admin/wp-security-list-locked-ip.php:61 +#: admin/wp-security-list-login-fails.php:55 +msgid "Username" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:62 +msgid "Login date" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:63 +msgid "Logout date" +msgstr "" + +#: admin/wp-security-list-acct-activity.php:136 +msgid "Nonce check failed for delete selected account activity logs operation!" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:59 +msgid "Spammer IP" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:60 +msgid "Number of spam comments from this IP" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:61 +msgid "Status" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:81 +msgid "Block" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:130 +#: admin/wp-security-list-comment-spammer-ip.php:179 +msgid "Nonce check failed for delete selected blocked IP operation!" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:137 +msgid "The selected IP addresses are now permanently blocked!" +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:193 +msgid "The selected IP addresses were saved in the blacklist configuration settings." +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:201 +msgid "The .htaccess file was successfully modified to include the selected IP addresses." +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:212 +msgid "NOTE: The .htaccess file was not modified because you have disabled the \"Enable IP or User Agent Blacklisting\" check box." +msgstr "" + +#: admin/wp-security-list-comment-spammer-ip.php:213 +msgid "To block these IP addresses you will need to enable the above flag in the %s menu" +msgstr "" + +#: admin/wp-security-list-debug.php:47 +msgid "Level" +msgstr "" + +#: admin/wp-security-list-debug.php:48 +msgid "Message" +msgstr "" + +#: admin/wp-security-list-debug.php:49 +msgid "Type" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:36 +#: admin/wp-security-list-locked-ip.php:83 +msgid "Unlock" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:59 +msgid "Locked IP/range" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:62 +#: admin/wp-security-list-permanent-blocked-ip.php:67 +msgid "Reason" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:63 +msgid "Date locked" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:64 +msgid "Release date" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:134 +msgid "The selected IP entries were unlocked successfully." +msgstr "选定的IP条目被成功解锁." + +#: admin/wp-security-list-locked-ip.php:140 +msgid "Nonce check failed for unlock IP operation!" +msgstr "" + +#: admin/wp-security-list-locked-ip.php:147 +msgid "The selected IP entry was unlocked successfully." +msgstr "" + +#: admin/wp-security-list-logged-in-users.php:45 +#: admin/wp-security-list-registered-users.php:70 +msgid "Login name" +msgstr "" + +#: admin/wp-security-list-logged-in-users.php:87 +msgid "Nonce check failed for force user logout operation!" +msgstr "" + +#: admin/wp-security-list-logged-in-users.php:96 +msgid "The selected user was logged out successfully!" +msgstr "" + +#: admin/wp-security-list-login-fails.php:53 +msgid "Login IP range" +msgstr "" + +#: admin/wp-security-list-login-fails.php:130 +msgid "Nonce check failed for delete failed login record operation!" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:66 +msgid "Blocked IP" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:87 +msgid "Unblock" +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:122 +#: admin/wp-security-list-permanent-blocked-ip.php:139 +msgid "Successfully unblocked and deleted the selected record(s)." +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:126 +#: admin/wp-security-list-permanent-blocked-ip.php:143 +msgid "Failed to unblock and delete the selected record(s)." +msgstr "" + +#: admin/wp-security-list-permanent-blocked-ip.php:133 +msgid "Nonce check failed for unblock IP operation!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:71 +msgid "Email" +msgstr "" + +#: admin/wp-security-list-registered-users.php:72 +msgid "Register date" +msgstr "" + +#: admin/wp-security-list-registered-users.php:73 +msgid "Account status" +msgstr "" + +#: admin/wp-security-list-registered-users.php:92 +msgid "Approve" +msgstr "" + +#: admin/wp-security-list-registered-users.php:94 +msgid "Block IP" +msgstr "" + +#: admin/wp-security-list-registered-users.php:159 +msgid "The selected accounts were approved successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:163 +msgid "The following accounts failed to update successfully: " +msgstr "" + +#: admin/wp-security-list-registered-users.php:171 +msgid "The selected account was approved successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:190 +msgid "Your account is now active" +msgstr "" + +#: admin/wp-security-list-registered-users.php:191 +msgid "Your account with username: " +msgstr "" + +#: admin/wp-security-list-registered-users.php:191 +msgid " is now active" +msgstr "" + +#: admin/wp-security-list-registered-users.php:222 +msgid "The selected accounts were deleted successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:230 +msgid "Nonce check failed for delete registered user account operation!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:238 +msgid "The selected account was deleted successfully!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:264 +msgid "The selected IP addresses were successfully added to the permanent block list!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:265 +#: admin/wp-security-list-registered-users.php:282 +msgid "View Blocked IPs" +msgstr "" + +#: admin/wp-security-list-registered-users.php:274 +msgid "Nonce check failed for block IP operation of registered user!" +msgstr "" + +#: admin/wp-security-list-registered-users.php:281 +msgid "The selected IP was successfully added to the permanent block list!" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:25 +msgid "Visitor lockout" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:85 +msgid "Site lockout feature settings saved!" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:92 +msgid "General visitor lockout" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:98 +msgid "This feature allows you to put your site into \"maintenance mode\" by locking down the front-end to all visitors except logged in users with super admin privileges." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:99 +msgid "Locking your site down to general visitors can be useful if you are investigating some issues on your site or perhaps you might be doing some maintenance and wish to keep out all traffic for security reasons." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:104 +msgid "Enable front-end lockout" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:107 +msgid "Check this if you want all visitors except those who are logged in as administrator to be locked out of the front-end of your site." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:111 +msgid "Enter a message:" +msgstr "" + +#: admin/wp-security-maintenance-menu.php:123 +msgid "Enter a message you wish to display to visitors when your site is in maintenance mode." +msgstr "" + +#: admin/wp-security-maintenance-menu.php:130 +msgid "Save site lockout settings" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:28 +msgid "Copy protection" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:29 +msgid "Frames" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:30 +msgid "Users enumeration" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:31 +msgid "WP REST API" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:89 +msgid "Copy Protection feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:94 +msgid "Disable the ability to copy text" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:100 +msgid "This feature allows you to disable the ability to select and copy text from your front end." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:101 +msgid "When admin user is logged in, the feature is automatically disabled for his session." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:106 +msgid "Enable copy protection" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:109 +msgid "Check this if you want to disable the \"Right click\", \"Text selection\" and \"Copy\" option on the front end of your site." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:116 +msgid "Save copy protection settings" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:140 +msgid "Frame Display Prevention feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:145 +msgid "Prevent your site from being displayed in a frame" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:151 +msgid "This feature allows you to prevent other sites from displaying any of your content via a frame or iframe." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:152 +msgid "When enabled, this feature will set the \"X-Frame-Options\" parameter to \"sameorigin\" in the HTTP header." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:157 +msgid "Enable iFrame protection" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:160 +msgid "Check this if you want to stop other sites from displaying your content in a frame or iframe." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:191 +msgid "Users Enumeration Prevention feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:196 +msgid "Prevent users enumeration" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:202 +msgid "This feature allows you to prevent external users/bots from fetching the user info with urls like \"/?author=1\"." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:203 +msgid "When enabled, this feature will print a \"forbidden\" error rather than the user information." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:208 +msgid "Disable users enumeration" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:211 +msgid "Check this if you want to stop users enumeration." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:242 +msgid "WP REST API Security feature settings saved!" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:253 +msgid "This feature allows you to block WordPress REST API access for unauthorized requests." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:254 +msgid "When enabled this feature will only allow REST requests to be processed if the user is logged in." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:260 +msgid "Beware that if you are using other plugins which have registered REST endpoints (eg, Contact Form 7), then this feature will also block REST requests used by these plugins if the user is not logged in. It is recommended that you leave this feature disabled if you want uninterrupted functionality for such plugins." +msgstr "" + +#: admin/wp-security-misc-options-menu.php:268 +msgid "Disallow unauthorized REST requests" +msgstr "" + +#: admin/wp-security-misc-options-menu.php:271 +msgid "Check this if you want to stop REST API access for non-logged in requests." +msgstr "" + +#: admin/wp-security-settings-menu.php:25 +msgid "General settings" +msgstr "常规设置" + +#: admin/wp-security-settings-menu.php:29 +#: admin/wp-security-settings-menu.php:33 +msgid "file" +msgstr "" + +#: admin/wp-security-settings-menu.php:37 +msgid "Delete plugin settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:41 +msgid "WP version info" +msgstr "" + +#: admin/wp-security-settings-menu.php:45 +msgid "Import/Export" +msgstr "导入/导出" + +#: admin/wp-security-settings-menu.php:52 +msgid "Advanced settings" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:128 +msgid "All the security features have been disabled successfully!" +msgstr "已成功禁用所有安全功能!" + +#: admin/wp-security-settings-menu.php:132 +#: admin/wp-security-settings-menu.php:159 +msgid "Could not write to the .htaccess file. Please restore your .htaccess file manually using the restore functionality in the \".htaccess File\"." +msgstr "" + +#: admin/wp-security-settings-menu.php:137 +msgid "Could not write to the wp-config.php. Please restore your wp-config.php file manually using the restore functionality in the \"wp-config.php File\"." +msgstr "" + +#: admin/wp-security-settings-menu.php:155 +msgid "All firewall rules have been disabled successfully!" +msgstr "" + +#: admin/wp-security-settings-menu.php:177 +msgid "Deletion of aio_wp_security_configs option and .htaccess directives failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:179 +msgid "Reset of aio_wp_security_configs option failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:181 +msgid "Deletion of .htaccess directives failed." +msgstr "" + +#: admin/wp-security-settings-menu.php:183 +msgid "All settings have been successfully reset." +msgstr "" + +#: admin/wp-security-settings-menu.php:203 +msgid "For information, updates and documentation, please visit the" +msgstr "有关信息,更新和文档,请访问" + +#: admin/wp-security-settings-menu.php:203 +msgid "Page" +msgstr "页面" + +#: admin/wp-security-settings-menu.php:204 +msgid "Follow us" +msgstr "关注我们" + +#: admin/wp-security-settings-menu.php:204 +msgid "on Twitter, Google+ or via Email to stay up to date about the new security features of this plugin." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:208 +msgid "WP Security plugin" +msgstr "WP安全插件" + +#: admin/wp-security-settings-menu.php:212 +msgid "Thank you for using the AIOS security plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:216 +msgid "There are a lot of security features in this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:221 +msgid "To start, go through each security option and enable the \"basic\" options." +msgstr "" + +#: admin/wp-security-settings-menu.php:225 +msgid "The more features you enable, the more security points you will achieve." +msgstr "" + +#: admin/wp-security-settings-menu.php:228 +msgid "Before doing anything we advise taking a backup of your .htaccess file, database and wp-config.php." +msgstr "" + +#: admin/wp-security-settings-menu.php:231 +msgid "Backup your database" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:232 +#: admin/wp-security-settings-menu.php:433 +msgid "Backup .htaccess file" +msgstr "备份 .htaccess 文件" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:233 +#: admin/wp-security-settings-menu.php:534 +msgid "Backup wp-config.php file" +msgstr "备份 wp-config.php 文件" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:240 +msgid "Disable security features" +msgstr "禁用安全功能" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:246 +msgid "If you think that some plugin functionality on your site is broken due to a security feature you enabled in this plugin, then use the following option to turn off all the security features of this plugin." +msgstr "如果您认为您的网站上的某些插件功能由于您在此插件中启用的安全功能而中断,请使用以下选项关闭此插件的所有安全功能." + +# @ default +#: admin/wp-security-settings-menu.php:250 +msgid "Disable all security features" +msgstr "禁用所有安全功能" + +# @ all-in-one-wp-security-and-firewall +# @ default +#: admin/wp-security-settings-menu.php:257 +#: admin/wp-security-settings-menu.php:267 +msgid "Disable all firewall rules" +msgstr "禁用所有防火墙规则" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:263 +msgid "This feature will disable all firewall rules which are currently active in this plugin and it will also delete these rules from your .htacess file. Use it if you think one of the firewall rules is causing an issue on your site." +msgstr "此功能将禁用在此插件中已激活的所有防火墙规则,同时.htacess中的规则也会被删除。如果您认为其中一个防火墙规则导致您的网站出现问题,请使用它。" + +#: admin/wp-security-settings-menu.php:274 +#: admin/wp-security-settings-menu.php:287 +msgid "Reset settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:279 +msgid "This button click will delete all of your settings related to the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:280 +msgid "This button click will reset/empty all the database tables of the security plugin also." +msgstr "" + +#: admin/wp-security-settings-menu.php:281 +msgid "Use this plugin if you were locked out by the All In One WP Security & Firewall Plugin and/or you are having issues logging in when that plugin is activated." +msgstr "" + +#: admin/wp-security-settings-menu.php:282 +msgid "In addition to the settings it will also delete any directives which were added to the .htaccess file by the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:283 +msgid "%1$sNOTE: %2$sAfter deleting the settings you will need to re-configure the All In One WP Security & Firewall Plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:295 +msgid "Debug settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:301 +msgid "This setting allows you to enable/disable debug for this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:307 +msgid "Enable debug" +msgstr "" + +#: admin/wp-security-settings-menu.php:310 +msgid "Check this if you want to enable debug. You should keep this option disabled after you have finished debugging the issue." +msgstr "" + +#: admin/wp-security-settings-menu.php:314 +msgid "Save debug settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:350 +msgid "Your .htaccess file was successfully backed up! Using an FTP program go to the \"/wp-content/aiowps_backups\" directory to save a copy of the file to your computer." +msgstr "您的.htaccess文件已成功备份!将通过FTP将此目录下\"/wp-content/aiowps_backups\"的文件备份到您的计算机中。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:356 +msgid "htaccess file rename failed during backup. Please check your root directory for the backup file using FTP." +msgstr "备份过程中 htaccess 文件重命名失败。请使用FTP检查备份文件的根目录。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:362 +msgid "htaccess backup failed." +msgstr "htaccess备份失败。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:377 +msgid "Please choose a .htaccess to restore from." +msgstr "请选择要从中还原的.htaccess。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:392 +msgid "htaccess file restore failed. Please attempt to restore the .htaccess manually using FTP." +msgstr "htaccess 文件恢复失败。请尝试使用FTP手动恢复 .htaccess 。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:396 +msgid "Your .htaccess file has successfully been restored!" +msgstr ".htaccess 文件已成功恢复!" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:402 +msgid "htaccess Restore operation failed! Please check the contents of the file you are trying to restore from." +msgstr "htaccess恢复操作失败! 请检查您要从中还原的文件的内容。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:408 +msgid ".htaccess file operations" +msgstr ".htaccess 文件操作" + +#: admin/wp-security-settings-menu.php:411 +msgid "Your \".htaccess\" file is a key component of your website's security and it can be modified to implement various levels of protection mechanisms." +msgstr "" + +#: admin/wp-security-settings-menu.php:412 +msgid "This feature allows you to backup and save your currently active .htaccess file should you need to re-use the the backed up file in the future." +msgstr "" + +#: admin/wp-security-settings-menu.php:413 +msgid "You can also restore your site's .htaccess settings using a backed up .htaccess file." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:428 +msgid "Save the current .htaccess file" +msgstr "保存当前 .htaccess 文件" + +#: admin/wp-security-settings-menu.php:432 +msgid "Click the button below to backup and save the currently active .htaccess file." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:437 +msgid "Restore from a backed up .htaccess file" +msgstr "从备份的.htaccess文件中恢复" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:443 +msgid ".htaccess file to restore from" +msgstr ".htaccess 恢复文件" + +#: admin/wp-security-settings-menu.php:445 +msgid "Select Your htaccess File" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:449 +msgid "After selecting your file, click the button below to restore your site using the backed up htaccess file (htaccess_backup.txt)." +msgstr "选择文件后,单击下面的恢复按钮,来恢复您网站的htaccess文件。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:455 +msgid "Restore .htaccess file" +msgstr "恢复 .htaccess 文件" + +#: admin/wp-security-settings-menu.php:477 +msgid "Please choose a wp-config.php file to restore from." +msgstr "" + +#: admin/wp-security-settings-menu.php:493 +msgid "wp-config.php file restore failed. Please attempt to restore this file manually using FTP." +msgstr "" + +#: admin/wp-security-settings-menu.php:497 +msgid "Your wp-config.php file has successfully been restored!" +msgstr "" + +#: admin/wp-security-settings-menu.php:503 +msgid "wp-config.php Restore operation failed! Please check the contents of the file you are trying to restore from." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:509 +msgid "wp-config.php file operations" +msgstr "wp-config.php 文件操作" + +#: admin/wp-security-settings-menu.php:512 +msgid "Your \"wp-config.php\" file is one of the most important in your WordPress installation. It is a primary configuration file and contains crucial things such as details of your database and other critical components." +msgstr "" + +#: admin/wp-security-settings-menu.php:513 +msgid "This feature allows you to backup and save your currently active wp-config.php file should you need to re-use the the backed up file in the future." +msgstr "" + +#: admin/wp-security-settings-menu.php:514 +msgid "You can also restore your site's wp-config.php settings using a backed up wp-config.php file." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:529 +msgid "Save the current wp-config.php file" +msgstr "保存当前wp-config.php文件" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:533 +msgid "Click the button below to backup and download the contents of the currently active wp-config.php file." +msgstr "点击下面的按钮备份和下载当前活动的wp-config.php文件的内容。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:539 +msgid "Restore from a backed up wp-config file" +msgstr "从备份的wp-config文件恢复" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:545 +msgid "wp-config file to restore from" +msgstr "wp-config 恢复文件" + +#: admin/wp-security-settings-menu.php:547 +msgid "Select Your wp-config File" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:551 +msgid "After selecting your file click the button below to restore your site using the backed up wp-config file (wp-config.php.backup.txt)." +msgstr "选择文件后,单击下面的恢复按钮,来恢复您网站的wp-config文件。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:557 +msgid "Restore wp-config file" +msgstr "恢复 wp-config 文件" + +#: admin/wp-security-settings-menu.php:591 +msgid "Manage delete plugin settings saved." +msgstr "" + +#: admin/wp-security-settings-menu.php:596 +msgid "Manage delete plugin tasks" +msgstr "" + +#: admin/wp-security-settings-menu.php:603 +msgid "Delete database tables" +msgstr "" + +#: admin/wp-security-settings-menu.php:606 +msgid "Check this if you want to remove database tables when the plugin is uninstalled." +msgstr "" + +#: admin/wp-security-settings-menu.php:610 +msgid "Delete settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:613 +msgid "Check this if you want to remove all plugin settings when uninstalling the plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:613 +msgid "It will also remove all custom htaccess rules that were added by this plugin." +msgstr "" + +#: admin/wp-security-settings-menu.php:647 +msgid "WP generator meta tag and version info" +msgstr "" + +#: admin/wp-security-settings-menu.php:650 +msgid "WordPress generator automatically adds some meta information inside the \"head\" tags of every page on your site's front end. Below is an example of this:" +msgstr "" + +#: admin/wp-security-settings-menu.php:652 +msgid "The above meta information shows which version of WordPress your site is currently running and thus can help hackers or crawlers scan your site to see if you have an older version of WordPress or one with a known exploit." +msgstr "" + +#: admin/wp-security-settings-menu.php:653 +msgid "There are also other ways wordpress reveals version info such as during style and script loading. An example of this is:" +msgstr "" + +#: admin/wp-security-settings-menu.php:655 +msgid "This feature will allow you to remove the WP generator meta info and other version info from your site's pages." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:661 +msgid "WP generator meta info" +msgstr "WP生成的元信息" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-settings-menu.php:673 +msgid "Remove WP generator meta info" +msgstr "删除WP生成的元信息" + +#: admin/wp-security-settings-menu.php:676 +msgid "Check this if you want to remove the version and meta info produced by WP from all pages" +msgstr "" + +#: admin/wp-security-settings-menu.php:704 +msgid "Please choose a file to import your settings from." +msgstr "" + +#: admin/wp-security-settings-menu.php:736 +msgid "Import AIOS settings from " +msgstr "" + +#: admin/wp-security-settings-menu.php:742 +#: admin/wp-security-settings-menu.php:786 +msgid "The deletion of the import file failed. Please delete this file manually via the media menu for security purposes." +msgstr "" + +#: admin/wp-security-settings-menu.php:744 +#: admin/wp-security-settings-menu.php:788 +msgid "The file you uploaded was also deleted for security purposes because it contains security settings details." +msgstr "" + +#: admin/wp-security-settings-menu.php:759 +msgid "Your AIOS settings were successfully imported via file input." +msgstr "" + +#: admin/wp-security-settings-menu.php:760 +msgid "The deletion of the import file failed. Please delete this file manually via the media menu for security purposes because it contains security settings details." +msgstr "" + +#: admin/wp-security-settings-menu.php:762 +msgid "Your AIOS settings were successfully imported. The file you uploaded was also deleted for security purposes because it contains security settings details." +msgstr "" + +#: admin/wp-security-settings-menu.php:765 +msgid "Your AIOS settings were successfully imported via text entry." +msgstr "" + +#: admin/wp-security-settings-menu.php:780 +msgid "The contents of your settings file appear invalid. Please check the contents of the file you are trying to import settings from." +msgstr "" + +#: admin/wp-security-settings-menu.php:797 +msgid "Export or import your AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:800 +msgid "This section allows you to export or import your All In One WP Security & Firewall settings." +msgstr "" + +#: admin/wp-security-settings-menu.php:801 +msgid "This can be handy if you wanted to save time by applying the settings from one site to another site." +msgstr "" + +#: admin/wp-security-settings-menu.php:802 +msgid "NOTE: Before importing, it is your responsibility to know what settings you are trying to import. Importing settings blindly can cause you to be locked out of your site." +msgstr "" + +#: admin/wp-security-settings-menu.php:803 +msgid "For Example: If a settings item relies on the domain URL then it may not work correctly when imported into a site with a different domain." +msgstr "" + +#: admin/wp-security-settings-menu.php:809 +#: admin/wp-security-settings-menu.php:818 +msgid "Export AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:815 +msgid "To export your All In One WP Security & Firewall settings click the button below." +msgstr "要导出您的All In One WP安全和防火墙设置,请单击下面的按钮。" + +#: admin/wp-security-settings-menu.php:822 +#: admin/wp-security-settings-menu.php:851 +msgid "Import AIOS settings" +msgstr "" + +#: admin/wp-security-settings-menu.php:828 +msgid "Use this section to import your All In One WP Security & Firewall settings from a file. Alternatively, copy/paste the contents of your import file into the textarea below." +msgstr "" + +#: admin/wp-security-settings-menu.php:830 +msgid "Import file" +msgstr "导入文件" + +#: admin/wp-security-settings-menu.php:833 +msgid "Select Your Import Settings File" +msgstr "" + +#: admin/wp-security-settings-menu.php:837 +msgid "After selecting your file, click the button below to apply the settings to your site." +msgstr "" + +#: admin/wp-security-settings-menu.php:844 +msgid "Copy/Paste import data" +msgstr "复制/粘贴导入数据" + +#: admin/wp-security-settings-menu.php:893 +msgid "Default - if correct, then this is the best option" +msgstr "" + +#: admin/wp-security-settings-menu.php:894 +msgid "Only use if you're using Cloudflare." +msgstr "" + +#: admin/wp-security-settings-menu.php:902 +msgid "(current value: %s)" +msgstr "" + +#: admin/wp-security-settings-menu.php:905 +msgid "no value (i.e. empty) on your server" +msgstr "" + +#: admin/wp-security-spam-menu.php:28 +msgid "Comment spam" +msgstr "" + +#: admin/wp-security-spam-menu.php:29 +msgid "Comment spam IP monitoring" +msgstr "" + +#: admin/wp-security-spam-menu.php:30 +msgid "BuddyPress" +msgstr "" + +#: admin/wp-security-spam-menu.php:31 +msgid "bbPress" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-spam-menu.php:57 +msgid "Spam prevention" +msgstr "垃圾防护" + +#: admin/wp-security-spam-menu.php:99 +msgid "You entered a non numeric value for the \"move spam comments to trash after number of days\" field." +msgstr "" + +#: admin/wp-security-spam-menu.php:99 +#: admin/wp-security-spam-menu.php:297 +#: admin/wp-security-user-login-menu.php:118 +#: admin/wp-security-user-login-menu.php:124 +#: admin/wp-security-user-login-menu.php:130 +#: admin/wp-security-user-login-menu.php:136 +msgid "It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:129 +msgid "Comment spam settings" +msgstr "" + +#: admin/wp-security-spam-menu.php:134 +msgid "Add CAPTCHA to comments form" +msgstr "" + +#: admin/wp-security-spam-menu.php:138 +msgid "This feature will add a CAPTCHA field in the WordPress comments form." +msgstr "" + +#: admin/wp-security-spam-menu.php:139 +msgid "Adding a CAPTCHA field in the comment form is a simple way of greatly reducing spam comments from bots without using .htaccess rules." +msgstr "" + +#: admin/wp-security-spam-menu.php:148 +msgid "Enable CAPTCHA on comment forms" +msgstr "" + +#: admin/wp-security-spam-menu.php:151 +msgid "Check this if you want to insert a CAPTCHA field on the comment forms." +msgstr "" + +#: admin/wp-security-spam-menu.php:158 +msgid "Block spambot comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:162 +msgid "A large portion of WordPress blog comment spam is mainly produced by automated bots and not necessarily by humans." +msgstr "" + +#: admin/wp-security-spam-menu.php:163 +msgid "This feature will greatly minimize the useless and unnecessary traffic and load on your server resulting from spam comments by blocking all comment requests which do not originate from your domain." +msgstr "" + +#: admin/wp-security-spam-menu.php:164 +msgid "In other words, if the comment was not submitted by a human who physically submitted the comment on your site, the request will be blocked." +msgstr "" + +#: admin/wp-security-spam-menu.php:182 +msgid "Block spambots from posting comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:185 +msgid "Check this if you want to apply a firewall rule which will block comments originating from spambots." +msgstr "" + +#: admin/wp-security-spam-menu.php:189 +msgid "This feature will implement a firewall rule to block all comment attempts which do not originate from your domain." +msgstr "" + +#: admin/wp-security-spam-menu.php:190 +msgid "A legitimate comment is one which is submitted by a human who physically fills out the comment form and clicks the submit button. For such events, the HTTP_REFERRER is always set to your own domain." +msgstr "" + +#: admin/wp-security-spam-menu.php:191 +msgid "A comment submitted by a spambot is done by directly calling the comments.php file, which usually means that the HTTP_REFERRER value is not your domain and often times empty." +msgstr "" + +#: admin/wp-security-spam-menu.php:192 +msgid "This feature will check and block comment requests which are not referred by your domain thus greatly reducing your overall blog spam and PHP requests done by the server to process these comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:202 +msgid "Comment processing" +msgstr "" + +#: admin/wp-security-spam-menu.php:207 +msgid "Trash spam comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:216 +msgid "Move spam comments to trash after %s days." +msgstr "" + +#: admin/wp-security-spam-menu.php:224 +msgid "Enable this feature in order to move the spam comments to trash after given number of days." +msgstr "" + +#: admin/wp-security-spam-menu.php:262 +msgid "You entered a non numeric value for the minimum number of spam comments field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:265 +msgid "You must enter an integer greater than zero for minimum number of spam comments field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-spam-menu.php:292 +msgid "Nonce check failed for list spam comment IPs." +msgstr "" + +#: admin/wp-security-spam-menu.php:297 +msgid "You entered a non numeric value for the minimum spam comments per IP field." +msgstr "" + +#: admin/wp-security-spam-menu.php:308 +msgid "Displaying results for IP addresses which have posted a minimum of %s spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:323 +msgid "Auto block spammer IPs" +msgstr "" + +#: admin/wp-security-spam-menu.php:328 +msgid "This feature has detected that %s is not active. It is highly recommended that you activate the Akismet plugin to make the most of this feature." +msgstr "" + +#: admin/wp-security-spam-menu.php:337 +msgid "This feature allows you to automatically and permanently block IP addresses which have exceeded a certain number of comments labelled as spam." +msgstr "" + +#: admin/wp-security-spam-menu.php:338 +msgid "Comments are usually labelled as spam either by the Akismet plugin or manually by the WP administrator when they mark a comment as \"spam\" from the WordPress Comments menu." +msgstr "" + +#: admin/wp-security-spam-menu.php:352 +msgid "You currently have no IP addresses permanently blocked due to spam." +msgstr "" + +#: admin/wp-security-spam-menu.php:365 +msgid "Spammer IPs added to permanent block list today: " +msgstr "" + +#: admin/wp-security-spam-menu.php:366 +msgid "All time total: " +msgstr "" + +#: admin/wp-security-spam-menu.php:367 +msgid "View blocked IPs" +msgstr "" + +#: admin/wp-security-spam-menu.php:380 +msgid "Enable auto block of spam comment IPs" +msgstr "" + +#: admin/wp-security-spam-menu.php:383 +msgid "Check this box if you want this plugin to automatically block IP addresses which submit spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:387 +msgid "Minimum number of spam comments" +msgstr "" + +#: admin/wp-security-spam-menu.php:389 +msgid "Specify the minimum number of spam comments for an IP address before it is permanently blocked." +msgstr "" + +#: admin/wp-security-spam-menu.php:393 +msgid "Example 1: Setting this value to \"1\" will block ALL IP addresses which were used to submit at least one spam comment." +msgstr "" + +#: admin/wp-security-spam-menu.php:394 +msgid "Example 2: Setting this value to \"5\" will block only those IP addresses which were used to submit 5 spam comments or more on your site." +msgstr "" + +#: admin/wp-security-spam-menu.php:412 +msgid "List spammer IP addresses" +msgstr "" + +#: admin/wp-security-spam-menu.php:416 +msgid "This section displays a list of the IP addresses of the people or bots who have left spam comments on your site." +msgstr "" + +#: admin/wp-security-spam-menu.php:417 +msgid "This information can be handy for identifying the most persistent IP addresses or ranges used by spammers." +msgstr "" + +#: admin/wp-security-spam-menu.php:418 +msgid "By inspecting the IP address data coming from spammers you will be in a better position to determine which addresses or address ranges you should block by adding them to the permanent block list." +msgstr "" + +#: admin/wp-security-spam-menu.php:419 +msgid "To add one or more of the IP addresses displayed in the table below to your blacklist, simply click the \"Block\" link for the individual row or select more than one address using the checkboxes and then choose the \"block\" option from the Bulk Actions dropdown list and click the \"Apply\" button." +msgstr "" + +#: admin/wp-security-spam-menu.php:427 +msgid "Minimum number of spam comments per IP" +msgstr "" + +#: admin/wp-security-spam-menu.php:429 +msgid "This field allows you to list only those IP addresses which have been used to post X or more spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:433 +msgid "Example 1: Setting this value to \"0\" or \"1\" will list ALL IP addresses which were used to submit spam comments." +msgstr "" + +#: admin/wp-security-spam-menu.php:434 +msgid "Example 2: Setting this value to \"5\" will list only those IP addresses which were used to submit 5 spam comments or more on your site." +msgstr "" + +#: admin/wp-security-spam-menu.php:441 +msgid "Find IP addresses" +msgstr "" + +#: admin/wp-security-spam-menu.php:445 +msgid "Spammer IP address results" +msgstr "" + +#: admin/wp-security-spam-menu.php:451 +#: classes/wp-security-utility.php:253 +msgid "The plugin has detected that you are using a Multi-Site WordPress installation." +msgstr "" + +#: admin/wp-security-spam-menu.php:452 +msgid "Only the \"superadmin\" can block IP addresses from the main site." +msgstr "" + +#: admin/wp-security-spam-menu.php:453 +msgid "Take note of the IP addresses you want blocked and ask the superadmin to add these to the blacklist using the \"Blacklist Manager\" on the main site." +msgstr "" + +#: admin/wp-security-spam-menu.php:498 +msgid "BuddyPress spam settings" +msgstr "" + +#: admin/wp-security-spam-menu.php:503 +msgid "Add CAPTCHA to BuddyPress registration form" +msgstr "" + +#: admin/wp-security-spam-menu.php:507 +msgid "This feature will add a simple math CAPTCHA field in the BuddyPress registration form." +msgstr "" + +#: admin/wp-security-spam-menu.php:508 +msgid "Adding a CAPTCHA field in the registration form is a simple way of greatly reducing spam signups from bots without using .htaccess rules." +msgstr "" + +#: admin/wp-security-spam-menu.php:518 +msgid "Enable CAPTCHA on BuddyPress registration form" +msgstr "" + +#: admin/wp-security-spam-menu.php:521 +msgid "Check this if you want to insert a CAPTCHA field on the BuddyPress registration forms." +msgstr "" + +#: admin/wp-security-spam-menu.php:530 +msgid "BuddyPress is not active! In order to use this feature you will need to have BuddyPress installed and activated." +msgstr "" + +#: admin/wp-security-spam-menu.php:560 +msgid "bbPress spam settings" +msgstr "" + +#: admin/wp-security-spam-menu.php:565 +msgid "Add CAPTCHA to bbPress new topic form" +msgstr "" + +#: admin/wp-security-spam-menu.php:569 +msgid "This feature will add a simple math CAPTCHA field in the bbPress new topic form." +msgstr "" + +#: admin/wp-security-spam-menu.php:570 +msgid "Adding a CAPTCHA field in this form is a simple way of greatly reducing spam submitted from bots." +msgstr "" + +#: admin/wp-security-spam-menu.php:580 +msgid "Enable CAPTCHA on bbPress new topic form" +msgstr "" + +#: admin/wp-security-spam-menu.php:583 +msgid "Check this if you want to insert a CAPTCHA field on the bbPress new topic forms." +msgstr "" + +#: admin/wp-security-spam-menu.php:592 +msgid "bbPress is not active. In order to use this feature you will need to have bbPress installed and activated." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-tools-menu.php:34 +msgid "WHOIS lookup" +msgstr "WHOIS 查询" + +#: admin/wp-security-tools-menu.php:95 +#: admin/wp-security-tools-menu.php:136 +msgid "Querying %s: %s" +msgstr "" + +#: admin/wp-security-tools-menu.php:103 +#: admin/wp-security-tools-menu.php:112 +#: admin/wp-security-tools-menu.php:151 +msgid "Redirected to %s" +msgstr "" + +#: admin/wp-security-tools-menu.php:173 +msgid "The WHOIS lookup feature gives you a way to look up who owns an IP address or domain name." +msgstr "" + +#: admin/wp-security-tools-menu.php:173 +msgid "You can use this to investigate users engaging in malicious activity on your site." +msgstr "" + +#: admin/wp-security-tools-menu.php:176 +msgid "WHOIS lookup on IP or domain" +msgstr "" + +#: admin/wp-security-tools-menu.php:183 +msgid "IP address or domain name:" +msgstr "" + +#: admin/wp-security-tools-menu.php:190 +msgid "Look up IP or domain" +msgstr "" + +#: admin/wp-security-tools-menu.php:219 +msgid "Please enter a valid IP address or domain name to look up." +msgstr "" + +#: admin/wp-security-tools-menu.php:220 +#: admin/wp-security-tools-menu.php:226 +msgid "Nothing to show." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:32 +msgid "WP username" +msgstr "WP 用户名" + +#: admin/wp-security-user-accounts-menu.php:33 +msgid "Display name" +msgstr "昵称安全" + +#: admin/wp-security-user-accounts-menu.php:34 +msgid "Password" +msgstr "密码" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:60 +msgid "User accounts" +msgstr "用户账户" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:82 +msgid "Admin user security" +msgstr "管理员用户安全" + +#: admin/wp-security-user-accounts-menu.php:85 +msgid "By default, WordPress sets the administrator username to \"admin\" at installation time." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:86 +msgid "A lot of hackers try to take advantage of this information by attempting \"Brute force login attacks\" where they repeatedly try to guess the password by using \"admin\" for username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:87 +msgid "From a security perspective, changing the default \"admin\" user name is one of the first and smartest things you should do on your site." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:88 +msgid "This feature will allow you to change your default \"admin\" user name to a more secure name of your choosing." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:95 +msgid "List of administrator accounts" +msgstr "管理员帐户列表" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:104 +#: classes/grade-system/wp-security-feature-item-manager.php:43 +msgid "Change admin username" +msgstr "更改管理员用户名" + +#: admin/wp-security-user-accounts-menu.php:112 +msgid "Your site currently has an account which uses the default \"admin\" username. It is highly recommended that you change this name to something else. Use the following field to change the admin username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:118 +msgid "New admin username" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:120 +msgid "Choose a new username for admin." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:124 +msgid "Change username" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:126 +msgid "NOTE: If you are currently logged in as \"admin\" you will be automatically logged out after changing your username and will be required to log back in." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:133 +msgid "No action required! " +msgstr "无需执行任何操作!" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:135 +msgid "Your site does not have any account which uses the default \"admin\" username. " +msgstr "您的网站没有任何使用默认“admin”用户名的帐户。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:136 +msgid "This is good security practice." +msgstr "这是很好的安全措施。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:148 +msgid "Display name security" +msgstr "昵称安全" + +#: admin/wp-security-user-accounts-menu.php:151 +msgid "When you submit a post or answer a comment, WordPress will usually display your \"nickname\"." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:152 +msgid "By default the nickname is set to the login (or user) name of your account." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:153 +msgid "From a security perspective, leaving your nickname the same as your user name is bad practice because it gives a hacker at least half of your account's login credentials." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:154 +msgid "Therefore to further tighten your site's security you are advised to change your nickname and Display name to be different from your Username." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:160 +msgid "Modify accounts with identical login name and display name" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:169 +msgid "Your site currently has the following accounts which have an identical login name and display name." +msgstr "您的网站目前有下列帐户的登录名和昵称是相同的。" + +#: admin/wp-security-user-accounts-menu.php:170 +msgid "Follow the link to edit the user profile of that particular user account, change Nickname, choose a different Display name compared to Username, and press the \"Update User\" button.)" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:185 +msgid "No action required." +msgstr "无需执行任何操作。" + +#: admin/wp-security-user-accounts-menu.php:186 +msgid "Your site does not have a user account where the display name is identical to the username." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:197 +msgid "Password tool" +msgstr "密码工具" + +#: admin/wp-security-user-accounts-menu.php:200 +msgid "Poor password selection is one of the most common weak points of many sites and is usually the first thing a hacker will try to exploit when attempting to break into your site." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:201 +msgid "Many people fall into the trap of using a simple word or series of numbers as their password. Such a predictable and simple password would take a competent hacker merely minutes to guess your password by using a simple script which cycles through the easy and most common combinations." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:202 +msgid "The longer and more complex your password is the harder it is for hackers to \"crack\" because more complex passwords require much greater computing power and time." +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:203 +msgid "This section contains a useful password strength tool which you can use to check whether your password is sufficiently strong enough." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:208 +msgid "Password strength tool" +msgstr "密码强度工具" + +#: admin/wp-security-user-accounts-menu.php:210 +msgid "This password tool uses an algorithm which calculates how long it would take for your password to be cracked using the computing power of an off-the-shelf current model desktop PC with high end processor, graphics card and appropriate password cracking software." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:213 +msgid "Start typing a password." +msgstr "输入一个密码。" + +#: admin/wp-security-user-accounts-menu.php:216 +msgid "It would take a desktop PC approximately" +msgstr "一台台式电脑需要约" + +#: admin/wp-security-user-accounts-menu.php:217 +msgid "1 sec" +msgstr "1秒" + +#: admin/wp-security-user-accounts-menu.php:217 +msgid "to crack your password!" +msgstr "破解您的密码!" + +#: admin/wp-security-user-accounts-menu.php:222 +msgid "Password Strength" +msgstr "密码强度" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:245 +msgid "Username " +msgstr "用户名" + +#: admin/wp-security-user-accounts-menu.php:245 +msgid " already exists. Please enter another value. " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:262 +msgid "The database update operation of the user account failed!" +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:291 +msgid "You entered an invalid username. Please enter another value. " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:295 +msgid "Please enter a value for your username. " +msgstr "" + +#: admin/wp-security-user-accounts-menu.php:302 +msgid "Username successfully changed." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-accounts-menu.php:322 +msgid "Account login name" +msgstr "帐户登录名" + +#: admin/wp-security-user-accounts-menu.php:331 +msgid "Edit user" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:54 +#: admin/wp-security-user-login-menu.php:474 +msgid "Failed login records" +msgstr "登录失败记录" + +#: admin/wp-security-user-login-menu.php:55 +#: classes/grade-system/wp-security-feature-item-manager.php:51 +msgid "Force logout" +msgstr "强制注销" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:56 +#: admin/wp-security-user-login-menu.php:632 +msgid "Account activity logs" +msgstr "帐户活动日志" + +#: admin/wp-security-user-login-menu.php:58 +#: admin/wp-security-user-login-menu.php:769 +msgid "Additional settings" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:81 +msgid "User login" +msgstr "用户登录" + +#: admin/wp-security-user-login-menu.php:118 +msgid "You entered a non-numeric value for the max login attempts field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:124 +msgid "You entered a non numeric value for the login retry time period field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:130 +msgid "You entered a non numeric value for the lockout time length field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:136 +msgid "You entered a non numeric value for the maximum lockout time length field." +msgstr "" + +#: admin/wp-security-user-login-menu.php:141 +msgid "You entered an invalid minimum lockout time length, it must be less than the maximum lockout time length value." +msgstr "" + +#: admin/wp-security-user-login-menu.php:141 +msgid "Both have been set to the default values." +msgstr "" + +#: admin/wp-security-user-login-menu.php:160 +msgid "Please fill in one or more email addresses to notify." +msgstr "" + +#: admin/wp-security-user-login-menu.php:162 +msgid "You have entered one or more invalid email addresses." +msgstr "" + +#: admin/wp-security-user-login-menu.php:165 +msgid "It has been set to your WordPress admin email as default." +msgstr "" + +#: admin/wp-security-user-login-menu.php:250 +msgid "Login lockout configuration" +msgstr "" + +#: admin/wp-security-user-login-menu.php:254 +msgid "One of the ways hackers try to compromise sites is via a " +msgstr "" + +#: admin/wp-security-user-login-menu.php:254 +msgid "Brute force login attack" +msgstr "" + +#: admin/wp-security-user-login-menu.php:254 +msgid "This is where attackers use repeated login attempts until they guess the password." +msgstr "" + +#: admin/wp-security-user-login-menu.php:255 +msgid "Apart from choosing strong passwords, monitoring and blocking IP addresses which are involved in repeated login failures in a short period of time is a very effective way to stop these types of attacks." +msgstr "" + +#: admin/wp-security-user-login-menu.php:256 +msgid "You may also want to checkout our %s feature for another secure way to protect against these types of attacks." +msgstr "" + +#: admin/wp-security-user-login-menu.php:261 +msgid "Login lockout options" +msgstr "" + +#: admin/wp-security-user-login-menu.php:272 +msgid "Enable login lockout feature" +msgstr "" + +#: admin/wp-security-user-login-menu.php:275 +msgid "Check this if you want to enable the login lockout feature and apply the settings below" +msgstr "" + +#: admin/wp-security-user-login-menu.php:279 +msgid "Allow unlock requests" +msgstr "允许解锁请求" + +#: admin/wp-security-user-login-menu.php:282 +msgid "Check this if you want to allow users to generate an automated unlock request link which will unlock their account" +msgstr "如果您希望允许用户生成自动解锁请求链接,解锁其帐户,请选中此项" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:286 +msgid "Max login attempts" +msgstr "最大登录尝试" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:288 +msgid "Set the value for the maximum login retries before IP address is locked out" +msgstr "设置IP地址被锁定前的登录次数" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:292 +msgid "Login retry time period (min)" +msgstr "登录重试时间 (分钟)" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:294 +msgid "If the maximum number of failed login attempts for a particular IP address occur within this time period the plugin will lock out that address" +msgstr "如果在此时间段内,特定IP地址达到最大失败登录尝试次数时,插件将锁定该地址" + +#: admin/wp-security-user-login-menu.php:299 +msgid "Minimum lockout time length" +msgstr "" + +#: admin/wp-security-user-login-menu.php:305 +msgid "Set the minimum time period in minutes of lockout." +msgstr "" + +#: admin/wp-security-user-login-menu.php:306 +msgid "This failed login lockout time will be tripled on each failed login." +msgstr "" + +#: admin/wp-security-user-login-menu.php:313 +msgid "Maximum lockout time length" +msgstr "" + +#: admin/wp-security-user-login-menu.php:318 +msgid "Set the maximum time period in minutes of lockout." +msgstr "" + +#: admin/wp-security-user-login-menu.php:319 +msgid "No IP address will be blocked for more than this time period after making a failed login attempt." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:324 +msgid "Display generic error message" +msgstr "显示通用错误消息" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:327 +msgid "Check this if you want to show a generic error message when a login attempt fails" +msgstr "如果您希望在登录尝试失败时显示通用错误消息,请选中此项" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:331 +msgid "Instantly lockout invalid usernames" +msgstr "即时锁定无效的用户名" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:334 +msgid "Check this if you want to instantly lockout login attempts with usernames which do not exist on your system" +msgstr "如果您想立即锁定系统中不存在的用户名登录尝试,请选中此项" + +#: admin/wp-security-user-login-menu.php:339 +msgid "Instantly lockout specific usernames" +msgstr "即时锁定特定的用户名" + +#: admin/wp-security-user-login-menu.php:349 +msgid "Insert one username per line. Existing usernames are not blocked even if present in the list." +msgstr "每行插入一个用户名。" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:354 +msgid "Notify by email" +msgstr "通过邮件通知" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:358 +msgid "Check this if you want to receive an email when someone has been locked out due to maximum failed login attempts" +msgstr "如果您希望通过邮件收到因登录失败而导致锁定的消息,请选中此项" + +#: admin/wp-security-user-login-menu.php:361 +msgid "Fill in one email address per line." +msgstr "" + +#: admin/wp-security-user-login-menu.php:365 +msgid "Each email address must be on a new line." +msgstr "" + +#: admin/wp-security-user-login-menu.php:366 +msgid "If a valid email address has not been filled in, it will not be saved." +msgstr "" + +#: admin/wp-security-user-login-menu.php:367 +msgid "The valid email address format is userid@example.com" +msgstr "" + +#: admin/wp-security-user-login-menu.php:368 +msgid "Example: %s" +msgstr "" + +#: admin/wp-security-user-login-menu.php:375 +msgid "Enable PHP backtrace in email" +msgstr "" + +#: admin/wp-security-user-login-menu.php:379 +msgid "Check this if you want to include the PHP backtrace in notification emails." +msgstr "" + +#: admin/wp-security-user-login-menu.php:379 +msgid "This is internal coding information which makes it easier to investigate where an issued occurred." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:389 +msgid "Currently locked out IP address ranges" +msgstr "当前被锁定的 IP 地址和范围" + +#: admin/wp-security-user-login-menu.php:394 +msgid "To see a list of all locked IP addresses and ranges go to the %s tab in the dashboard menu." +msgstr "要查看所有已锁定的IP地址和范围的列表,请转到控制表菜单中的 %s 选项卡。" + +#: admin/wp-security-user-login-menu.php:399 +msgid "Login lockout IP whitelist settings" +msgstr "" + +#: admin/wp-security-user-login-menu.php:405 +msgid "Enable login lockout IP whitelist" +msgstr "" + +#: admin/wp-security-user-login-menu.php:416 +msgid "The addresses specified here will never be blocked by the login lockout feature." +msgstr "" + +#: admin/wp-security-user-login-menu.php:450 +msgid "User login feature - Delete all failed login records operation failed." +msgstr "" + +#: admin/wp-security-user-login-menu.php:452 +msgid "All records from the failed logins table were deleted successfully." +msgstr "" + +#: admin/wp-security-user-login-menu.php:467 +msgid "This tab displays the failed login attempts for your site." +msgstr "" + +#: admin/wp-security-user-login-menu.php:468 +msgid "The information below can be handy if you need to do security investigations because it will show you the IP range, username and ID (if applicable) and the time/date of the failed login attempt." +msgstr "" + +#: admin/wp-security-user-login-menu.php:469 +msgid "Failed login records that are older than %1$d days are purged automatically." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:508 +#: admin/wp-security-user-login-menu.php:517 +msgid "Delete all failed login records" +msgstr "删除所有失败的登录记录" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:514 +msgid "Click this button if you wish to delete all failed login records in one go." +msgstr "如果你要一次性删除所有失败的登录记录,请单击此按钮。" + +#: admin/wp-security-user-login-menu.php:544 +msgid "You entered a non numeric value for the logout time period field. It has been set to the default value." +msgstr "" + +#: admin/wp-security-user-login-menu.php:569 +msgid "Setting an expiry period for your WP administration session is a simple way to protect against unauthorized access to your site from your computer." +msgstr "" + +#: admin/wp-security-user-login-menu.php:570 +msgid "This feature allows you to specify a time period in minutes after which the admin session will expire and the user will be forced to log back in." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:575 +msgid "Force user logout options" +msgstr "强制用户注销选项" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:587 +msgid "Enable force WP user logout" +msgstr "启用强制WP用户注销" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:590 +msgid "Check this if you want to force a wp user to be logged out after a configured amount of time" +msgstr "如果您想强制wp用户在配置的时间后退出,请选中此项" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:594 +msgid "Logout the WP user after XX minutes" +msgstr "在XX分钟后注销WP用户" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:596 +msgid "(Minutes) The user will be forced to log back in after this time period has elapased." +msgstr "(分钟) 在此时间段过后,用户将被强制重新登录。" + +#: admin/wp-security-user-login-menu.php:625 +msgid "This tab displays the activity for accounts registered with your site that have logged in using the WordPress login form." +msgstr "" + +#: admin/wp-security-user-login-menu.php:626 +msgid "The information below can be handy if you need to do security investigations because it will show you the last 100 recent login events by username, IP address and time/date." +msgstr "" + +#: admin/wp-security-user-login-menu.php:627 +msgid "Account activity logs that are older than %1$d days are purged automatically." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:697 +msgid "Refresh logged in user data" +msgstr "刷新登录用户数据" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:701 +msgid "Refresh data" +msgstr "刷新数据" + +#: admin/wp-security-user-login-menu.php:706 +msgid "This tab displays all users who are currently logged into your site." +msgstr "" + +#: admin/wp-security-user-login-menu.php:707 +msgid "If you suspect there is a user or users who are logged in which should not be, you can block them by inspecting the IP addresses from the data below and adding them to your blacklist." +msgstr "" + +#: admin/wp-security-user-login-menu.php:708 +msgid "You can also instantly log them out by clicking on the \"Force logout\" link when you hover over the row in the user id column." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: admin/wp-security-user-login-menu.php:713 +msgid "Currently logged in users" +msgstr "当前登录用户" + +#: admin/wp-security-user-login-menu.php:761 +msgid "WordPress 5.6 introduced a new feature called \"Application passwords\"." +msgstr "" + +#: admin/wp-security-user-login-menu.php:762 +msgid "This allows you to create a token from the WordPress dashboard which then can be used in the authorization header." +msgstr "" + +#: admin/wp-security-user-login-menu.php:763 +msgid "This feature allows you to disable application passwords as they can leave your site vulnerable to social engineering and phishing scams." +msgstr "" + +#: admin/wp-security-user-login-menu.php:780 +#: classes/grade-system/wp-security-feature-item-manager.php:53 +msgid "Disable application password" +msgstr "" + +#: admin/wp-security-user-login-menu.php:783 +msgid "Check this if you want to disable the application password." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:27 +msgid "Manual approval" +msgstr "人工审核" + +#: admin/wp-security-user-registration-menu.php:28 +#: classes/grade-system/wp-security-feature-item-manager.php:59 +msgid "Registration CAPTCHA" +msgstr "注册验证码" + +#: admin/wp-security-user-registration-menu.php:29 +msgid "Registration honeypot" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:55 +msgid "User registration" +msgstr "用户注册" + +#: admin/wp-security-user-registration-menu.php:115 +msgid "User registration settings" +msgstr "用户注册设置" + +#: admin/wp-security-user-registration-menu.php:119 +msgid "Manually approve new registrations" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:123 +msgid "If your site allows people to create their own accounts via the WordPress registration form, then you can minimize spam or bogus registrations by manually approving each registration." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:124 +msgid "This feature will automatically set a newly registered account to \"pending\" until the administrator activates it. Therefore undesirable registrants will be unable to log in without your express approval." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:125 +msgid "You can view all accounts which have been newly registered via the handy table below and you can also perform bulk activation/deactivation/deletion tasks on each account." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:142 +msgid "Enable manual approval of new registrations" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:145 +msgid "Check this if you want to automatically disable all newly registered accounts so that you can approve them manually." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:154 +msgid "Approve registered users" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:206 +msgid "This feature allows you to add a CAPTCHA form on the WordPress registration page." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:207 +msgid "Users who attempt to register will also need to enter the answer to a simple mathematical question - if they enter the wrong answer, the plugin will not allow them to register." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:208 +msgid "Therefore, adding a CAPTCHA form on the registration page is another effective yet simple spam registration prevention technique." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:212 +msgid "Registration page CAPTCHA settings" +msgstr "注册页面验证码设置" + +#: admin/wp-security-user-registration-menu.php:219 +msgid "The core default behaviour for WordPress Multi Site regarding user registration is that all users are registered via the main site." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:220 +msgid "Therefore, if you would like to add a CAPTCHA form to the registration page for a Multi Site, please go to \"Registration CAPTCHA\" settings on the main site." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:235 +msgid "Enable CAPTCHA on registration page" +msgstr "在注册页面上启用验证码" + +#: admin/wp-security-user-registration-menu.php:238 +msgid "Check this if you want to insert a CAPTCHA form on the WordPress user registration page (if you allow user registration)." +msgstr "如果您要在WordPress用户注册页面上插入验证码表单(如果您允许用户注册),请选中此项。" + +#: admin/wp-security-user-registration-menu.php:276 +msgid "This feature allows you to add a special hidden \"honeypot\" field on the WordPress registration page. This will only be visible to robots and not humans." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:277 +msgid "Since robots usually fill in every input field from a registration form, they will also submit a value for the special hidden honeypot field." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:279 +msgid "Therefore, if the plugin detects that this field has a value when the registration form is submitted, then the robot which is attempting to register on your site will be redirected to its localhost address - http://127.0.0.1." +msgstr "" + +#: admin/wp-security-user-registration-menu.php:285 +msgid "Registration form honeypot settings" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:296 +msgid "Enable honeypot on registration page" +msgstr "" + +#: admin/wp-security-user-registration-menu.php:299 +msgid "Check this if you want to enable the honeypot feature for the registration page" +msgstr "" + +#: classes/aios-ajax.php:89 +msgid "Invalid IP retrieve method." +msgstr "" + +#: classes/aios-ajax.php:131 +#: wp-security-core.php:258 +msgid "The security check failed; try refreshing the page." +msgstr "" + +#: classes/aios-ajax.php:152 +#: wp-security-core.php:268 +msgid "You are not allowed to run this command." +msgstr "" + +#: classes/aios-ajax.php:173 +#: wp-security-core.php:282 +msgid "Options can only be saved by network admin" +msgstr "" + +#: classes/aios-ajax.php:202 +msgid "The command \"%s\" was not found" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:39 +msgid "Remove WP generator meta tag" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:45 +msgid "Change display name" +msgstr "更改显示名称" + +#: classes/grade-system/wp-security-feature-item-manager.php:57 +msgid "Registration approval" +msgstr "人工审核" + +#: classes/grade-system/wp-security-feature-item-manager.php:61 +msgid "Enable registration honeypot" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:73 +msgid "WordPress files access" +msgstr "WordPress文件访问" + +#: classes/grade-system/wp-security-feature-item-manager.php:77 +msgid "IP and user agent blacklisting" +msgstr "IP和用户代理黑名单" + +#: classes/grade-system/wp-security-feature-item-manager.php:81 +msgid "Enable basic firewall" +msgstr "启用基本防火墙" + +#: classes/grade-system/wp-security-feature-item-manager.php:82 +msgid "Enable pingback vulnerability protection" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:83 +msgid "Block access to debug log file" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:87 +msgid "Forbid proxy comments" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:88 +msgid "Deny bad queries" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:91 +msgid "5G/6G blacklist" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:97 +msgid "Enable IP blocking for 404 detection" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:101 +msgid "Enable rename login page" +msgstr "启用重命名登录页面" + +#: classes/grade-system/wp-security-feature-item-manager.php:106 +msgid "Lost password CAPTCHA" +msgstr "忘记密码验证码" + +#: classes/grade-system/wp-security-feature-item-manager.php:107 +msgid "Custom login CAPTCHA" +msgstr "自定义登录验证码" + +#: classes/grade-system/wp-security-feature-item-manager.php:108 +msgid "Woo login CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:109 +msgid "Woo lost password CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:110 +msgid "Woo register CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:112 +msgid "Login IP whitelisting" +msgstr "登录IP白名单" + +#: classes/grade-system/wp-security-feature-item-manager.php:114 +msgid "Enable login honeypot" +msgstr "启用登录蜜罐" + +#: classes/grade-system/wp-security-feature-item-manager.php:118 +msgid "Comment CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:119 +msgid "Block spambots" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:121 +msgid "BuddyPress registration CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item-manager.php:123 +msgid "bbPress new topic CAPTCHA" +msgstr "" + +#: classes/grade-system/wp-security-feature-item.php:29 +msgid "Basic" +msgstr "基本" + +#: classes/grade-system/wp-security-feature-item.php:31 +msgid "Intermediate" +msgstr "中级" + +#: classes/grade-system/wp-security-feature-item.php:33 +msgid "Advanced" +msgstr "高级" + +#: classes/wp-security-captcha.php:47 +#: classes/wp-security-general-init-tasks.php:407 +msgid "Please enter an answer in digits:" +msgstr "请输入数字答案:" + +#: classes/wp-security-captcha.php:127 +msgid "one" +msgstr "1" + +#: classes/wp-security-captcha.php:128 +msgid "two" +msgstr "2" + +#: classes/wp-security-captcha.php:129 +msgid "three" +msgstr "3" + +#: classes/wp-security-captcha.php:130 +msgid "four" +msgstr "4" + +#: classes/wp-security-captcha.php:131 +msgid "five" +msgstr "5" + +#: classes/wp-security-captcha.php:132 +msgid "six" +msgstr "6" + +#: classes/wp-security-captcha.php:133 +msgid "seven" +msgstr "7" + +#: classes/wp-security-captcha.php:134 +msgid "eight" +msgstr "8" + +#: classes/wp-security-captcha.php:135 +msgid "nine" +msgstr "9" + +#: classes/wp-security-captcha.php:136 +msgid "ten" +msgstr "10" + +#: classes/wp-security-captcha.php:137 +msgid "eleven" +msgstr "11" + +#: classes/wp-security-captcha.php:138 +msgid "twelve" +msgstr "12" + +#: classes/wp-security-captcha.php:139 +msgid "thirteen" +msgstr "13" + +#: classes/wp-security-captcha.php:140 +msgid "fourteen" +msgstr "14" + +#: classes/wp-security-captcha.php:141 +msgid "fifteen" +msgstr "15" + +#: classes/wp-security-captcha.php:142 +msgid "sixteen" +msgstr "16" + +#: classes/wp-security-captcha.php:143 +msgid "seventeen" +msgstr "17" + +#: classes/wp-security-captcha.php:144 +msgid "eighteen" +msgstr "18" + +#: classes/wp-security-captcha.php:145 +msgid "nineteen" +msgstr "19" + +#: classes/wp-security-captcha.php:146 +msgid "twenty" +msgstr "20" + +#: classes/wp-security-cronjob-handler.php:34 +msgid "Every 15 minutes" +msgstr "" + +#: classes/wp-security-debug-logger.php:46 +msgid "Unable to get the reason why" +msgstr "" + +#: classes/wp-security-debug-logger.php:47 +msgid "Unable to clear the logs" +msgstr "" + +#: classes/wp-security-file-scan.php:85 +msgid "All In One WP Security - File change detected!" +msgstr "" + +#: classes/wp-security-file-scan.php:87 +msgid "A file change was detected on your system for site URL" +msgstr "" + +#: classes/wp-security-file-scan.php:87 +msgid ". Scan was generated on" +msgstr "" + +#: classes/wp-security-file-scan.php:88 +msgid "A summary of the scan results is shown below:" +msgstr "" + +#: classes/wp-security-file-scan.php:91 +msgid "Login to your site to view the scan details." +msgstr "" + +#: classes/wp-security-file-scan.php:313 +msgid "The following files were added to your host" +msgstr "" + +#: classes/wp-security-file-scan.php:315 +#: classes/wp-security-file-scan.php:323 +#: classes/wp-security-file-scan.php:332 +msgid "modified on: " +msgstr "" + +#: classes/wp-security-file-scan.php:321 +msgid "The following files were removed from your host" +msgstr "" + +#: classes/wp-security-file-scan.php:330 +msgid "The following files were changed on your host" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:212 +#: classes/wp-security-general-init-tasks.php:481 +msgid "Application passwords have been disabled by All In One WP Security & Firewall plugin." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:428 +#: classes/wp-security-general-init-tasks.php:541 +#: classes/wp-security-general-init-tasks.php:574 +#: classes/wp-security-user-login.php:137 +#: classes/wp-security-user-registration.php:74 +msgid "ERROR: Your answer was incorrect - please try again." +msgstr "错误:您的验证码答案不正确 - 请再试一次。" + +#: classes/wp-security-general-init-tasks.php:463 +msgid "Enter something special:" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:476 +msgid "Application passwords" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:485 +msgid "Change setting" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:487 +msgid "Site admin can only change this setting." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:516 +msgid "Error: You entered an incorrect CAPTCHA answer. Please go back and try again." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:558 +msgid "Your CAPTCHA answer was incorrect - please try again." +msgstr "" + +#: classes/wp-security-general-init-tasks.php:567 +msgid "ERROR: Your IP address is currently locked please contact the administrator!" +msgstr "" + +#. translators: %s: Admin Dashboard > WP Security > Brute Force > Login CAPTCHA Tab Link +#: classes/wp-security-general-init-tasks.php:642 +msgid "Your Google reCAPTCHA site key is wrong. Please fill the correct reCAPTCHA keys %s to use the Google reCAPTCHA feature." +msgstr "" + +#. translators: %s: Admin Dashboard > WP Security > Brute Force > Login CAPTCHA Tab Link +#: classes/wp-security-general-init-tasks.php:642 +#: classes/wp-security-notices.php:99 +msgid "here" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +msgid "Would you like All In One WP Security & Firewall to re-insert the security rules in your .htaccess file which were cleared when you deactivated the plugin?" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +#: templates/may-also-like.php:40 +#: templates/may-also-like.php:43 +#: templates/may-also-like.php:54 +#: templates/may-also-like.php:57 +#: templates/may-also-like.php:68 +#: templates/may-also-like.php:71 +#: templates/may-also-like.php:91 +#: templates/may-also-like.php:103 +#: templates/may-also-like.php:115 +#: templates/may-also-like.php:127 +#: templates/may-also-like.php:139 +#: templates/may-also-like.php:151 +#: templates/may-also-like.php:168 +#: templates/may-also-like.php:171 +#: templates/may-also-like.php:183 +#: templates/may-also-like.php:195 +#: templates/may-also-like.php:207 +#: templates/may-also-like.php:219 +#: templates/may-also-like.php:231 +#: templates/may-also-like.php:243 +#: templates/may-also-like.php:252 +#: templates/may-also-like.php:255 +#: templates/may-also-like.php:264 +#: templates/may-also-like.php:267 +#: templates/may-also-like.php:279 +#: templates/may-also-like.php:297 +#: templates/may-also-like.php:309 +#: templates/may-also-like.php:327 +#: templates/may-also-like.php:339 +#: templates/may-also-like.php:351 +#: templates/may-also-like.php:368 +#: templates/may-also-like.php:380 +msgid "Yes" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:655 +#: templates/may-also-like.php:88 +#: templates/may-also-like.php:100 +#: templates/may-also-like.php:112 +#: templates/may-also-like.php:124 +#: templates/may-also-like.php:136 +#: templates/may-also-like.php:148 +#: templates/may-also-like.php:180 +#: templates/may-also-like.php:192 +#: templates/may-also-like.php:204 +#: templates/may-also-like.php:216 +#: templates/may-also-like.php:228 +#: templates/may-also-like.php:240 +#: templates/may-also-like.php:276 +#: templates/may-also-like.php:294 +#: templates/may-also-like.php:306 +#: templates/may-also-like.php:324 +#: templates/may-also-like.php:336 +#: templates/may-also-like.php:348 +#: templates/may-also-like.php:365 +#: templates/may-also-like.php:377 +#: templates/notices/custom-notice.php:27 +msgid "No" +msgstr "" + +#: classes/wp-security-general-init-tasks.php:674 +msgid "Your registration is pending approval." +msgstr "" + +#: classes/wp-security-notices.php:25 +msgid "The All in One Security plugin has disabled the login whitelist setting that you have enabled in the past." +msgstr "" + +#: classes/wp-security-notices.php:29 +msgid "Your website is running on an Apache webserver, the login whitelisting might not be functional until the recent update of AIOS (because it relied upon Apache-specific module features)." +msgstr "" + +#: classes/wp-security-notices.php:31 +msgid "Your website is running on a non-Apache webserver, so the login whitelisting was not functional until the recent update of AIOS (because it relied upon Apache-specific features)." +msgstr "" + +#: classes/wp-security-notices.php:33 +msgid "It began working with AIOS version 5.0.8." +msgstr "" + +#: classes/wp-security-notices.php:33 +msgid "We have disabled it so that your login page will not be blocked unexpectedly." +msgstr "" + +#: classes/wp-security-notices.php:42 +msgid "Would you like to re-enable login whitelisting?" +msgstr "" + +#: classes/wp-security-notices.php:48 +msgid "Removed database backup feature from the All In One WP Security & Firewall plugin" +msgstr "" + +#: classes/wp-security-notices.php:50 +msgid "Beginning with version 5.0.0, AIOS has replaced the AIOS backup method with the superior UpdraftPlus method." +msgstr "" + +#: classes/wp-security-notices.php:51 +msgid "It remains free and is fully supported by the UpdraftPlus team." +msgstr "" + +#: classes/wp-security-notices.php:54 +msgid "You are seeing this notice because you have previously set up automated database backups in AIOS." +msgstr "" + +#: classes/wp-security-notices.php:55 +msgid "Would you like to set up scheduled backups with UpdraftPlus?" +msgstr "" + +#: classes/wp-security-notices.php:61 +msgid "Setup UpdraftPlus backup plugin" +msgstr "" + +#: classes/wp-security-notices.php:67 +msgid "Important: set up your IP address detection settings" +msgstr "" + +#: classes/wp-security-notices.php:69 +msgid "The All in One Security plugin couldn't be certain about the correct method to detect the IP address for your site visitors with your currently-configured IP address detection settings." +msgstr "" + +#: classes/wp-security-notices.php:70 +msgid "It is important for your security to set the IP address detection settings properly." +msgstr "" + +#: classes/wp-security-notices.php:73 +msgid "Please go to the settings and set them now." +msgstr "" + +#: classes/wp-security-notices.php:79 +msgid "Setup IP address detection settings" +msgstr "" + +#: classes/wp-security-notices.php:85 +msgid "Important: Disabled login whitelist setting" +msgstr "" + +#: classes/wp-security-notices.php:91 +msgid "Turn it back on" +msgstr "" + +#: classes/wp-security-notices.php:92 +msgid "Edit the settings" +msgstr "" + +#: classes/wp-security-notices.php:95 +msgid "Keep it off" +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Hey - We noticed All In One WP Security & Firewall has kept your site safe for a while. If you like us, please consider leaving a positive review to spread the word. Or if you have any issues or questions please leave us a support message %s." +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Thank you so much!" +msgstr "" + +#: classes/wp-security-notices.php:99 +msgid "Team All In One WP Security & Firewall" +msgstr "" + +#: classes/wp-security-notices.php:109 +msgid "Enhance your security even more by backing up your site" +msgstr "" + +#: classes/wp-security-notices.php:110 +msgid "UpdraftPlus is the world's most trusted backup plugin from the owners of All In One WP Security & Firewall" +msgstr "" + +#: classes/wp-security-notices.php:121 +msgid "After you've secured your site, we recommend you install our WP-Optimize plugin to streamline it for better website performance." +msgstr "" + +#: classes/wp-security-process-renamed-login-page.php:152 +msgid "Not available." +msgstr "" + +#: classes/wp-security-two-factor-login.php:34 +msgid "Two factor authentication - Admin settings" +msgstr "" + +#: classes/wp-security-two-factor-login.php:97 +msgid "Two Factor Auth" +msgstr "" + +#: classes/wp-security-two-factor-login.php:153 +msgid "PHP OpenSSL or mcrypt module required" +msgstr "" + +#: classes/wp-security-two-factor-login.php:153 +msgid "The All In One WP Security plugin's Two Factor Authentication module requires either the PHP openssl (preferred) or mcrypt module to be installed. Please ask your web hosting company to install one of them." +msgstr "" + +#: classes/wp-security-user-login.php:71 +msgid "You have disabled login lockout by defining the AIOS_DISABLE_LOGIN_LOCKOUT constant value as true, and the login lockout setting has enabled it." +msgstr "" + +#. translators: 1: Locked IP Addresses admin page link +#: classes/wp-security-user-login.php:73 +msgid "Delete your login lockout IP from %s and define the AIOS_DISABLE_LOGIN_LOCKOUT constant value as false." +msgstr "" + +#: classes/wp-security-user-login.php:100 +msgid "ERROR: Access from your IP address has been blocked for security reasons. Please contact the administrator." +msgstr "错误︰ 出于安全考虑,您的IP地址的访问权限已被阻止。 请与管理员联系。" + +#: classes/wp-security-user-login.php:108 +msgid "Service temporarily unavailable" +msgstr "服务暂时无法使用" + +#: classes/wp-security-user-login.php:163 +msgid "ACCOUNT PENDING: Your account is currently not active. An administrator needs to activate your account before you can login." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-user-login.php:242 +msgid "ERROR: Invalid login credentials." +msgstr "错误:无效的登录凭据。" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-user-login.php:392 +msgid "Site Lockout Notification" +msgstr "网站锁定通知" + +#: classes/wp-security-user-login.php:393 +msgid "User login lockout events had occurred due to too many failed login attempts or invalid username:" +msgstr "" + +#: classes/wp-security-user-login.php:396 +msgid "Username:" +msgstr "用户名:" + +#: classes/wp-security-user-login.php:397 +msgid "IP address:" +msgstr "IP 地址:" + +#: classes/wp-security-user-login.php:399 +msgid "IP range:" +msgstr "IP范围:" + +#: classes/wp-security-user-login.php:404 +msgid "Log into your site WordPress administration panel to see the duration of the lockout or to unlock the user." +msgstr "" + +#: classes/wp-security-user-login.php:515 +msgid "Unlock request notification" +msgstr "解锁请求通知" + +#: classes/wp-security-user-login.php:516 +msgid "You have requested for the account with email address %s to be unlocked. Please click the link below to unlock your account:" +msgstr "您已请求通过电子邮件地址 %s 进行账户解锁。请点击以下链接进行帐户解锁:" + +#: classes/wp-security-user-login.php:516 +msgid "Unlock link: %s" +msgstr "解锁链接: %s" + +#: classes/wp-security-user-login.php:516 +msgid "After clicking the above link you will be able to login to the WordPress administration panel." +msgstr "点击上面的链接后,您将能够跳转到登录界面。" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-user-login.php:739 +msgid "Your session has expired because it has been over %d minutes since your last login." +msgstr "您的会话已经过期,因为它已经超过 %d 分钟,自从您的最后一次登录。" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-user-login.php:740 +#: classes/wp-security-user-login.php:744 +msgid "Please log back in to continue." +msgstr "请重新登录以继续。" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-user-login.php:743 +msgid "You were logged out because you just changed the \"admin\" username." +msgstr "你已被注销,因为你刚刚更改了“admin”的用户名。" + +#: classes/wp-security-user-login.php:773 +msgid "Request unlock" +msgstr "请求解锁" + +#: classes/wp-security-user-registration.php:68 +msgid "ERROR: You are not allowed to register because your IP address is currently locked!" +msgstr "错误:您无法注册,因为您的IP地址当前已锁定!" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-utility-ip-address.php:217 +#: classes/wp-security-utility-ip-address.php:231 +#: classes/wp-security-utility-ip-address.php:245 +#: classes/wp-security-utility-ip-address.php:257 +#: classes/wp-security-utility-ip-address.php:269 +msgid " is not a valid ip address format." +msgstr " 不是有效的IP地址格式。" + +# @ all-in-one-wp-security-and-firewall +#: classes/wp-security-utility-ip-address.php:274 +msgid "You cannot ban your own IP address: " +msgstr "你不能禁止自己的 IP 地址:" + +#: classes/wp-security-utility.php:254 +msgid "This feature can only be configured by the \"superadmin\" on the main site." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:32 +msgid "ERROR: Unable to process your request!" +msgstr "" + +#: other-includes/wp-security-unlock-request.php:45 +msgid "Please enter a valid email address" +msgstr "请输入有效的电子邮件地址" + +#: other-includes/wp-security-unlock-request.php:57 +msgid "User account not found!" +msgstr "用户帐户未找到!" + +#: other-includes/wp-security-unlock-request.php:71 +msgid "Error: No locked entry was found in the database with your IP address range." +msgstr "" + +#: other-includes/wp-security-unlock-request.php:76 +msgid "An email has been sent to you with the unlock instructions." +msgstr "有关解锁说明已通过电子邮件发送给您。" + +#: other-includes/wp-security-unlock-request.php:93 +msgid "You are here because you have been locked out due to too many incorrect login attempts." +msgstr "由于多次登陆失败,您已经被锁定。" + +#: other-includes/wp-security-unlock-request.php:94 +msgid "Please enter your email address and you will receive an email with instructions on how to unlock yourself." +msgstr "请输入您的电子邮件地址,您将收到一封电子邮件,请按提示解锁您的帐号。" + +#: other-includes/wp-security-unlock-request.php:104 +msgid "Email Address" +msgstr "Email 地址" + +#: other-includes/wp-security-unlock-request.php:108 +msgid "Send unlock request" +msgstr "" + +#: templates/admin/incompatible-plugin.php:6 +msgid "Two Factor Authentication" +msgstr "" + +#: templates/admin/incompatible-plugin.php:10 +msgid "Two Factor Authentication currently disabled" +msgstr "" + +#: templates/admin/incompatible-plugin.php:12 +#: templates/admin/incompatible-plugin.php:16 +msgid "Two factor authentication in All In One WP Security is currently disabled because the incompatible plugin %s is active." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: templates/automated-database-backup.php:4 +msgid "Automated scheduled backups" +msgstr "自动定时备份" + +#: templates/automated-database-backup.php:9 +msgid "Automate backup in the UpdraftPlus plugin" +msgstr "" + +#: templates/automated-database-backup.php:19 +msgid "The AIOS 5.0.0 version release has removed the automated backup feature." +msgstr "" + +#: templates/automated-database-backup.php:20 +msgid "The AIOS automated backup had issues that made it less robust than we could be happy with." +msgstr "" + +#: templates/automated-database-backup.php:21 +msgid "Follow this link to automate backups in the superior UpdraftPlus backup plugin." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: templates/info/ip-address-ip-range-info.php:5 +msgid "Each IP address must be on a new line." +msgstr "每一个 IP 地址必须新起一行。" + +#: templates/info/ip-address-ip-range-info.php:6 +msgid "To specify an IPv4 range use a wildcard \"*\" character. Acceptable ways to use wildcards is shown in the examples below:" +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: templates/info/ip-address-ip-range-info.php:7 +msgid "Example 1: 195.47.89.*" +msgstr "示例 1:195.47.89.*" + +# @ all-in-one-wp-security-and-firewall +#: templates/info/ip-address-ip-range-info.php:8 +msgid "Example 2: 195.47.*.*" +msgstr "示例 2:195.47.*.*" + +# @ all-in-one-wp-security-and-firewall +#: templates/info/ip-address-ip-range-info.php:9 +msgid "Example 3: 195.*.*.*" +msgstr "示例 3:195.*.*.*" + +#: templates/info/ip-address-ip-range-info.php:10 +msgid "To specify an IPv6 range use CIDR format as shown in the examples below:" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:11 +msgid "Example 4: 2401:4900:54c3:af15:2:2:5dc0:0/112" +msgstr "" + +#: templates/info/ip-address-ip-range-info.php:12 +msgid "Example 5: 2001:db8:1263::/48" +msgstr "" + +#: templates/may-also-like.php:5 +msgid "All-In-One Security (AIOS) Free vs Premium Comparison Chart" +msgstr "" + +#: templates/may-also-like.php:7 +msgid "FAQs" +msgstr "" + +#: templates/may-also-like.php:9 +msgid "Ask a pre-sales question" +msgstr "" + +#: templates/may-also-like.php:17 +msgid "All In One WP Security & Firewall Free" +msgstr "" + +#: templates/may-also-like.php:26 +#: templates/may-also-like.php:386 +msgid "Installed" +msgstr "" + +#: templates/may-also-like.php:29 +#: templates/may-also-like.php:389 +msgid "Upgrade now" +msgstr "" + +#: templates/may-also-like.php:34 +msgid "Login security feature suite" +msgstr "" + +#: templates/may-also-like.php:35 +msgid "Protect against brute-force attacks and keep bots at bay." +msgstr "" + +#: templates/may-also-like.php:35 +msgid "AIOS takes WordPress' default login security features to a whole new level." +msgstr "" + +#: templates/may-also-like.php:37 +msgid "To see all login security features, visit %s" +msgstr "" + +#: templates/may-also-like.php:48 +msgid "Firewall and file protection feature suite" +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Protection from the latest exploits." +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Activate firewall settings ranging from basic, intermediate and advanced." +msgstr "" + +#: templates/may-also-like.php:49 +msgid "Get comprehensive, instant protection with All-in-One Security." +msgstr "" + +#: templates/may-also-like.php:51 +msgid "To see all firewall and file protection features, visit %s" +msgstr "" + +#: templates/may-also-like.php:62 +msgid "Content protection feature suite" +msgstr "" + +#: templates/may-also-like.php:63 +msgid "Eliminate spam and protect your content to dramatically improve your website's interactions with search engines." +msgstr "" + +#: templates/may-also-like.php:65 +msgid "To see all content protection features, visit %s" +msgstr "" + +#: templates/may-also-like.php:76 +msgid "Malware scanning" +msgstr "" + +#: templates/may-also-like.php:77 +msgid "Finding out by accident that your site has been infected with malware is too late." +msgstr "" + +#: templates/may-also-like.php:79 +msgid "Malware can have a dramatic effect on your site's search rankings and you may not even know about it." +msgstr "" + +#: templates/may-also-like.php:79 +msgid "It can slow your website down, access customer data, send unsolicited emails, change your content or prevent users from accessing it." +msgstr "" + +#: templates/may-also-like.php:84 +msgid "Automatic malware scanning" +msgstr "" + +#: templates/may-also-like.php:85 +msgid "Best-in-class scanning for the latest malware, trojans and spyware 24/7." +msgstr "" + +#: templates/may-also-like.php:96 +msgid "Response time monitoring" +msgstr "" + +#: templates/may-also-like.php:97 +msgid "You'll know immediately if your website's response time is negatively affected." +msgstr "" + +#: templates/may-also-like.php:108 +msgid "Up-time monitoring" +msgstr "" + +#: templates/may-also-like.php:109 +msgid "AIOS checks your website's uptime every 5 minutes." +msgstr "" + +#: templates/may-also-like.php:109 +msgid "We'll notify you straight away if your site/server goes down." +msgstr "" + +#: templates/may-also-like.php:120 +msgid "Prevents blacklisting by search engines" +msgstr "" + +#: templates/may-also-like.php:121 +msgid "AIOS monitors your site's blacklist status daily." +msgstr "" + +#: templates/may-also-like.php:121 +msgid "We'll notify you within 24 hours if something's amiss so you can take action, before it's too late." +msgstr "" + +#: templates/may-also-like.php:132 +msgid "Flexible assignment" +msgstr "" + +#: templates/may-also-like.php:133 +msgid "Register and remove websites from the scanning service at any time." +msgstr "" + +#: templates/may-also-like.php:144 +msgid "Malware reports" +msgstr "" + +#: templates/may-also-like.php:145 +msgid "Reports are available via the 'My Account' page and directly via email." +msgstr "" + +#: templates/may-also-like.php:156 +msgid "Flexible two-factor authentication" +msgstr "" + +#: templates/may-also-like.php:157 +msgid "With Two-Factor Authentication (TFA) users enter their username and password and a one-time code sent to a device to login." +msgstr "" + +#: templates/may-also-like.php:159 +msgid "TFA is a feature in both our free and premium packages, but AIOS Premium affords whole new levels of control over how TFA is implemented." +msgstr "" + +#: templates/may-also-like.php:164 +msgid "Authenticator apps" +msgstr "" + +#: templates/may-also-like.php:165 +msgid "Supports TOTP and HOTP protocols." +msgstr "" + +#: templates/may-also-like.php:165 +msgid "TFA Can be used with Google Authenticator, Microsoft Authenticator, Authy and many more." +msgstr "" + +#: templates/may-also-like.php:176 +msgid "Role specific configuration" +msgstr "" + +#: templates/may-also-like.php:177 +msgid "Make it compulsory for certain roles e.g. for admin and editor roles." +msgstr "" + +#: templates/may-also-like.php:188 +msgid "Require TFA after a set time period" +msgstr "" + +#: templates/may-also-like.php:189 +msgid "For example you could require all admins to have TFA once their accounts are a week old." +msgstr "" + +#: templates/may-also-like.php:200 +msgid "Trusted devices - control how often TFA is required" +msgstr "" + +#: templates/may-also-like.php:201 +msgid "Ask for TFA after a chosen number of days for trusted devices instead of on every login." +msgstr "" + +#: templates/may-also-like.php:212 +msgid "Anti-bot protection" +msgstr "" + +#: templates/may-also-like.php:213 +msgid "Option to hide the existence of forms on WooCommerce login pages unless JavaScript is active." +msgstr "" + +#: templates/may-also-like.php:224 +msgid "Customise TFA design layout" +msgstr "" + +#: templates/may-also-like.php:225 +msgid "Customise the design of TFA so it aligns with your existing web design." +msgstr "" + +#: templates/may-also-like.php:236 +msgid "TFA emergency codes" +msgstr "" + +#: templates/may-also-like.php:237 +msgid "Generate a one-time use emergency code to allow access if your device is lost." +msgstr "" + +#: templates/may-also-like.php:248 +msgid "TFA multisite compatibility" +msgstr "" + +#: templates/may-also-like.php:249 +msgid "TFA is Compatible with multisite networks and sub-sites." +msgstr "" + +#: templates/may-also-like.php:260 +msgid "TFA support for common login forms" +msgstr "" + +#: templates/may-also-like.php:261 +msgid "Supports WooCommerce, Affiliates-WP and Theme my Login login forms." +msgstr "" + +#: templates/may-also-like.php:272 +msgid "TFA support for other login forms" +msgstr "" + +#: templates/may-also-like.php:273 +msgid "Supports Elementor Pro, bbPress and all third-party login forms without any further coding needed." +msgstr "" + +#: templates/may-also-like.php:284 +msgid "Smart 404 blocking" +msgstr "" + +#: templates/may-also-like.php:285 +msgid "404 errors can occur when someone legitimately mistypes a URL, but they're also generated by hackers searching for weaknesses in your site." +msgstr "" + +#: templates/may-also-like.php:290 +msgid "Automatically and permanently blocks bots producing 404s" +msgstr "" + +#: templates/may-also-like.php:291 +msgid "AIOS Premium provides more protection than the competition by automatically and permanently blocking IP addresses of bots and hackers based on how many 404 errors they generate." +msgstr "" + +#: templates/may-also-like.php:302 +msgid "404 error charts" +msgstr "" + +#: templates/may-also-like.php:303 +msgid "Handy charts keep you informed of how many 404s have occurred and which IP address or country is producing them." +msgstr "" + +#: templates/may-also-like.php:314 +msgid "Country blocking" +msgstr "" + +#: templates/may-also-like.php:315 +msgid "Most malicious attacks come from a handful of countries and so it's possible to prevent most attacks with our country blocking tool." +msgstr "" + +#: templates/may-also-like.php:320 +msgid "Block traffic based on country of origin" +msgstr "" + +#: templates/may-also-like.php:321 +msgid "AIOS Premium utilises an IP database that promises 99.5% accuracy." +msgstr "" + +#: templates/may-also-like.php:332 +msgid "Block traffic to specific pages based on country of origin" +msgstr "" + +#: templates/may-also-like.php:333 +msgid "Block access to your whole site or on a page-by-page basis." +msgstr "" + +#: templates/may-also-like.php:344 +msgid "Whitelist some users from blocked countries" +msgstr "" + +#: templates/may-also-like.php:345 +msgid "Whitelist IP addresses or IP ranges even if they are part of a blocked country." +msgstr "" + +#: templates/may-also-like.php:356 +msgid "Premium support" +msgstr "" + +#: templates/may-also-like.php:361 +msgid "Unlimited support" +msgstr "" + +#: templates/may-also-like.php:362 +msgid "Personalised, email support from our team of Security experts, as and when you need it." +msgstr "" + +#: templates/may-also-like.php:373 +msgid "Guaranteed response time" +msgstr "" + +#: templates/may-also-like.php:374 +msgid "We offer a guaranteed response time of three days." +msgstr "" + +#: templates/may-also-like.php:374 +msgid "99% of our Premium customers receive a response to their enquiry within 24 hours during the working week." +msgstr "" + +#: templates/may-also-like.php:397 +msgid "Our other plugins" +msgstr "" + +#: templates/may-also-like.php:411 +msgid "UpdraftPlus – the ultimate protection for your site, hard work and business" +msgstr "" + +#: templates/may-also-like.php:412 +msgid "Simplifies backups and restoration." +msgstr "" + +#: templates/may-also-like.php:412 +msgid "It is the world's highest ranking and most popular scheduled backup plugin, with over three million currently-active installs." +msgstr "" + +#: templates/may-also-like.php:413 +#: templates/may-also-like.php:419 +#: templates/may-also-like.php:425 +#: templates/may-also-like.php:431 +msgid "Try for free" +msgstr "" + +#: templates/may-also-like.php:417 +msgid "WP-Optimize – keep your database fast and efficient" +msgstr "" + +#: templates/may-also-like.php:418 +msgid "Makes your site fast and efficient." +msgstr "" + +#: templates/may-also-like.php:418 +msgid "It cleans the database, compresses images and caches pages for ultimate speed." +msgstr "" + +#: templates/may-also-like.php:423 +msgid "UpdraftCentral – save hours managing multiple WP sites from one place" +msgstr "" + +#: templates/may-also-like.php:424 +msgid "Highly efficient way to manage, optimize, update and backup multiple websites from one place." +msgstr "" + +#: templates/may-also-like.php:429 +msgid "Easy Updates Manager" +msgstr "" + +#: templates/may-also-like.php:430 +msgid "Keeps your WordPress site up to date and bug free." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:2 +msgid "IP address detection settings" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:6 +msgid "The IP address detection settings allow you to specify how visitors' IP addresses are made known to PHP (and hence to WordPress and its plugins)." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:7 +msgid "Usually, this is automatic and there is only one choice." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:8 +msgid "However in some setups, such as those using proxies (including load-balancers and security firewalls like Cloudflare), it may be necessary to set this manually." +msgstr "" + +# @ all-in-one-wp-security-and-firewall +#: templates/menus/settings/advanced-settings.php:9 +msgid "Attention" +msgstr "注意!" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "It is important to set this correctly - otherwise you may make it possible for a hacker to ban all your visitors (e.g. via banning Cloudflare from connecting to you) instead of being banned himself." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:9 +msgid "The default is to use the REMOTE_ADDR PHP server variable. If this variable does not contain the visitor's IP address, then whilst you can make a different selection below, it is better to ask your web hosting company to have it correctly set." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:10 +msgid "This is the most secure setup, because when set correctly it is immune from being spoofed by an attacker." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:16 +msgid "You have no available IP address detection method(s); you must contact your web hosting company." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:22 +#: templates/menus/settings/advanced-settings.php:27 +#: templates/menus/settings/advanced-settings.php:32 +msgid "Your detected IP address according to %s:" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:38 +msgid "If your site is setup on localhost, you won't see your external IP address using your server's IP detection setting; but on a localhost-served site (not available to the outside world), the setting is irrelevant and can be ignored." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:61 +msgid "Choose a $_SERVER variable you would like to detect visitors' IP address using." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:67 +msgid "If your chosen server variable fails the plugin will automatically fall back to retrieving the IP address from $_SERVER[\"REMOTE_ADDR\"]" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:73 +msgid "Your IP address if using this setting:" +msgstr "" + +#: templates/menus/settings/advanced-settings.php:75 +msgid "fetching..." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:81 +#: templates/menus/settings/advanced-settings.php:190 +msgid "getting..." +msgstr "" + +#: templates/menus/settings/advanced-settings.php:89 +msgid "look-up possibly blocked by an ad-blocker or similar tool" +msgstr "" + +#: templates/notices/cookie-based-brute-force-prevention-disabled.php:4 +msgid "Cookie based brute force login prevention currently disabled" +msgstr "" + +#: templates/notices/cookie-based-brute-force-prevention-disabled.php:6 +msgid "Cookie based brute force login prevention is currently disabled via the AIOS_DISABLE_COOKIE_BRUTE_FORCE_PREVENTION constant (which is mostly likely to be defined in your wp-config.php)" +msgstr "" + +#: templates/notices/disable-login-whitelist.php:4 +msgid "Login whitelisting currently disabled" +msgstr "" + +#: templates/notices/disable-login-whitelist.php:6 +msgid "Login whitelisting is currently disabled via the AIOS_DISABLE_LOGIN_WHITELIST constant (which is mostly likely to be defined in your wp-config.php)" +msgstr "" + +#: templates/notices/horizontal-notice.php:8 +#: templates/notices/horizontal-notice.php:40 +msgid "notice image" +msgstr "" + +#: templates/notices/horizontal-notice.php:18 +msgid "Ok, you deserve it" +msgstr "" + +#: templates/notices/horizontal-notice.php:22 +msgid "Maybe later" +msgstr "" + +#: templates/notices/horizontal-notice.php:26 +msgid "Never" +msgstr "" + +#: templates/notices/horizontal-notice.php:66 +msgid "Get UpdraftCentral" +msgstr "" + +#: templates/notices/horizontal-notice.php:68 +msgid "Get UpdraftPlus" +msgstr "" + +#: templates/notices/horizontal-notice.php:70 +msgid "Get WP-Optimize" +msgstr "" + +#: templates/notices/horizontal-notice.php:72 +msgid "Find out more." +msgstr "" + +#: templates/notices/horizontal-notice.php:74 +msgid "Sign up" +msgstr "" + +#: templates/notices/horizontal-notice.php:76 +msgid "Go there" +msgstr "" + +#: templates/notices/horizontal-notice.php:78 +msgid "Read more" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:4 +msgid "Dismiss (for %s months)" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:6 +msgid "Thank you for installing All In One WP Security & Firewall!" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:13 +msgid "Super-charge and secure your WordPress site even more with our other top plugins:" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:17 +msgid "%s makes your site fast and efficient. It cleans the database, compresses images and caches pages for ultimate speed." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:21 +msgid "%s simplifies backups and restoration. It is the world's highest ranking and most popular scheduled backup plugin, with over three million currently-active installs." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:25 +msgid "%s is a highly efficient way to manage, optimize, update and backup multiple websites from one place." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:29 +msgid "%s is a WordPress subscription extension for WooCommerce store owners." +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:33 +msgid "More quality plugins" +msgstr "" + +#: templates/notices/thanks-for-using-main-dash.php:33 +msgid "Premium WooCommerce plugins" +msgstr "" + +#: templates/partials/non-apache-feature-notice.php:9 +msgid "This feature works only on the Apache server." +msgstr "" + +#: templates/partials/non-apache-feature-notice.php:10 +msgid "You are using the non-apache server %s, so this feature won't work on your site." +msgstr "" + +#: wp-security-core.php:236 +#: wp-security.php:45 +msgid "This plugin requires PHP version %s." +msgstr "" + +#: wp-security-core.php:237 +msgid "Current site PHP version is %s." +msgstr "" + +#: wp-security-core.php:238 +#: wp-security.php:47 +msgid "You will need to ask your web hosting company to upgrade." +msgstr "" + +#: wp-security-core.php:397 +msgid "Error:" +msgstr "" + +#: wp-security-core.php:397 +msgid "template not found" +msgstr "" + +#: wp-security.php:44 +msgid "All In One WP Security and Firewall plugin has been deactivated." +msgstr "" + +#: wp-security.php:46 +msgid "Your current PHP version is %s." +msgstr "" diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall.pot b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall.pot new file mode 100755 index 00000000..a892f6da --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/all-in-one-wp-security-and-firewall.pot @@ -0,0 +1,7895 @@ +# Copyright (C) 2025 all-in-one-wp-security-and-firewall +# This file is distributed under the same license as the all-in-one-wp-security-and-firewall package. +msgid "" +msgstr "" +"Project-Id-Version: all-in-one-wp-security-and-firewall\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language-Team: Team Updraft \n" +"Last-Translator: Team Updraft \n" +"POT-Creation-Date: 2025-11-06 13:53+0000\n" +"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/all-in-one-wp-security-and-firewall\n" +"X-Poedit-Basepath: ..\n" +"X-Poedit-KeywordsList: __;_e;_ex:1,2c;_n:1,2;_n_noop:1,2;_nx:1,2,4c;_nx_noop:1,2,3c;_x:1,2c;esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c\n" +"X-Poedit-SearchPath-0: .\n" +"X-Poedit-SearchPathExcluded-0: *.js\n" +"X-Poedit-SourceCharset: UTF-8\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: dist/wp-security-core.php:352, dist/admin/wp-security-database-menu.php:134, dist/admin/wp-security-database-menu.php:137, dist/admin/wp-security-database-menu.php:141, dist/includes/simba-tfa/simba-tfa.php:1065, dist/includes/simba-tfa/simba-tfa.php:1470, dist/includes/simba-tfa/simba-tfa.php:1507, dist/includes/simba-tfa/simba-tfa.php:1521, dist/includes/simba-tfa/simba-tfa.php:1664, dist/includes/simba-tfa/includes/login-form-integrations.php:128 +msgid "Error:" +msgstr "" + +#: dist/wp-security-core.php:352 +msgid "template not found" +msgstr "" + +#: dist/wp-security.php:43 +msgid "All In One WP Security" +msgstr "" + +#: dist/wp-security.php:44 +msgid "All In One WP Security plugin has been deactivated." +msgstr "" + +#. translators: %s: Required PHP version +#: dist/wp-security.php:46 +msgid "This plugin requires PHP version %s." +msgstr "" + +#. translators: %s: PHP version +#: dist/wp-security.php:48 +msgid "Your current PHP version is %s." +msgstr "" + +#: dist/wp-security.php:49 +msgid "You will need to ask your web hosting company to upgrade." +msgstr "" + +#: dist/wp-security.php:64, dist/admin/wp-security-admin-init.php:86, dist/admin/wp-security-admin-init.php:87, dist/admin/wp-security-settings-menu.php:23, dist/includes/simba-tfa/templates/user-settings.php:20, dist/templates/wp-admin/brute-force/captcha-settings.php:27, dist/templates/wp-admin/filesystem-security/file-protection.php:29 +msgid "Settings" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:78, dist/admin/wp-security-admin-init.php:79, dist/admin/wp-security-dashboard-menu.php:19, dist/admin/wp-security-dashboard-menu.php:30 +msgid "Dashboard" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:94, dist/admin/wp-security-admin-init.php:95, dist/admin/wp-security-user-security-menu.php:19 +msgid "User Security" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:102, dist/admin/wp-security-admin-init.php:103 +msgid "Database Security" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:111, dist/admin/wp-security-admin-init.php:112 +msgid "File Security" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:119, dist/admin/wp-security-admin-init.php:120, dist/admin/wp-security-firewall-menu.php:22, dist/templates/wp-admin/dashboard/may-also-like.php:144, dist/templates/wp-admin/firewall/partials/firewall-setup.php:13 +msgid "Firewall" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:127, dist/admin/wp-security-admin-init.php:128 +msgid "Brute Force" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:135, dist/admin/wp-security-admin-init.php:136 +msgid "Spam Prevention" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:143, dist/admin/wp-security-admin-init.php:144, dist/admin/wp-security-filescan-menu.php:25 +msgid "Scanner" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:152, dist/admin/wp-security-admin-init.php:153, dist/admin/wp-security-tools-menu.php:20 +msgid "Tools" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:223 +msgid "Id" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:224 +msgid "Event Type" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:225 +msgid "IP Address" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:226, dist/admin/wp-security-list-404.php:115 +msgid "Attempted URL" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:227, dist/admin/wp-security-list-404.php:116 +msgid "Referer" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:228, dist/admin/wp-security-list-404.php:117, dist/admin/wp-security-list-audit.php:176, dist/admin/wp-security-list-debug.php:53, dist/classes/commands/wp-security-log-commands.php:104 +msgid "Date and time" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:229 +msgid "Lock Status" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:351, dist/templates/wp-admin/settings/advanced-settings.php:83 +msgid "Unexpected response:" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:352 +msgid "Copied" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:353 +msgid "You have not yet selected a file to import." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:354 +msgid "Processing..." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:355 +msgid "Please enter a valid IP address or domain name." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:357, dist/includes/simba-tfa/includes/tfa_frontend.php:183 +msgid "Saving..." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:358 +msgid "Deleting..." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:359 +msgid "Blocking..." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:360 +msgid "Unlocking..." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:361 +msgid "Clearing..." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:362 +msgid "Importing..." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:363 +msgid "Exporting..." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:364 +msgid "Refreshing..." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:365 +msgid "Scanning..." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:366 +msgid "Close" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:367 +msgid "Completed." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:368 +msgid "Refreshed." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:369 +msgid "Deleted." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:370 +msgid "show more" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:371 +msgid "hide" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:372 +msgid "But the following notices have been raised" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:373 +msgid "Disabling..." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:374 +msgid "Setting up firewall..." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:375 +msgid "Downgrading firewall..." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:376, dist/admin/wp-security-dashboard-menu.php:489 +msgid "Maintenance mode is currently enabled." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:376, dist/admin/wp-security-dashboard-menu.php:489 +msgid "Remember to disable it when you are done." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:377, dist/admin/wp-security-dashboard-menu.php:491 +msgid "Maintenance mode is currently disabled." +msgstr "" + +#: dist/admin/wp-security-admin-init.php:384 +msgid "year(s)" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:385 +msgid "month(s)" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:386 +msgid "day(s)" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:387 +msgid "hour(s)" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:388 +msgid "minute(s)" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:389 +msgid "second(s)" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:390 +msgid "less than one second" +msgstr "" + +#. translators: 1: Product Name, 2: Rating, 3: Trustpilot URL, 4: G2 URL +#: dist/admin/wp-security-admin-init.php:427 +msgid "Enjoyed %1$s? Please leave us a %2$s rating on %3$s or %4$s" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:427 +msgid "We really appreciate your support!" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:505, dist/admin/wp-security-admin-init.php:505, dist/classes/wp-security-two-factor-login.php:121, dist/classes/wp-security-two-factor-login.php:121 +msgid "AIOS" +msgstr "" + +#: dist/admin/wp-security-admin-init.php:522 +msgid "Premium Upgrade" +msgstr "" + +#: dist/admin/wp-security-admin-menu.php:117 +msgid "Press to toggle" +msgstr "" + +#: dist/admin/wp-security-admin-menu.php:160, dist/admin/wp-security-admin-menu.php:176, dist/classes/wp-security-commands.php:266, dist/classes/commands/wp-brute-force-commands.php:51, dist/classes/commands/wp-brute-force-commands.php:123, dist/classes/commands/wp-security-tools-commands.php:129, dist/classes/commands/wp-security-user-security-commands.php:206, dist/classes/commands/wp-security-user-security-commands.php:284, dist/classes/commands/wp-security-user-security-commands.php:329, dist/classes/commands/wp-security-user-security-commands.php:376, dist/classes/commands/wp-security-user-security-commands.php:417, dist/classes/commands/wp-security-user-security-commands.php:508 +msgid "The settings have been successfully updated." +msgstr "" + +#: dist/admin/wp-security-admin-menu.php:190, dist/admin/wp-security-list-audit.php:355, dist/classes/commands/wp-brute-force-commands.php:467 +msgid "The selected record(s) has been deleted successfully." +msgstr "" + +#: dist/admin/wp-security-admin-menu.php:200, dist/admin/wp-security-list-audit.php:342, dist/admin/wp-security-list-audit.php:358, dist/classes/commands/wp-brute-force-commands.php:465 +msgid "The selected record(s) have failed to delete." +msgstr "" + +#: dist/admin/wp-security-brute-force-menu.php:24 +msgid "Brute force" +msgstr "" + +#: dist/admin/wp-security-brute-force-menu.php:35, dist/admin/wp-security-dashboard-menu.php:532, dist/templates/wp-admin/brute-force/login-whitelist.php:17 +msgid "Rename login page" +msgstr "" + +#: dist/admin/wp-security-brute-force-menu.php:39, dist/templates/wp-admin/brute-force/rename-login.php:6 +msgid "Cookie based brute force prevention" +msgstr "" + +#: dist/admin/wp-security-brute-force-menu.php:44 +msgid "CAPTCHA settings" +msgstr "" + +#: dist/admin/wp-security-brute-force-menu.php:48, dist/templates/wp-admin/brute-force/login-whitelist.php:2 +msgid "Login whitelist" +msgstr "" + +#: dist/admin/wp-security-brute-force-menu.php:52 +msgid "404 detection" +msgstr "" + +#: dist/admin/wp-security-brute-force-menu.php:57 +msgid "Honeypot" +msgstr "" + +#: dist/admin/wp-security-brute-force-menu.php:116, dist/classes/commands/wp-brute-force-commands.php:316 +msgid "Your Cloudflare Turnstile configuration is invalid." +msgstr "" + +#: dist/admin/wp-security-brute-force-menu.php:116, dist/classes/commands/wp-brute-force-commands.php:316 +msgid "Please enter the correct Cloudflare Turnstile keys below to use the Turnstile feature." +msgstr "" + +#. translators: %s: Admin Dashboard > WP Security > Brute Force > Login CAPTCHA Tab Link +#: dist/admin/wp-security-brute-force-menu.php:120, dist/classes/wp-security-general-init-tasks.php:829, dist/classes/commands/wp-brute-force-commands.php:318 +msgid "Your Google reCAPTCHA configuration is invalid." +msgstr "" + +#: dist/admin/wp-security-brute-force-menu.php:120, dist/classes/commands/wp-brute-force-commands.php:318 +msgid "Please enter the correct reCAPTCHA keys below to use the reCAPTCHA feature." +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:34, dist/admin/wp-security-dashboard-menu.php:218, dist/admin/wp-security-dashboard-menu.php:589, dist/classes/wp-security-user-login.php:83 +msgid "Locked IP addresses" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:38 +msgid "Permanent block list" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:42, dist/templates/wp-admin/dashboard/audit-logs.php:3 +msgid "Audit logs" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:46 +msgid "Debugging" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:50 +msgid "Premium upgrade" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:205 +msgid "Security strength meter" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:206 +msgid "Security points breakdown" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:207 +msgid "Spread the word" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:208 +msgid "Get to know the developers" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:209 +msgid "Critical feature status" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:210 +msgid "Last 5 login summary" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:211 +msgid "Maintenance mode status" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:215 +msgid "Brute force prevention login page" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:217, dist/admin/wp-security-dashboard-menu.php:549, dist/admin/wp-security-user-security-menu.php:42 +msgid "Logged in users" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:224, dist/admin/wp-security-dashboard-menu.php:477 +msgid "View all" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:278 +msgid "Website strength:" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:283 +msgid "Total Achievable Points:" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:284 +msgid "Current Score of Your Site:" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:334 +msgid "We are working hard to make your WordPress site more secure." +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:334 +msgid "Please support us, here is how:" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:335 +msgid "Follow us on" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:339 +msgid "Post to X" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:343 +msgid "Give us a good rating" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:350 +msgid "Wanna know more about the developers behind this plugin?" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:365 +msgid "Admin username" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:369, dist/admin/wp-security-user-security-menu.php:34, dist/classes/grade-system/wp-security-feature-item-manager.php:81, dist/templates/wp-admin/dashboard/locked-ip.php:4 +msgid "Login lockout" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:373 +msgid "File permission" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:378 +msgid "Basic firewall" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:383, dist/admin/wp-security-database-menu.php:86, dist/classes/grade-system/wp-security-feature-item-manager.php:157 +msgid "Database prefix" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:388 +msgid "PHP file editing" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:393 +msgid "Renamed login page" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:397 +msgid "Hidden WP meta info" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:405 +msgid "Below is the current status of the critical features that you should activate on your site to achieve a minimum level of recommended security" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:450, dist/admin/wp-security-dashboard-menu.php:469 +msgid "Date" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:450 +msgid "Logins" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:469 +msgid "User" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:465 +msgid "No data found." +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:498, dist/templates/wp-admin/tools/visitor-lockout.php:14 +msgid "Enable maintenance mode" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:507 +msgid "Configure" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:513 +msgid "Cookie-based brute force" +msgstr "" + +#. translators: %s: Brute Force Login URL +#. translators: %s: Rename Login URL +#: dist/admin/wp-security-dashboard-menu.php:517, dist/admin/wp-security-dashboard-menu.php:535 +msgid "The %s feature is currently active." +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:518, dist/admin/wp-security-dashboard-menu.php:536 +msgid "Your new WordPress login URL is now:" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:551 +msgid "Number of users currently logged into your site (including you) is:" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:552 +msgid "There are no other users currently logged in." +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:566 +msgid "Number of users currently logged in site-wide (including you) is:" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:567 +msgid "There are no other site-wide users currently logged in." +msgstr "" + +#. translators: %s: Users Online URL +#. translators: %s: Number of locked out IPs +#: dist/admin/wp-security-dashboard-menu.php:581, dist/admin/wp-security-dashboard-menu.php:598 +msgid "Go to the %s menu to see more details" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:596 +msgid "Number of temporarily locked out IP addresses:" +msgstr "" + +#: dist/admin/wp-security-dashboard-menu.php:593 +msgid "There are no IP addresses currently locked out." +msgstr "" + +#: dist/admin/wp-security-database-menu.php:19 +msgid "Database security" +msgstr "" + +#: dist/admin/wp-security-database-menu.php:49 +msgid "UpdraftPlus is installed but currently not active." +msgstr "" + +#: dist/admin/wp-security-database-menu.php:49 +msgid "Follow this link to activate UpdraftPlus, to take a backup." +msgstr "" + +#: dist/admin/wp-security-database-menu.php:54 +msgid "Follow this link to install UpdraftPlus, to take a database backup." +msgstr "" + +#: dist/admin/wp-security-database-menu.php:91 +msgid "Database backup" +msgstr "" + +#: dist/admin/wp-security-database-menu.php:114 +msgid "Nonce check failed for DB prefix change operation." +msgstr "" + +#: dist/admin/wp-security-database-menu.php:134 +msgid "prefix contains HTML tags" +msgstr "" + +#: dist/admin/wp-security-database-menu.php:137 +msgid "prefix contains invalid characters, the prefix should only contain alphanumeric and underscore characters." +msgstr "" + +#: dist/admin/wp-security-database-menu.php:129 +msgid "Please enter a value for the DB prefix." +msgstr "" + +#: dist/admin/wp-security-database-menu.php:121 +msgid "The plugin has detected that it cannot write to the wp-config.php file." +msgstr "" + +#: dist/admin/wp-security-database-menu.php:121 +msgid "This feature can only be used if the plugin can successfully write to the wp-config.php file." +msgstr "" + +#: dist/admin/wp-security-database-menu.php:169 +msgid "Take a database backup using UpdraftPlus" +msgstr "" + +#: dist/admin/wp-security-database-menu.php:204 +msgid "Error - Could not get tables or no tables found!" +msgstr "" + +#: dist/admin/wp-security-database-menu.php:208 +msgid "Starting DB prefix change operations....." +msgstr "" + +#: dist/admin/wp-security-database-menu.php:210 +msgid "Your WordPress system has a total of %s tables and your new DB prefix will be: %s" +msgstr "" + +#: dist/admin/wp-security-database-menu.php:218 +msgid "A backup copy of your wp-config.php file was created successfully!" +msgstr "" + +#: dist/admin/wp-security-database-menu.php:215, dist/classes/wp-security-utility.php:316 +msgid "Failed to make a backup of the wp-config.php file." +msgstr "" + +#: dist/admin/wp-security-database-menu.php:215, dist/classes/wp-security-utility.php:316 +msgid "This operation will not go ahead." +msgstr "" + +#: dist/admin/wp-security-database-menu.php:243 +msgid "%s table name update failed" +msgstr "" + +#: dist/admin/wp-security-database-menu.php:255 +msgid "%s tables had their prefix updated successfully!" +msgstr "" + +#: dist/admin/wp-security-database-menu.php:253 +msgid "Please change the prefix manually for the above tables to: %s" +msgstr "" + +#: dist/admin/wp-security-database-menu.php:277 +msgid "The \"wp-config.php\" file was not able to be modified." +msgstr "" + +#: dist/admin/wp-security-database-menu.php:277 +msgid "Please modify this file manually using your favourite editor and search for variable \"$table_prefix\" and assign the following value to that variable: %s" +msgstr "" + +#: dist/admin/wp-security-database-menu.php:275 +msgid "wp-config.php file was updated successfully!" +msgstr "" + +#: dist/admin/wp-security-database-menu.php:288 +msgid "The options table records which had references to the old DB prefix were updated successfully!" +msgstr "" + +#: dist/admin/wp-security-database-menu.php:285, dist/admin/wp-security-database-menu.php:301 +msgid "Update of table %s failed: unable to change %s to %s" +msgstr "" + +#: dist/admin/wp-security-database-menu.php:304 +msgid "The %s table records which had references to the old DB prefix were updated successfully!" +msgstr "" + +#: dist/admin/wp-security-database-menu.php:325 +msgid "Error updating user_meta table where new meta_key = %s, old meta_key = %s and user_id = %s." +msgstr "" + +#: dist/admin/wp-security-database-menu.php:330 +msgid "The usermeta table records which had references to the old DB prefix were updated successfully!" +msgstr "" + +#: dist/admin/wp-security-database-menu.php:332 +msgid "The database prefix change tasks have been completed." +msgstr "" + +#: dist/admin/wp-security-database-menu.php:379 +msgid "Checking for MySQL tables of type \"view\"....." +msgstr "" + +#: dist/admin/wp-security-database-menu.php:396 +msgid "Update of the following MySQL view definition failed: %s" +msgstr "" + +#: dist/admin/wp-security-database-menu.php:403 +msgid "%s view definitions were updated successfully." +msgstr "" + +#: dist/admin/wp-security-filescan-menu.php:36, dist/classes/grade-system/wp-security-feature-item-manager.php:409 +msgid "File change detection" +msgstr "" + +#: dist/admin/wp-security-filescan-menu.php:40 +msgid "Malware scan" +msgstr "" + +#: dist/admin/wp-security-filesystem-menu.php:18 +msgid "File security" +msgstr "" + +#: dist/admin/wp-security-filesystem-menu.php:30, dist/classes/grade-system/wp-security-feature-item-manager.php:167 +msgid "File permissions" +msgstr "" + +#: dist/admin/wp-security-filesystem-menu.php:35, dist/templates/wp-admin/filesystem-security/file-protection.php:2 +msgid "File protection" +msgstr "" + +#: dist/admin/wp-security-filesystem-menu.php:40 +msgid "Host system logs" +msgstr "" + +#: dist/admin/wp-security-filesystem-menu.php:45 +msgid "Copy protection" +msgstr "" + +#: dist/admin/wp-security-filesystem-menu.php:49 +msgid "Frames" +msgstr "" + +#: dist/admin/wp-security-firewall-menu.php:33 +msgid "PHP rules" +msgstr "" + +#: dist/admin/wp-security-firewall-menu.php:37 +msgid ".htaccess rules" +msgstr "" + +#: dist/admin/wp-security-firewall-menu.php:42, dist/templates/wp-admin/general/moved.php:6 +msgid "6G firewall rules" +msgstr "" + +#: dist/admin/wp-security-firewall-menu.php:47 +msgid "5G legacy rules" +msgstr "" + +#: dist/admin/wp-security-firewall-menu.php:52, dist/templates/wp-admin/general/moved.php:10 +msgid "Internet bots" +msgstr "" + +#: dist/admin/wp-security-firewall-menu.php:57 +msgid "Block & allow lists" +msgstr "" + +#: dist/admin/wp-security-firewall-menu.php:62, dist/admin/wp-security-settings-menu.php:60, dist/templates/wp-admin/firewall/advanced-settings.php:2, dist/includes/simba-tfa/providers/totp/loader.php:245 +msgid "Advanced settings" +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:389, dist/admin/wp-security-firewall-setup-notice.php:521, dist/classes/commands/wp-security-firewall-commands.php:725, dist/templates/notices/firewall-installed-notice.php:2, dist/templates/notices/firewall-setup-notice.php:9, dist/templates/wp-admin/settings/general-settings.php:12 +msgid "All-In-One Security" +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:391 +msgid "We were unable to create the file necessary to give you the highest level of protection." +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:392 +msgid "Your firewall will have reduced protection which means some of your firewall's functionality will be unavailable." +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:393 +msgid "If you would like to manually set up the necessary file, please follow these steps:" +msgstr "" + +#. translators: %s Bootstrap file name. +#. translators: %s Firewall file name. +#: dist/admin/wp-security-firewall-setup-notice.php:397, dist/admin/wp-security-firewall-setup-notice.php:495 +msgid "1. Create a file with the name %s in the same directory as your WordPress install is in, i.e.:" +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:401 +msgid "2. Paste in the following code:" +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:403, dist/admin/wp-security-firewall-setup-notice.php:504 +msgid "3. Save the file and press the 'Try again' button below:" +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:422 +msgid "1. Open the following file:" +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:432 +msgid "2. Look for the following:" +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:428 +msgid "2. Look for the auto_prepend_file directive." +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:438 +msgid "3. Change it to the following:" +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:442 +msgid "4. Save the file and press the 'Try again' button below:" +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:442, dist/admin/wp-security-firewall-setup-notice.php:483 +msgid "You may have to wait up to 5 minutes before the settings take effect." +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:500 +msgid "2. Paste in the following directives:" +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:476 +msgid "1. Open your php.ini file." +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:479 +msgid "2. Set the auto_prepend_file directive like below:" +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:483 +msgid "3. Restart the webserver and refresh the page" +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:524 +msgid "We were unable to set up your firewall with the highest level of protection." +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:525 +msgid "Your firewall will have reduced functionality." +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:529 +msgid "To give your site the highest level of protection, please follow these steps:" +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:542 +msgid "Note: if you're unable to perform any of the aforementioned steps, please ask your web hosting provider for further assistance." +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:559 +msgid "Try again" +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:581 +msgid "We have detected that your AIOS firewall is not fully installed, and therefore does not have the highest level of protection." +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:582 +msgid "Your firewall will have reduced functionality until it has been upgraded." +msgstr "" + +#: dist/admin/wp-security-firewall-setup-notice.php:584 +msgid "Upgrade your protection now" +msgstr "" + +#: dist/admin/wp-security-list-404.php:48, dist/admin/wp-security-list-audit.php:62, dist/admin/wp-security-list-locked-ip.php:65 +msgid "Are you sure you want to delete this item?" +msgstr "" + +#: dist/admin/wp-security-list-404.php:48, dist/admin/wp-security-list-404.php:148, dist/admin/wp-security-list-audit.php:62, dist/admin/wp-security-list-locked-ip.php:65, dist/admin/wp-security-list-locked-ip.php:161, dist/admin/wp-security-list-registered-users.php:37, dist/admin/wp-security-list-registered-users.php:104, dist/templates/wp-admin/filesystem-security/partials/wp-file-access.php:27 +msgid "Delete" +msgstr "" + +#: dist/admin/wp-security-list-404.php:60, dist/admin/wp-security-list-registered-users.php:38 +msgid "Are you sure you want to block this IP address?" +msgstr "" + +#: dist/admin/wp-security-list-404.php:60 +msgid "Temporarily block" +msgstr "" + +#: dist/admin/wp-security-list-404.php:61, dist/admin/wp-security-list-comment-spammer-ip.php:34 +msgid "Are you sure you want to permanently block this IP address?" +msgstr "" + +#: dist/admin/wp-security-list-404.php:61, dist/admin/wp-security-list-404.php:147, dist/admin/wp-security-list-audit.php:98 +msgid "Blacklist IP" +msgstr "" + +#: dist/admin/wp-security-list-404.php:56, dist/admin/wp-security-list-404.php:52 +msgid "Are you sure you want to unblock this item?" +msgstr "" + +#: dist/admin/wp-security-list-404.php:56, dist/admin/wp-security-list-404.php:52, dist/admin/wp-security-list-permanent-blocked-ip.php:89 +msgid "Unblock" +msgstr "" + +#: dist/admin/wp-security-list-404.php:113 +msgid "Event type" +msgstr "" + +#: dist/admin/wp-security-list-404.php:114, dist/admin/wp-security-list-logged-in-users.php:55, dist/admin/wp-security-list-registered-users.php:85 +msgid "IP address" +msgstr "" + +#: dist/admin/wp-security-list-404.php:118 +msgid "Lock status" +msgstr "" + +#: dist/admin/wp-security-list-404.php:146 +msgid "Temporarily block IP" +msgstr "" + +#: dist/admin/wp-security-list-404.php:169, dist/admin/wp-security-list-404.php:178, dist/admin/wp-security-list-404.php:186, dist/admin/wp-security-list-audit.php:240, dist/admin/wp-security-list-comment-spammer-ip.php:102, dist/admin/wp-security-list-locked-ip.php:179, dist/admin/wp-security-list-locked-ip.php:188, dist/admin/wp-security-list-permanent-blocked-ip.php:102, dist/admin/wp-security-list-registered-users.php:122, dist/admin/wp-security-list-registered-users.php:130, dist/admin/wp-security-list-registered-users.php:138 +msgid "Please select some records using the checkboxes" +msgstr "" + +#: dist/admin/wp-security-list-404.php:213, dist/admin/wp-security-list-404.php:247 +msgid "Could not process the request because the IP addresses for the selected entries could not be found." +msgstr "" + +#: dist/admin/wp-security-list-404.php:222 +msgid "The selected IP addresses are now temporarily blocked." +msgstr "" + +#: dist/admin/wp-security-list-404.php:266, dist/classes/commands/wp-brute-force-commands.php:510 +msgid "The selected IP addresses have been added to the blacklist and will be permanently blocked." +msgstr "" + +#: dist/admin/wp-security-list-audit.php:78 +msgid "Are you sure you want to unblacklist this IP address?" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:79 +msgid "Are you sure you want to unlock this IP address?" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:80 +msgid "Are you sure you want to temporarily lock this IP address?" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:81 +msgid "Are you sure you want to blacklist this IP address?" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:94 +msgid "Lock IP" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:90, dist/admin/wp-security-list-locked-ip.php:64, dist/admin/wp-security-list-locked-ip.php:160 +msgid "Unlock" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:86 +msgid "Unblacklist" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:113 +msgid "No event type available." +msgstr "" + +#: dist/admin/wp-security-list-audit.php:149 +msgid "No stack trace available." +msgstr "" + +#: dist/admin/wp-security-list-audit.php:162, dist/admin/wp-security-list-audit.php:184, dist/classes/commands/wp-security-log-commands.php:112 +msgid "Stack trace" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:162 +msgid "Show trace" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:177, dist/admin/wp-security-list-debug.php:54, dist/classes/commands/wp-security-log-commands.php:105 +msgid "Level" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:178, dist/admin/wp-security-list-debug.php:55, dist/classes/commands/wp-security-log-commands.php:106 +msgid "Network ID" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:179, dist/admin/wp-security-list-debug.php:56, dist/admin/wp-security-list-logged-in-users.php:56, dist/classes/commands/wp-security-log-commands.php:107 +msgid "Site ID" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:180, dist/admin/wp-security-list-locked-ip.php:129, dist/classes/commands/wp-security-log-commands.php:108 +msgid "Username" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:181, dist/classes/wp-security-debug.php:418, dist/classes/commands/wp-security-log-commands.php:109 +msgid "IP" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:182, dist/classes/commands/wp-security-log-commands.php:110 +msgid "Event" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:183, dist/classes/commands/wp-security-log-commands.php:111 +msgid "Details" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:218 +msgid "Delete all" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:219 +msgid "Delete selected" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:220 +msgid "Delete filtered" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:253 +msgid "Please select the level or the event type filter or filter by a search term" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:275 +msgid "All levels" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:287 +msgid "All events" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:296 +msgid "Filter" +msgstr "" + +#: dist/admin/wp-security-list-audit.php:301, dist/templates/wp-admin/brute-force/404-detection.php:104, dist/templates/wp-admin/brute-force/404-detection.php:113 +msgid "Export to CSV" +msgstr "" + +#: dist/admin/wp-security-list-comment-spammer-ip.php:34, dist/admin/wp-security-list-comment-spammer-ip.php:79 +msgid "Block" +msgstr "" + +#: dist/admin/wp-security-list-comment-spammer-ip.php:57 +msgid "Spammer IP" +msgstr "" + +#: dist/admin/wp-security-list-comment-spammer-ip.php:58 +msgid "Number of spam comments from this IP" +msgstr "" + +#: dist/admin/wp-security-list-comment-spammer-ip.php:59 +msgid "Status" +msgstr "" + +#: dist/admin/wp-security-list-comment-spammer-ip.php:132 +msgid "The selected IP addresses are now permanently blocked." +msgstr "" + +#: dist/admin/wp-security-list-debug.php:57 +msgid "Message" +msgstr "" + +#: dist/admin/wp-security-list-debug.php:58 +msgid "Type" +msgstr "" + +#: dist/admin/wp-security-list-locked-ip.php:64 +msgid "Are you sure you want to unlock this address range?" +msgstr "" + +#: dist/admin/wp-security-list-locked-ip.php:99, dist/admin/wp-security-list-locked-ip.php:104 +msgid "There is no IP lookup result available." +msgstr "" + +#: dist/admin/wp-security-list-locked-ip.php:107, dist/classes/wp-security-user-login.php:414, dist/classes/wp-security-user-login.php:415 +msgid "Not Found" +msgstr "" + +#: dist/admin/wp-security-list-locked-ip.php:113, dist/admin/wp-security-list-locked-ip.php:133 +msgid "IP lookup result" +msgstr "" + +#: dist/admin/wp-security-list-locked-ip.php:113 +msgid "Show result" +msgstr "" + +#: dist/admin/wp-security-list-locked-ip.php:127 +msgid "Locked IP/range" +msgstr "" + +#: dist/admin/wp-security-list-locked-ip.php:128, dist/admin/wp-security-list-logged-in-users.php:53, dist/admin/wp-security-list-registered-users.php:80 +msgid "User ID" +msgstr "" + +#: dist/admin/wp-security-list-locked-ip.php:130, dist/admin/wp-security-list-permanent-blocked-ip.php:73 +msgid "Reason" +msgstr "" + +#: dist/admin/wp-security-list-locked-ip.php:131 +msgid "Date locked" +msgstr "" + +#: dist/admin/wp-security-list-locked-ip.php:132 +msgid "Release date" +msgstr "" + +#: dist/admin/wp-security-list-locked-ip.php:216 +msgid "The selected IP entries were unlocked successfully." +msgstr "" + +#: dist/admin/wp-security-list-logged-in-users.php:35 +msgid "Are you sure you want to force this user to be logged out of this session?" +msgstr "" + +#: dist/admin/wp-security-list-logged-in-users.php:35, dist/admin/wp-security-user-security-menu.php:38, dist/classes/grade-system/wp-security-feature-item-manager.php:89 +msgid "Force logout" +msgstr "" + +#: dist/admin/wp-security-list-logged-in-users.php:54, dist/admin/wp-security-list-registered-users.php:81 +msgid "Login name" +msgstr "" + +#: dist/admin/wp-security-list-logged-in-users.php:97 +msgid "Logout all" +msgstr "" + +#: dist/admin/wp-security-list-logged-in-users.php:98 +msgid "Logout selected" +msgstr "" + +#: dist/admin/wp-security-list-logged-in-users.php:166 +msgid "Some users were not logged out due to the ID being invalid, or them being a super admin or a member of a different subsite on a multisite" +msgstr "" + +#: dist/admin/wp-security-list-permanent-blocked-ip.php:45 +msgid "Are you sure you want to unblock this IP address?" +msgstr "" + +#: dist/admin/wp-security-list-permanent-blocked-ip.php:72 +msgid "Blocked IP" +msgstr "" + +#: dist/admin/wp-security-list-permanent-blocked-ip.php:74 +msgid "Date and Time" +msgstr "" + +#: dist/admin/wp-security-list-permanent-blocked-ip.php:132, dist/classes/commands/wp-security-ip-commands.php:75 +msgid "Failed to unblock and delete the selected record(s)." +msgstr "" + +#: dist/admin/wp-security-list-permanent-blocked-ip.php:128, dist/classes/commands/wp-security-ip-commands.php:77 +msgid "Successfully unblocked and deleted the selected record(s)." +msgstr "" + +#: dist/admin/wp-security-list-registered-users.php:35 +msgid "View" +msgstr "" + +#: dist/admin/wp-security-list-registered-users.php:36 +msgid "Are you sure you want to approve this account?" +msgstr "" + +#: dist/admin/wp-security-list-registered-users.php:36, dist/admin/wp-security-list-registered-users.php:103 +msgid "Approve" +msgstr "" + +#: dist/admin/wp-security-list-registered-users.php:37 +msgid "Are you sure you want to delete this account?" +msgstr "" + +#: dist/admin/wp-security-list-registered-users.php:38, dist/admin/wp-security-list-registered-users.php:105 +msgid "Block IP" +msgstr "" + +#: dist/admin/wp-security-list-registered-users.php:57 +msgid "blocked" +msgstr "" + +#: dist/admin/wp-security-list-registered-users.php:82 +msgid "Email" +msgstr "" + +#: dist/admin/wp-security-list-registered-users.php:83 +msgid "Register date" +msgstr "" + +#: dist/admin/wp-security-list-registered-users.php:84 +msgid "Account status" +msgstr "" + +#: dist/admin/wp-security-list-registered-users.php:178 +msgid "The selected accounts were approved successfully." +msgstr "" + +#: dist/admin/wp-security-list-registered-users.php:183 +msgid "The following accounts failed to update successfully:" +msgstr "" + +#: dist/admin/wp-security-list-registered-users.php:203 +msgid "Your account is now active" +msgstr "" + +#. translators: %s: Username +#: dist/admin/wp-security-list-registered-users.php:205 +msgid "Your account with username: %s is now active" +msgstr "" + +#: dist/admin/wp-security-list-registered-users.php:234 +msgid "The selected accounts were deleted successfully." +msgstr "" + +#: dist/admin/wp-security-list-registered-users.php:253 +msgid "Only invalid IP addresses were provided: you can not block your own IP address" +msgstr "" + +#: dist/admin/wp-security-list-registered-users.php:264, dist/classes/commands/wp-brute-force-commands.php:478, dist/classes/commands/wp-security-comment-commands.php:154, dist/classes/commands/wp-security-user-security-commands.php:593 +msgid "You cannot block your own IP address:" +msgstr "" + +#: dist/admin/wp-security-list-registered-users.php:272 +msgid "The selected IP addresses were successfully added to the permanent block list." +msgstr "" + +#: dist/admin/wp-security-list-registered-users.php:273, dist/classes/commands/wp-security-user-security-commands.php:601 +msgid "View Blocked IPs" +msgstr "" + +#: dist/admin/wp-security-settings-menu.php:34 +msgid "General settings" +msgstr "" + +#: dist/admin/wp-security-settings-menu.php:38, dist/admin/wp-security-settings-menu.php:43, dist/classes/wp-security-settings-tasks.php:60, dist/classes/wp-security-settings-tasks.php:65, dist/classes/wp-security-settings-tasks.php:90 +msgid "file" +msgstr "" + +#: dist/admin/wp-security-settings-menu.php:48 +msgid "Delete plugin settings" +msgstr "" + +#: dist/admin/wp-security-settings-menu.php:52 +msgid "WP version info" +msgstr "" + +#: dist/admin/wp-security-settings-menu.php:56 +msgid "Import/Export" +msgstr "" + +#: dist/admin/wp-security-spam-menu.php:19, dist/templates/wp-admin/dashboard/may-also-like.php:174 +msgid "Spam prevention" +msgstr "" + +#: dist/admin/wp-security-spam-menu.php:30 +msgid "Comment spam" +msgstr "" + +#: dist/admin/wp-security-spam-menu.php:34 +msgid "Comment spam IP monitoring" +msgstr "" + +#: dist/admin/wp-security-spam-menu.php:82, dist/classes/commands/wp-security-comment-commands.php:212 +msgid "Spammer IPs added to permanent block list today:" +msgstr "" + +#: dist/admin/wp-security-spam-menu.php:82, dist/classes/commands/wp-security-comment-commands.php:213 +msgid "All time total:" +msgstr "" + +#: dist/admin/wp-security-spam-menu.php:82, dist/classes/commands/wp-security-comment-commands.php:214 +msgid "View blocked IPs" +msgstr "" + +#: dist/admin/wp-security-spam-menu.php:70, dist/classes/commands/wp-security-comment-commands.php:207 +msgid "You currently have no IP addresses permanently blocked due to spam." +msgstr "" + +#: dist/admin/wp-security-tools-menu.php:32, dist/templates/wp-admin/tools/password-tool.php:2, dist/templates/wp-admin/user-security/http-authentication.php:81 +msgid "Password tool" +msgstr "" + +#: dist/admin/wp-security-tools-menu.php:36 +msgid "WHOIS lookup" +msgstr "" + +#: dist/admin/wp-security-tools-menu.php:40, dist/templates/wp-admin/tools/custom-htaccess.php:28 +msgid "Custom .htaccess rules" +msgstr "" + +#: dist/admin/wp-security-tools-menu.php:45 +msgid "Visitor lockout" +msgstr "" + +#: dist/admin/wp-security-user-security-menu.php:30 +msgid "User accounts" +msgstr "" + +#: dist/admin/wp-security-user-security-menu.php:46 +msgid "Manual approval" +msgstr "" + +#: dist/admin/wp-security-user-security-menu.php:50 +msgid "Salt" +msgstr "" + +#: dist/admin/wp-security-user-security-menu.php:55 +msgid "HTTP authentication" +msgstr "" + +#: dist/admin/wp-security-user-security-menu.php:59, dist/classes/grade-system/wp-security-feature-item-manager.php:97, dist/templates/wp-admin/tools/password-tool.php:23, dist/templates/wp-admin/user-security/hibp.php:4, dist/templates/wp-admin/user-security/http-authentication.php:82 +msgid "HIBP" +msgstr "" + +#: dist/admin/wp-security-user-security-menu.php:64, dist/templates/wp-admin/user-security/additional.php:9 +msgid "Additional settings" +msgstr "" + +#: dist/admin/wp-security-user-security-menu.php:109 +msgid "Account login name" +msgstr "" + +#: dist/admin/wp-security-user-security-menu.php:118 +msgid "Edit user" +msgstr "" + +#: dist/admin/wp-security-user-security-menu.php:222 +msgid "Failed to save 'Enable for WordPress dashboard'." +msgstr "" + +#: dist/admin/wp-security-user-security-menu.php:222, dist/admin/wp-security-user-security-menu.php:233, dist/templates/wp-admin/user-security/http-authentication.php:9 +msgid "Your site is currently not using https." +msgstr "" + +#: dist/admin/wp-security-user-security-menu.php:233 +msgid "Failed to save 'Enable for frontend'." +msgstr "" + +#: dist/admin/wp-security-user-security-menu.php:241 +msgid "Failed to save 'Username'." +msgstr "" + +#: dist/admin/wp-security-user-security-menu.php:241 +msgid "Please enter a value for the HTTP authentication username." +msgstr "" + +#: dist/admin/wp-security-user-security-menu.php:248 +msgid "Failed to save 'Password'." +msgstr "" + +#: dist/admin/wp-security-user-security-menu.php:248 +msgid "Please enter a value for the HTTP authentication password." +msgstr "" + +#: dist/classes/wp-security-ajax.php:149 +msgid "Options can only be saved by network admin" +msgstr "" + +#. translators: %s: Subaction +#: dist/classes/wp-security-ajax.php:182 +msgid "The command \"%s\" was not found" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:102 +msgid "Core updated" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:103 +msgid "Plugin installed" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:104 +msgid "Plugin activated" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:105 +msgid "Plugin updated" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:106 +msgid "Plugin deactivated" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:107 +msgid "Plugin deleted" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:108 +msgid "Theme installed" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:109 +msgid "Theme activated" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:110 +msgid "Theme updated" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:111 +msgid "Theme deleted" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:112 +msgid "Translation updated" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:113 +msgid "Entity changed" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:114 +msgid "Successful login" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:115 +msgid "Successful logout" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:116 +msgid "Failed login" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:117 +msgid "User registration" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:118 +msgid "User deleted" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:119 +msgid "User removed from blog" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:120 +msgid "Table migration" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:121 +msgid "Rule triggered" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:122 +msgid "Rule not triggered" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:123 +msgid "Rule active" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:124 +msgid "Rule not active" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:125 +msgid "Password reset" +msgstr "" + +#: dist/classes/wp-security-audit-events.php:635 +msgid "(force logout)" +msgstr "" + +#. translators: %s: User name +#: dist/classes/wp-security-audit-text-handler.php:18 +msgid "Successful login with username: %s" +msgstr "" + +#: dist/classes/wp-security-audit-text-handler.php:29 +msgid "Successful logout with username:" +msgstr "" + +#. translators: 1: Old version, 2: New version +#: dist/classes/wp-security-audit-text-handler.php:40 +msgid "WordPress updated from version %1$s to %2$s" +msgstr "" + +#: dist/classes/wp-security-audit-text-handler.php:50 +msgid "Plugin" +msgstr "" + +#: dist/classes/wp-security-audit-text-handler.php:63, dist/classes/wp-security-audit-text-handler.php:61, dist/templates/wp-admin/brute-force/captcha-provider.php:57 +msgid "Theme" +msgstr "" + +#: dist/classes/wp-security-audit-text-handler.php:78 +msgid "An unknown entity has changed, please check the stacktrace for more details" +msgstr "" + +#: dist/classes/wp-security-audit-text-handler.php:76 +msgid "Entity: \"%s\" has changed, please check the stacktrace for more details" +msgstr "" + +#. translators: 1: Slug, 2: Language name, 3: Version +#: dist/classes/wp-security-audit-text-handler.php:97 +msgid "Theme \"%1$s\" %2$s translations updated to version %3$s" +msgstr "" + +#: dist/classes/wp-security-audit-text-handler.php:94 +msgid "Plugin \"%1$s\" %2$s translations updated to version %3$s" +msgstr "" + +#: dist/classes/wp-security-audit-text-handler.php:91 +msgid "Core %1$s translations updated to version %2$s" +msgstr "" + +#. translators: %s: User name +#: dist/classes/wp-security-audit-text-handler.php:115 +msgid "Failed login attempt with a unknown username: %s" +msgstr "" + +#: dist/classes/wp-security-audit-text-handler.php:112 +msgid "Failed login attempt with a known username: %s" +msgstr "" + +#: dist/classes/wp-security-audit-text-handler.php:109 +msgid "Event imported from the failed logins table" +msgstr "" + +#. translators: %s: Registered User name +#: dist/classes/wp-security-audit-text-handler.php:134 +msgid "User %s registered" +msgstr "" + +#: dist/classes/wp-security-audit-text-handler.php:131 +msgid "User %s registered and set to pending" +msgstr "" + +#: dist/classes/wp-security-audit-text-handler.php:128 +msgid "Admin %1$s registered new user: %2$s" +msgstr "" + +#. translators: 1: From table, 2: To table +#: dist/classes/wp-security-audit-text-handler.php:150 +msgid "Failed to migrate the `%1$s` table data to the `%2$s` table" +msgstr "" + +#: dist/classes/wp-security-audit-text-handler.php:147 +msgid "Successfully migrated the `%1$s` table data to the `%2$s` table" +msgstr "" + +#. translators: 1: Rule name, 2: Rule family +#: dist/classes/wp-security-audit-text-handler.php:165 +msgid "\"%1$s [%2$s]\" rule has been triggered." +msgstr "" + +#. translators: 1: Rule name, 2: Rule family +#: dist/classes/wp-security-audit-text-handler.php:169 +msgid "\"%1$s [%2$s]\" rule was not triggered." +msgstr "" + +#. translators: 1: Rule name, 2: Rule family +#: dist/classes/wp-security-audit-text-handler.php:173 +msgid "\"%1$s [%2$s]\" rule is active." +msgstr "" + +#. translators: 1: Rule name, 2: Rule family +#: dist/classes/wp-security-audit-text-handler.php:177 +msgid "\"%1$s [%2$s]\" rule is not active." +msgstr "" + +#: dist/classes/wp-security-audit-text-handler.php:190 +msgid "Configure this rule" +msgstr "" + +#. translators: %s: User login +#: dist/classes/wp-security-audit-text-handler.php:204 +msgid "Password for user account: `%s` successfully changed" +msgstr "" + +#. translators: 1: User login, 2: User ID, 3: Reassign +#: dist/classes/wp-security-audit-text-handler.php:219 +msgid "User account: `%1$s` with ID: `%2$s` has been deleted and all content has been reassigned to user with ID: `%3$s`" +msgstr "" + +#: dist/classes/wp-security-audit-text-handler.php:216 +msgid "User account: %1$s with ID: `%2$s` has been deleted" +msgstr "" + +#. translators: 1: User login, 2: User ID, 3: Blog ID, 4: Reassign +#: dist/classes/wp-security-audit-text-handler.php:235 +msgid "User account: `%1$s` with ID: `%2$s` has been removed from the blog with ID: `%3$s` and all content has been reassigned to user with ID: `%4$s`" +msgstr "" + +#: dist/classes/wp-security-audit-text-handler.php:232 +msgid "User account: %1$s with ID: `%2$s` has been removed from the blog with ID: `%3$s`" +msgstr "" + +#: dist/classes/wp-security-captcha.php:100 +msgid "Auto" +msgstr "" + +#: dist/classes/wp-security-captcha.php:101 +msgid "Light" +msgstr "" + +#: dist/classes/wp-security-captcha.php:102 +msgid "Dark" +msgstr "" + +#: dist/classes/wp-security-captcha.php:183, dist/classes/wp-security-captcha.php:224, dist/classes/wp-security-captcha.php:367 +msgid "Please enter an answer in digits:" +msgstr "" + +#: dist/classes/wp-security-captcha.php:213 +msgid "This content is password protected." +msgstr "" + +#: dist/classes/wp-security-captcha.php:213 +msgid "To view it please enter your password below:" +msgstr "" + +#: dist/classes/wp-security-captcha.php:214, dist/templates/wp-admin/user-security/http-authentication.php:74 +msgid "Password:" +msgstr "" + +#: dist/classes/wp-security-captcha.php:233 +msgid "Enter" +msgstr "" + +#: dist/classes/wp-security-captcha.php:248 +msgid "Captcha verification failed." +msgstr "" + +#: dist/classes/wp-security-captcha.php:248 +msgid "Please try again." +msgstr "" + +#: dist/classes/wp-security-captcha.php:464 +msgid "one" +msgstr "" + +#: dist/classes/wp-security-captcha.php:465 +msgid "two" +msgstr "" + +#: dist/classes/wp-security-captcha.php:466 +msgid "three" +msgstr "" + +#: dist/classes/wp-security-captcha.php:467 +msgid "four" +msgstr "" + +#: dist/classes/wp-security-captcha.php:468 +msgid "five" +msgstr "" + +#: dist/classes/wp-security-captcha.php:469 +msgid "six" +msgstr "" + +#: dist/classes/wp-security-captcha.php:470 +msgid "seven" +msgstr "" + +#: dist/classes/wp-security-captcha.php:471 +msgid "eight" +msgstr "" + +#: dist/classes/wp-security-captcha.php:472 +msgid "nine" +msgstr "" + +#: dist/classes/wp-security-captcha.php:473 +msgid "ten" +msgstr "" + +#: dist/classes/wp-security-captcha.php:474 +msgid "eleven" +msgstr "" + +#: dist/classes/wp-security-captcha.php:475 +msgid "twelve" +msgstr "" + +#: dist/classes/wp-security-captcha.php:476 +msgid "thirteen" +msgstr "" + +#: dist/classes/wp-security-captcha.php:477 +msgid "fourteen" +msgstr "" + +#: dist/classes/wp-security-captcha.php:478 +msgid "fifteen" +msgstr "" + +#: dist/classes/wp-security-captcha.php:479 +msgid "sixteen" +msgstr "" + +#: dist/classes/wp-security-captcha.php:480 +msgid "seventeen" +msgstr "" + +#: dist/classes/wp-security-captcha.php:481 +msgid "eighteen" +msgstr "" + +#: dist/classes/wp-security-captcha.php:482 +msgid "nineteen" +msgstr "" + +#: dist/classes/wp-security-captcha.php:483 +msgid "twenty" +msgstr "" + +#: dist/classes/wp-security-captcha.php:816, dist/classes/wp-security-general-init-tasks.php:756 +msgid "Your CAPTCHA answer was incorrect - please try again." +msgstr "" + +#: dist/classes/wp-security-captcha.php:900 +msgid "%s captcha" +msgstr "" + +#: dist/classes/wp-security-captcha.php:913 +msgid "Generate a form-tag to use %s CAPTCHA" +msgstr "" + +#: dist/classes/wp-security-captcha.php:919 +msgid "Insert tag" +msgstr "" + +#. translators: %s: Error notification with strong HTML tag. +#: dist/classes/wp-security-captcha.php:936, dist/classes/wp-security-general-init-tasks.php:798, dist/classes/wp-security-user-login.php:151 +msgid "%s: Your answer was incorrect - please try again." +msgstr "" + +#: dist/classes/wp-security-captcha.php:936, dist/classes/wp-security-general-init-tasks.php:790, dist/classes/wp-security-general-init-tasks.php:798, dist/classes/wp-security-user-login.php:110, dist/classes/wp-security-user-login.php:151 +msgid "ERROR" +msgstr "" + +#: dist/classes/wp-security-commands.php:70 +msgid "The feature item manager could not be initialized." +msgstr "" + +#: dist/classes/wp-security-commands.php:88 +msgid "Invalid IP retrieve method." +msgstr "" + +#: dist/classes/wp-security-commands.php:266 +msgid "The settings update was unsuccessful." +msgstr "" + +#: dist/classes/wp-security-commands.php:318 +msgid "Invalid email address." +msgstr "" + +#: dist/classes/wp-security-commands.php:327 +msgid "The diagnostic report has been sent successfully." +msgstr "" + +#: dist/classes/wp-security-commands.php:333 +msgid "There was an error sending the diagnostic report." +msgstr "" + +#: dist/classes/wp-security-commands.php:401 +msgid "AIOS premium" +msgstr "" + +#: dist/classes/wp-security-commands.php:403 +msgid "Advanced malware scanning" +msgstr "" + +#: dist/classes/wp-security-commands.php:404 +msgid "Real-time response time monitoring" +msgstr "" + +#: dist/classes/wp-security-commands.php:405 +msgid "Custom two-factor authentication" +msgstr "" + +#: dist/classes/wp-security-commands.php:406 +msgid "404 error protection & bot blocking" +msgstr "" + +#: dist/classes/wp-security-commands.php:407 +msgid "Country-based traffic blocking" +msgstr "" + +#: dist/classes/wp-security-commands.php:408 +msgid "Country whitelist management" +msgstr "" + +#: dist/classes/wp-security-commands.php:409 +msgid "Guaranteed premium support" +msgstr "" + +#: dist/classes/wp-security-commands.php:412 +msgid "Upgrade Now" +msgstr "" + +#: dist/classes/wp-security-configure-settings.php:519 +msgid "Basic firewall settings disabled" +msgstr "" + +#. translators: %s: Dashboard link. +#: dist/classes/wp-security-configure-settings.php:521 +msgid "Our basic firewall rules have been upgraded and to prevent any unexpected site issues we have disabled the features." +msgstr "" + +#: dist/classes/wp-security-configure-settings.php:521 +msgid "You can enable the features again by logging into your WordPress dashboard." +msgstr "" + +#: dist/classes/wp-security-configure-settings.php:521, dist/classes/wp-security-configure-settings.php:539 +msgid "Go to dashboard: %s" +msgstr "" + +#: dist/classes/wp-security-configure-settings.php:521 +msgid "Once logged in you will see a notification where you can decide on which course of action you wish to take." +msgstr "" + +#: dist/classes/wp-security-configure-settings.php:537 +msgid "Blacklist manager disabled notification" +msgstr "" + +#. translators: %s: Dashboard link +#: dist/classes/wp-security-configure-settings.php:539 +msgid "The blacklist manager feature has been updated and to prevent any unexpected site lockouts we have disabled the feature." +msgstr "" + +#: dist/classes/wp-security-configure-settings.php:539 +msgid "You can enable the feature again by logging into your WordPress dashboard." +msgstr "" + +#: dist/classes/wp-security-configure-settings.php:539 +msgid "Once logged in before turning the blacklist manger on please double check your settings to ensure you have not entered your own details." +msgstr "" + +#: dist/classes/wp-security-cronjob-handler.php:35 +msgid "Every 15 minutes" +msgstr "" + +#: dist/classes/wp-security-debug-logger.php:48 +msgid "Unable to get the reason why" +msgstr "" + +#: dist/classes/wp-security-debug-logger.php:49 +msgid "Unable to clear the logs" +msgstr "" + +#: dist/classes/wp-security-debug.php:416 +msgid "status" +msgstr "" + +#: dist/classes/wp-security-debug.php:416 +msgid "On" +msgstr "" + +#: dist/classes/wp-security-debug.php:511 +msgid "Enter your email address" +msgstr "" + +#: dist/classes/wp-security-debug.php:513 +msgid "Send report" +msgstr "" + +#: dist/classes/wp-security-file-scan.php:78 +msgid "All In One WP Security - File change detected" +msgstr "" + +#: dist/classes/wp-security-file-scan.php:80 +msgid "A file change was detected on your system for site URL" +msgstr "" + +#: dist/classes/wp-security-file-scan.php:80 +msgid ". Scan was generated on" +msgstr "" + +#: dist/classes/wp-security-file-scan.php:81 +msgid "A summary of the scan results is shown below:" +msgstr "" + +#: dist/classes/wp-security-file-scan.php:84 +msgid "Login to your site to view the scan details." +msgstr "" + +#: dist/classes/wp-security-file-scan.php:323 +msgid "The following files were added to your host" +msgstr "" + +#: dist/classes/wp-security-file-scan.php:325, dist/classes/wp-security-file-scan.php:333, dist/classes/wp-security-file-scan.php:342 +msgid "modified on:" +msgstr "" + +#: dist/classes/wp-security-file-scan.php:331 +msgid "The following files were removed from your host" +msgstr "" + +#: dist/classes/wp-security-file-scan.php:340 +msgid "The following files were changed on your host" +msgstr "" + +#: dist/classes/wp-security-general-init-tasks.php:230, dist/classes/wp-security-general-init-tasks.php:557 +msgid "Application passwords have been disabled by All-In-One Security plugin." +msgstr "" + +#: dist/classes/wp-security-general-init-tasks.php:528, dist/classes/wp-security-general-init-tasks.php:616, dist/classes/wp-security-general-init-tasks.php:772, dist/classes/wp-security-user-registration.php:86 +msgid "ERROR: Your answer was incorrect - please try again." +msgstr "" + +#: dist/classes/wp-security-general-init-tasks.php:539 +msgid "Enter something special:" +msgstr "" + +#: dist/classes/wp-security-general-init-tasks.php:552 +msgid "Application passwords" +msgstr "" + +#: dist/classes/wp-security-general-init-tasks.php:556, dist/includes/simba-tfa/simba-tfa.php:444, dist/includes/simba-tfa/simba-tfa.php:1317 +msgid "Disabled" +msgstr "" + +#: dist/classes/wp-security-general-init-tasks.php:562 +msgid "Site admin can only change this setting." +msgstr "" + +#: dist/classes/wp-security-general-init-tasks.php:560 +msgid "Change setting" +msgstr "" + +#: dist/classes/wp-security-general-init-tasks.php:591 +msgid "Error: You entered an incorrect CAPTCHA answer, please go back and try again." +msgstr "" + +#: dist/classes/wp-security-general-init-tasks.php:765 +msgid "ERROR: Your IP address is currently locked please contact the administrator!" +msgstr "" + +#. translators: %s: Error notification with strong HTML tag. +#: dist/classes/wp-security-general-init-tasks.php:790 +msgid "%s: Your IP address is currently locked." +msgstr "" + +#: dist/classes/wp-security-general-init-tasks.php:790, dist/classes/wp-security-user-login.php:110 +msgid "Please contact the administrator." +msgstr "" + +#: dist/classes/wp-security-general-init-tasks.php:829 +msgid "Please enter the correct reCAPTCHA keys %s to use the Google reCAPTCHA feature." +msgstr "" + +#: dist/classes/wp-security-general-init-tasks.php:829, dist/templates/wp-admin/general/moved.php:21, dist/templates/wp-admin/scanner/malware-scan.php:7 +msgid "here" +msgstr "" + +#: dist/classes/wp-security-general-init-tasks.php:849 +msgid "Your registration is pending approval." +msgstr "" + +#: dist/classes/wp-security-general-init-tasks.php:886 +msgid "You are not authorized to perform this action." +msgstr "" + +#: dist/classes/wp-security-general-init-tasks.php:921 +msgid "Accessing user details is forbidden." +msgstr "" + +#: dist/classes/wp-security-general-init-tasks.php:916 +msgid "Listing users is forbidden." +msgstr "" + +#: dist/classes/wp-security-general-init-tasks.php:1017, dist/classes/wp-security-process-renamed-login-page.php:149 +msgid "You do not have permission to access this page." +msgstr "" + +#: dist/classes/wp-security-general-init-tasks.php:1018, dist/classes/wp-security-process-renamed-login-page.php:149 +msgid "Please log in and try again." +msgstr "" + +#: dist/classes/wp-security-notices.php:30 +msgid "An error occurred while rendering this notice, please enable and check your debug log." +msgstr "" + +#. translators: 1. HTML text. 2. HTML text, 3. HTML text. +#: dist/classes/wp-security-notices.php:45 +msgid "Get %1$s with %2$s. %3$s, downtime, and response time issues." +msgstr "" + +#: dist/classes/wp-security-notices.php:45, dist/classes/wp-security-notices.php:48 +msgid "added protection" +msgstr "" + +#: dist/classes/wp-security-notices.php:45, dist/classes/wp-security-notices.php:48, dist/templates/wp-admin/dashboard/may-also-like.php:24 +msgid "Premium" +msgstr "" + +#: dist/classes/wp-security-notices.php:45, dist/classes/wp-security-notices.php:48 +msgid "Scan your site for malware" +msgstr "" + +#. translators: %s: HTML text. +#: dist/classes/wp-security-notices.php:48 +msgid "Block traffic by country of origin, get advanced two-factor authentication, %s, and more." +msgstr "" + +#: dist/classes/wp-security-notices.php:52 +msgid "The All in One Security plugin has deactivated some of the firewall settings that you had activated." +msgstr "" + +#: dist/classes/wp-security-notices.php:55 +msgid "We have upgraded the following settings so that they are now part of the PHP firewall instead of .htaccess directives:" +msgstr "" + +#: dist/classes/wp-security-notices.php:85 +msgid "None of the settings that have been upgraded were active." +msgstr "" + +#: dist/classes/wp-security-notices.php:68 +msgid "Completely block xmlrpc.php" +msgstr "" + +#: dist/classes/wp-security-notices.php:71, dist/templates/wp-admin/firewall/partials/proxy-comment.php:13 +msgid "Forbid proxy comment posting" +msgstr "" + +#: dist/classes/wp-security-notices.php:74, dist/templates/wp-admin/firewall/partials/bad-query-strings.php:13 +msgid "Deny bad query strings" +msgstr "" + +#: dist/classes/wp-security-notices.php:77 +msgid "Advanced character filter" +msgstr "" + +#: dist/classes/wp-security-notices.php:89 +msgid "What would you like to do?" +msgstr "" + +#: dist/classes/wp-security-notices.php:92 +msgid "The All in One Security plugin has disabled the login whitelist setting that you have enabled in the past." +msgstr "" + +#: dist/classes/wp-security-notices.php:98 +msgid "Your website is running on a non-Apache webserver, so the login whitelisting was not functional until the recent update of AIOS (because it relied upon Apache-specific features)." +msgstr "" + +#: dist/classes/wp-security-notices.php:96 +msgid "Your website is running on an Apache webserver, the login whitelisting might not be functional until the recent update of AIOS (because it relied upon Apache-specific module features)." +msgstr "" + +#: dist/classes/wp-security-notices.php:100 +msgid "It began working with AIOS version 5.0.8." +msgstr "" + +#: dist/classes/wp-security-notices.php:100 +msgid "We have disabled it so that your login page will not be blocked unexpectedly." +msgstr "" + +#: dist/classes/wp-security-notices.php:106 +msgid "Whitelisted login IP address(es):" +msgstr "" + +#: dist/classes/wp-security-notices.php:109 +msgid "Would you like to re-enable login whitelisting?" +msgstr "" + +#: dist/classes/wp-security-notices.php:115 +msgid "Removed database backup feature from the All-In-One Security plugin" +msgstr "" + +#: dist/classes/wp-security-notices.php:117 +msgid "Beginning with version 5.0.0, AIOS has replaced the AIOS backup method with the superior UpdraftPlus method." +msgstr "" + +#: dist/classes/wp-security-notices.php:118 +msgid "It remains free and is fully supported by the UpdraftPlus team." +msgstr "" + +#: dist/classes/wp-security-notices.php:121 +msgid "You are seeing this notice because you have previously set up automated database backups in AIOS." +msgstr "" + +#: dist/classes/wp-security-notices.php:122 +msgid "Would you like to set up scheduled backups with UpdraftPlus?" +msgstr "" + +#: dist/classes/wp-security-notices.php:128 +msgid "Setup UpdraftPlus backup plugin" +msgstr "" + +#: dist/classes/wp-security-notices.php:134 +msgid "Important: set up your IP address detection settings" +msgstr "" + +#: dist/classes/wp-security-notices.php:136 +msgid "The All in One Security plugin couldn't be certain about the correct method to detect the IP address for your site visitors with your currently-configured IP address detection settings." +msgstr "" + +#: dist/classes/wp-security-notices.php:137 +msgid "It is important for your security to set the IP address detection settings properly." +msgstr "" + +#: dist/classes/wp-security-notices.php:140 +msgid "Please go to the settings and set them now." +msgstr "" + +#: dist/classes/wp-security-notices.php:146 +msgid "Setup IP address detection settings" +msgstr "" + +#: dist/classes/wp-security-notices.php:154 +msgid "Failed to load the firewall resources." +msgstr "" + +#: dist/classes/wp-security-notices.php:155 +msgid "The firewall won't operate correctly." +msgstr "" + +#: dist/classes/wp-security-notices.php:162 +msgid "AIOS PHP 5.6 support will end soon" +msgstr "" + +#: dist/classes/wp-security-notices.php:169 +msgid "Important: Disabled firewall settings" +msgstr "" + +#: dist/classes/wp-security-notices.php:175 +msgid "Reactivate" +msgstr "" + +#: dist/classes/wp-security-notices.php:176 +msgid "Configure manually" +msgstr "" + +#: dist/classes/wp-security-notices.php:179 +msgid "Keep deactivated" +msgstr "" + +#: dist/classes/wp-security-notices.php:183 +msgid "Important: Blacklist manager disabled" +msgstr "" + +#: dist/classes/wp-security-notices.php:185 +msgid "The blacklist manager feature has been disabled to prevent any unexpected site lockouts." +msgstr "" + +#: dist/classes/wp-security-notices.php:188 +msgid "This feature will block any IP address or range listed in its settings, please double check your own details are not included before turning it back on." +msgstr "" + +#: dist/classes/wp-security-notices.php:195, dist/classes/wp-security-notices.php:209 +msgid "Edit the settings" +msgstr "" + +#: dist/classes/wp-security-notices.php:202 +msgid "Important: Disabled login whitelist setting" +msgstr "" + +#: dist/classes/wp-security-notices.php:208 +msgid "Turn it back on" +msgstr "" + +#: dist/classes/wp-security-notices.php:212 +msgid "Keep it off" +msgstr "" + +#: dist/classes/wp-security-notices.php:216 +msgid "We noticed AIOS has kept your site safe for a while." +msgstr "" + +#: dist/classes/wp-security-notices.php:216 +msgid "If you like us, please consider leaving a positive review." +msgstr "" + +#: dist/classes/wp-security-notices.php:216 +msgid "If you have any issues or questions, please contact %s." +msgstr "" + +#: dist/classes/wp-security-notices.php:216 +msgid "support" +msgstr "" + +#: dist/classes/wp-security-notices.php:216 +msgid "Thank you so much!" +msgstr "" + +#: dist/classes/wp-security-notices.php:216 +msgid "All-In-One Security (AIOS)" +msgstr "" + +#: dist/classes/wp-security-notices.php:226 +msgid "Enhance your security even more by backing up your site" +msgstr "" + +#: dist/classes/wp-security-notices.php:227 +msgid "UpdraftPlus is the world's most trusted backup plugin." +msgstr "" + +#: dist/classes/wp-security-notices.php:227 +msgid "From the owners of All-In-One Security (AIOS)." +msgstr "" + +#: dist/classes/wp-security-notices.php:237 +msgid "Speed up your site" +msgstr "" + +#: dist/classes/wp-security-notices.php:238 +msgid "After you've secured your site, we recommend you install our WP-Optimize plugin to streamline it for better website performance." +msgstr "" + +#: dist/classes/wp-security-notices.php:250 +msgid "20% off - Black Friday Sale" +msgstr "" + +#: dist/classes/wp-security-notices.php:252 +msgid "at checkout." +msgstr "" + +#: dist/classes/wp-security-notices.php:252 +msgid "Hurry, offer ends 2 December." +msgstr "" + +#: dist/classes/wp-security-notices.php:254 +msgid "Save 20%% with code %s" +msgstr "" + +#: dist/classes/wp-security-notices.php:318 +msgid "AIOS will end support for PHP 5.6 on the 1st September 2025." +msgstr "" + +#: dist/classes/wp-security-notices.php:320 +msgid "PHP 5.6 is outdated and no longer receives security updates." +msgstr "" + +#: dist/classes/wp-security-notices.php:320 +msgid "To keep things secure and compatible with modern WordPress standards, AIOS will move to a minimum requirement of PHP 7.0." +msgstr "" + +#: dist/classes/wp-security-notices.php:322 +msgid "After the 1st September 2025, AIOS may not operate correctly on PHP versions below 7.0." +msgstr "" + +#: dist/classes/wp-security-notices.php:324 +msgid "If you require help upgrading your PHP version, please contact your hosting provider." +msgstr "" + +#: dist/classes/wp-security-process-renamed-login-page.php:163 +msgid "Invalid key" +msgstr "" + +#: dist/classes/wp-security-process-renamed-login-page.php:172 +msgid "User action confirmed." +msgstr "" + +#. translators: %s: .htaccess path +#. translators: %s: wp-config.php path +#. translators: %s: .htaccess path, %s file tab name. +#: dist/classes/wp-security-settings-tasks.php:32, dist/classes/wp-security-settings-tasks.php:60, dist/classes/wp-security-settings-tasks.php:65, dist/classes/wp-security-settings-tasks.php:90, dist/classes/commands/wp-security-settings-commands.php:307 +msgid "Could not write to the %s file." +msgstr "" + +#: dist/classes/wp-security-settings-tasks.php:32, dist/classes/commands/wp-security-settings-commands.php:307 +msgid "Please check the file permissions." +msgstr "" + +#: dist/classes/wp-security-settings-tasks.php:29 +msgid "Settings were successfully saved." +msgstr "" + +#: dist/classes/wp-security-settings-tasks.php:60, dist/classes/wp-security-settings-tasks.php:65, dist/classes/wp-security-settings-tasks.php:90 +msgid "Please restore it manually using the restore functionality in the \"%s\" tab." +msgstr "" + +#: dist/classes/wp-security-settings-tasks.php:57 +msgid "All the security features have been disabled successfully." +msgstr "" + +#: dist/classes/wp-security-settings-tasks.php:87 +msgid "All firewall rules have been disabled successfully." +msgstr "" + +#: dist/classes/wp-security-settings-tasks.php:122 +msgid "All settings have been successfully reset." +msgstr "" + +#: dist/classes/wp-security-settings-tasks.php:120 +msgid "Deletion of .htaccess directives failed." +msgstr "" + +#: dist/classes/wp-security-settings-tasks.php:118 +msgid "Reset of aio_wp_security_configs option failed." +msgstr "" + +#: dist/classes/wp-security-settings-tasks.php:116 +msgid "Deletion of aio_wp_security_configs option and .htaccess directives failed." +msgstr "" + +#: dist/classes/wp-security-two-factor-login.php:66 +msgid "Two factor authentication - Admin settings" +msgstr "" + +#: dist/classes/wp-security-two-factor-login.php:123, dist/classes/wp-security-two-factor-login.php:123 +msgid "Two Factor Auth" +msgstr "" + +#: dist/classes/wp-security-two-factor-login.php:146 +msgid "Two factor authentication" +msgstr "" + +#: dist/classes/wp-security-two-factor-login.php:195 +msgid "PHP OpenSSL or mcrypt module required" +msgstr "" + +#: dist/classes/wp-security-two-factor-login.php:195 +msgid "The All-In-One Security plugin's Two Factor Authentication module requires either the PHP openssl (preferred) or mcrypt module to be installed." +msgstr "" + +#: dist/classes/wp-security-two-factor-login.php:195 +msgid "Please ask your web hosting company to install one of them." +msgstr "" + +#: dist/classes/wp-security-user-login.php:80 +msgid "You have disabled login lockout by defining the AIOS_DISABLE_LOGIN_LOCKOUT constant value as true, and the login lockout setting has enabled it." +msgstr "" + +#. translators: 1: Locked IP Addresses admin page link +#: dist/classes/wp-security-user-login.php:82 +msgid "Delete your login lockout IP from %s and define the AIOS_DISABLE_LOGIN_LOCKOUT constant value as false." +msgstr "" + +#. translators: %s: Error notification with strong HTML tag. +#: dist/classes/wp-security-user-login.php:110 +msgid "%s: Access from your IP address has been blocked for security reasons." +msgstr "" + +#: dist/classes/wp-security-user-login.php:119 +msgid "Service temporarily unavailable" +msgstr "" + +#. translators: %s: Notification with strong HTML tag. +#: dist/classes/wp-security-user-login.php:178 +msgid "%s: Your account is currently not active." +msgstr "" + +#: dist/classes/wp-security-user-login.php:178 +msgid "ACCOUNT PENDING" +msgstr "" + +#: dist/classes/wp-security-user-login.php:178 +msgid "An administrator needs to activate your account before you can login." +msgstr "" + +#: dist/classes/wp-security-user-login.php:256 +msgid "ERROR: Invalid login credentials." +msgstr "" + +#: dist/classes/wp-security-user-login.php:398 +msgid "Site Lockout Notification" +msgstr "" + +#: dist/classes/wp-security-user-login.php:399 +msgid "User login lockout events had occurred due to too many failed login attempts or invalid username:" +msgstr "" + +#. translators: %s: User name. +#: dist/classes/wp-security-user-login.php:403 +msgid "Username: %s" +msgstr "" + +#. translators: %s: IP Address. +#: dist/classes/wp-security-user-login.php:406 +msgid "IP address: %s" +msgstr "" + +#. translators: %s: IP Range. +#: dist/classes/wp-security-user-login.php:409 +msgid "IP range: %s" +msgstr "" + +#. translators: %s: Org. +#: dist/classes/wp-security-user-login.php:418 +msgid "Org: %s" +msgstr "" + +#. translators: %s: AS. +#: dist/classes/wp-security-user-login.php:420 +msgid "AS: %s" +msgstr "" + +#: dist/classes/wp-security-user-login.php:427 +msgid "Log into your site WordPress administration panel to see the duration of the lockout or to unlock the user." +msgstr "" + +#: dist/classes/wp-security-user-login.php:544 +msgid "Unlock request notification" +msgstr "" + +#. translators: 1: Email 2: Link +#: dist/classes/wp-security-user-login.php:546 +msgid "You have requested for the account with email address %s to be unlocked." +msgstr "" + +#: dist/classes/wp-security-user-login.php:546 +msgid "Please press the link below to unlock your account:" +msgstr "" + +#: dist/classes/wp-security-user-login.php:546 +msgid "Unlock link: %s" +msgstr "" + +#: dist/classes/wp-security-user-login.php:546 +msgid "After pressing the above link you will be able to login to the WordPress administration panel." +msgstr "" + +#. translators: %s: Minute count +#: dist/classes/wp-security-user-login.php:746 +msgid "Your session has expired because it has been over %d minutes since your last login." +msgstr "" + +#: dist/classes/wp-security-user-login.php:747, dist/classes/wp-security-user-login.php:751 +msgid "Please log back in to continue." +msgstr "" + +#: dist/classes/wp-security-user-login.php:750 +msgid "You were logged out because you just changed the \"admin\" username." +msgstr "" + +#: dist/classes/wp-security-user-login.php:781 +msgid "Request unlock" +msgstr "" + +#: dist/classes/wp-security-user-registration.php:80 +msgid "ERROR: You are not allowed to register because your IP address is currently locked!" +msgstr "" + +#: dist/classes/wp-security-utility-file.php:457, dist/templates/wp-admin/filesystem-security/partials/file-permissions-table.php:5, dist/templates/wp-admin/filesystem-security/partials/file-permissions-table.php:21 +msgid "Name" +msgstr "" + +#: dist/classes/wp-security-utility-file.php:457, dist/admin/general/wp-security-ajax-data-table.php:553, dist/admin/general/wp-security-ajax-data-table.php:1387, dist/admin/general/wp-security-list-table.php:545, dist/admin/general/wp-security-list-table.php:1399 +msgid "Show more details" +msgstr "" + +#: dist/classes/wp-security-utility-file.php:458, dist/templates/wp-admin/filesystem-security/partials/file-permissions-table.php:6, dist/templates/wp-admin/filesystem-security/partials/file-permissions-table.php:22 +msgid "File/Folder" +msgstr "" + +#: dist/classes/wp-security-utility-file.php:459, dist/templates/wp-admin/filesystem-security/partials/file-permissions-table.php:7, dist/templates/wp-admin/filesystem-security/partials/file-permissions-table.php:23 +msgid "Current permissions" +msgstr "" + +#: dist/classes/wp-security-utility-file.php:460, dist/templates/wp-admin/filesystem-security/partials/file-permissions-table.php:8, dist/templates/wp-admin/filesystem-security/partials/file-permissions-table.php:24 +msgid "Recommended permissions" +msgstr "" + +#: dist/classes/wp-security-utility-file.php:466 +msgid "No action required" +msgstr "" + +#: dist/classes/wp-security-utility-file.php:462, dist/templates/wp-admin/filesystem-security/partials/file-permissions-table.php:9, dist/templates/wp-admin/filesystem-security/partials/file-permissions-table.php:25 +msgid "Recommended action" +msgstr "" + +#: dist/classes/wp-security-utility-file.php:463 +msgid "Set recommended permissions" +msgstr "" + +#: dist/classes/wp-security-utility-htaccess.php:169 +msgid "The .htaccess file is not supported by your web server." +msgstr "" + +#: dist/classes/wp-security-utility-htaccess.php:178 +msgid "The .htaccess file either does not exist or is unreadable" +msgstr "" + +#: dist/classes/wp-security-utility-htaccess.php:185 +msgid "The .htaccess file contains invalid content, please manually verify the file contents" +msgstr "" + +#: dist/classes/wp-security-utility-htaccess.php:195 +msgid "A copy of the .htaccess file could not be created" +msgstr "" + +#: dist/classes/wp-security-utility-htaccess.php:202 +msgid "Unable to delete plugin's content from .htaccess file." +msgstr "" + +#: dist/classes/wp-security-utility-htaccess.php:218 +msgid "Write operation on .htaccess failed." +msgstr "" + +#: dist/classes/wp-security-utility-htaccess.php:241 +msgid "The .htaccess file has invalid content, please manually verify that the file is properly formatted" +msgstr "" + +#: dist/classes/wp-security-utility-htaccess.php:248 +msgid "An error has occurred while writing to the .htaccess file." +msgstr "" + +#. translators: %s: IP Address +#: dist/classes/wp-security-utility-ip-address.php:153 +msgid "%s is not a valid IP address format." +msgstr "" + +#: dist/classes/wp-security-utility-ip-address.php:159 +msgid "You cannot ban your own IP address:" +msgstr "" + +#: dist/classes/wp-security-utility-permissions.php:58, dist/includes/simba-tfa/simba-tfa.php:1398 +msgid "Multisite Super Admin" +msgstr "" + +#: dist/classes/wp-security-utility.php:263, dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:101 +msgid "The plugin has detected that you are using a Multi-Site WordPress installation." +msgstr "" + +#: dist/classes/wp-security-utility.php:264 +msgid "Some features on this page can only be configured by the \"superadmin\"." +msgstr "" + +#. translators: %s: File name +#: dist/classes/wp-security-utility.php:1252 +msgid "The %s file has already been deleted." +msgstr "" + +#: dist/classes/wp-security-utility.php:1242 +msgid "Failed to delete the %s file." +msgstr "" + +#: dist/classes/wp-security-utility.php:1242 +msgid "Check the file/directory permissions at: %s" +msgstr "" + +#: dist/classes/wp-security-utility.php:1234 +msgid "Successfully deleted the %s file." +msgstr "" + +#: dist/other-includes/wp-security-stop-users-enumeration.php:8 +msgid "Accessing author info via link is forbidden" +msgstr "" + +#: dist/other-includes/wp-security-unlock-request.php:14 +msgid "Powered by WordPress" +msgstr "" + +#: dist/other-includes/wp-security-unlock-request.php:31 +msgid "ERROR: Unable to process your request!" +msgstr "" + +#: dist/other-includes/wp-security-unlock-request.php:44 +msgid "Please enter a valid email address" +msgstr "" + +#: dist/other-includes/wp-security-unlock-request.php:75 +msgid "An email has been sent to you with the unlock instructions." +msgstr "" + +#: dist/other-includes/wp-security-unlock-request.php:70 +msgid "Error: No locked entry was found in the database with your IP address range." +msgstr "" + +#: dist/other-includes/wp-security-unlock-request.php:56 +msgid "User account not found!" +msgstr "" + +#: dist/other-includes/wp-security-unlock-request.php:92 +msgid "You are here because you have been locked out due to too many incorrect login attempts." +msgstr "" + +#: dist/other-includes/wp-security-unlock-request.php:93 +msgid "Please enter your email address and you will receive an email with instructions on how to unlock yourself." +msgstr "" + +#: dist/other-includes/wp-security-unlock-request.php:103 +msgid "Email Address" +msgstr "" + +#: dist/other-includes/wp-security-unlock-request.php:107 +msgid "Send unlock request" +msgstr "" + +#: dist/admin/general/wp-security-ajax-data-table.php:187, dist/admin/general/wp-security-list-table.php:176 +msgid "List view" +msgstr "" + +#: dist/admin/general/wp-security-ajax-data-table.php:188, dist/admin/general/wp-security-list-table.php:177 +msgid "Excerpt view" +msgstr "" + +#: dist/admin/general/wp-security-ajax-data-table.php:353, dist/admin/general/wp-security-list-table.php:342 +msgid "No items found." +msgstr "" + +#: dist/admin/general/wp-security-ajax-data-table.php:482, dist/admin/general/wp-security-list-table.php:473 +msgid "Select bulk action" +msgstr "" + +#: dist/admin/general/wp-security-ajax-data-table.php:484, dist/admin/general/wp-security-list-table.php:475 +msgid "Bulk actions" +msgstr "" + +#: dist/admin/general/wp-security-ajax-data-table.php:498, dist/admin/general/wp-security-list-table.php:488 +msgid "Are you sure you want to perform this bulk action?" +msgstr "" + +#: dist/admin/general/wp-security-ajax-data-table.php:501, dist/admin/general/wp-security-list-table.php:491 +msgid "Apply" +msgstr "" + +#: dist/admin/general/wp-security-ajax-data-table.php:611, dist/admin/general/wp-security-list-table.php:616 +msgid "Filter by date" +msgstr "" + +#: dist/admin/general/wp-security-ajax-data-table.php:613, dist/admin/general/wp-security-list-table.php:618 +msgid "All dates" +msgstr "" + +#. translators: 1: month name, 2: 4-digit year +#: dist/admin/general/wp-security-ajax-data-table.php:627, dist/admin/general/wp-security-list-table.php:633 +msgid "%1$s %2$d" +msgstr "" + +#. translators: %s: Approved comments +#. translators: %s: Approved comments. +#: dist/admin/general/wp-security-ajax-data-table.php:678, dist/admin/general/wp-security-list-table.php:686 +msgid "%s comment" +msgid_plural "%s comments" +msgstr[0] "" +msgstr[1] "" + +#. translators: %s: Approved comments +#. translators: %s: Approved comments. +#: dist/admin/general/wp-security-ajax-data-table.php:680, dist/admin/general/wp-security-list-table.php:688 +msgid "%s approved comment" +msgid_plural "%s approved comments" +msgstr[0] "" +msgstr[1] "" + +#. translators: %s: Pending comments +#. translators: %s: Pending comments. +#: dist/admin/general/wp-security-ajax-data-table.php:682, dist/admin/general/wp-security-list-table.php:690 +msgid "%s pending comment" +msgid_plural "%s pending comments" +msgstr[0] "" +msgstr[1] "" + +#: dist/admin/general/wp-security-ajax-data-table.php:706, dist/admin/general/wp-security-list-table.php:718 +msgid "No approved comments" +msgstr "" + +#: dist/admin/general/wp-security-ajax-data-table.php:706, dist/admin/general/wp-security-ajax-data-table.php:686, dist/admin/general/wp-security-ajax-data-table.php:729, dist/admin/general/wp-security-list-table.php:718, dist/admin/general/wp-security-list-table.php:696, dist/admin/general/wp-security-list-table.php:741 +msgid "No comments" +msgstr "" + +#: dist/admin/general/wp-security-ajax-data-table.php:729, dist/admin/general/wp-security-list-table.php:741 +msgid "No pending comments" +msgstr "" + +#. translators: %s: Total items +#. translators: %s: Item count. +#: dist/admin/general/wp-security-ajax-data-table.php:808, dist/admin/general/wp-security-ajax-data-table.php:1434, dist/admin/general/wp-security-list-table.php:819, dist/admin/general/wp-security-list-table.php:1425 +msgid "%s item" +msgid_plural "%s items" +msgstr[0] "" +msgstr[1] "" + +#: dist/admin/general/wp-security-ajax-data-table.php:848, dist/admin/general/wp-security-list-table.php:858 +msgid "First page" +msgstr "" + +#: dist/admin/general/wp-security-ajax-data-table.php:859, dist/admin/general/wp-security-list-table.php:869 +msgid "Previous page" +msgstr "" + +#: dist/admin/general/wp-security-ajax-data-table.php:870, dist/admin/general/wp-security-ajax-data-table.php:866, dist/admin/general/wp-security-list-table.php:880, dist/admin/general/wp-security-list-table.php:876 +msgid "Current page" +msgstr "" + +#. translators: 1: Current page, 2: Total pages +#: dist/admin/general/wp-security-ajax-data-table.php:877, dist/admin/general/wp-security-list-table.php:889 +msgctxt "paging" +msgid "%1$s of %2$s" +msgstr "" + +#: dist/admin/general/wp-security-ajax-data-table.php:885, dist/admin/general/wp-security-list-table.php:897 +msgid "Next page" +msgstr "" + +#: dist/admin/general/wp-security-ajax-data-table.php:896, dist/admin/general/wp-security-list-table.php:908 +msgid "Last page" +msgstr "" + +#: dist/admin/general/wp-security-ajax-data-table.php:1121, dist/admin/general/wp-security-list-table.php:1134 +msgid "Select all" +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:32 +msgid "You must use alphanumeric characters for your login page slug." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:30 +msgid "You cannot use the value \"wp-admin\" for your login page slug." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:26 +msgid "Please enter a value for your login page slug." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:110 +msgid "You have successfully saved cookie based brute force prevention feature settings." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:84 +msgid "Settings have not been saved - your secret word must consist only of alphanumeric characters i.e., letters and/or numbers only." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:82 +msgid "You entered an invalid value for the secret word." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:82, dist/classes/commands/wp-brute-force-commands.php:92, dist/classes/commands/wp-brute-force-commands.php:382, dist/classes/commands/wp-brute-force-commands.php:387 +msgid "It has been set to the default value." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:92 +msgid "You entered an invalid value for the redirect url." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:101 +msgid "You have successfully enabled the cookie based brute force prevention feature" +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:102 +msgid "From now on you will need to log into your WP Admin using the following URL:" +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:104 +msgid "It is important that you save this URL value somewhere in case you forget it, OR," +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:105 +msgid "simply remember to add a \"?%s=1\" to your current site URL address." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:166 +msgid "The cookie test failed." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:166, dist/classes/commands/wp-brute-force-commands.php:167 +msgid "Consequently, this feature cannot be used on this site." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:167 +msgid "The cookie test failed on this server." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:162, dist/classes/commands/wp-brute-force-commands.php:163 +msgid "The cookie test was successful, you can now enable this feature." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:382 +msgid "You entered a non numeric or negative value for the lockout time length field." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:387 +msgid "You entered an incorrect format for the \"Redirect URL\" field." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:429 +msgid "All 404 event logs were deleted from the database successfully." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:427 +msgid "404 Detection Feature - The operation to delete all the 404 event logs failed" +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:446 +msgid "Invalid action provided for 404 log item." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:455 +msgid "Invalid 404 event log ID provided." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:472, dist/classes/commands/wp-brute-force-commands.php:491, dist/classes/commands/wp-security-ip-commands.php:23, dist/classes/commands/wp-security-ip-commands.php:47, dist/classes/commands/wp-security-ip-commands.php:96, dist/classes/commands/wp-security-ip-commands.php:122 +msgid "Invalid IP provided." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:485 +msgid "The selected entry is not a valid IP address." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:483 +msgid "The selected IP address is now temporarily blocked." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:515, dist/classes/commands/wp-brute-force-commands.php:526 +msgid "Invalid log event ID provided." +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:534 +msgid "The selected IP entry could not be unlocked" +msgstr "" + +#: dist/classes/commands/wp-brute-force-commands.php:532 +msgid "Access from the selected IP address has been unblocked." +msgstr "" + +#: dist/classes/commands/wp-security-comment-commands.php:30 +msgid "You entered a non-numeric value for the \"move spam comments to trash after number of days\" field; it has been set to the default value." +msgstr "" + +#: dist/classes/commands/wp-security-comment-commands.php:44, dist/classes/commands/wp-security-comment-commands.php:87, dist/classes/commands/wp-security-firewall-commands.php:251 +msgid "The settings were successfully updated." +msgstr "" + +#: dist/classes/commands/wp-security-comment-commands.php:76 +msgid "You must enter an integer greater than zero for the \"minimum number of spam comments\" field; it has been set to the default value." +msgstr "" + +#: dist/classes/commands/wp-security-comment-commands.php:73 +msgid "You entered a non-numeric value for the \"minimum number of spam comments\" field; it has been set to the default value." +msgstr "" + +#: dist/classes/commands/wp-security-comment-commands.php:115 +msgid "You must enter an integer greater than zero for the minimum spam comments per IP field; it has been set to the default value." +msgstr "" + +#: dist/classes/commands/wp-security-comment-commands.php:112 +msgid "You entered a non-numeric value for the minimum spam comments per IP field; it has been set to the default value." +msgstr "" + +#: dist/classes/commands/wp-security-comment-commands.php:148 +msgid "Invalid IP address provided." +msgstr "" + +#: dist/classes/commands/wp-security-comment-commands.php:164 +msgid "The selected IP address could not be blocked due to one of the following reasons:" +msgstr "" + +#: dist/classes/commands/wp-security-comment-commands.php:165 +msgid "either it has already been blocked, or your user account lacks sufficient permissions to perform IP blocking." +msgstr "" + +#: dist/classes/commands/wp-security-comment-commands.php:161 +msgid "The selected IP address is now permanently blocked." +msgstr "" + +#: dist/classes/commands/wp-security-file-scan-commands.php:31 +msgid "You entered a non numeric value for the \"backup time interval\" field, it has been set to the default value." +msgstr "" + +#: dist/classes/commands/wp-security-file-scan-commands.php:57 +msgid "The following address was removed because it is not a valid email address:" +msgstr "" + +#: dist/classes/commands/wp-security-file-scan-commands.php:80 +msgid "You have configured your file change detection scan to occur at least once daily." +msgstr "" + +#: dist/classes/commands/wp-security-file-scan-commands.php:81 +msgid "For most websites we recommended that you choose a less frequent schedule such as once every few days, once a week or once a month." +msgstr "" + +#: dist/classes/commands/wp-security-file-scan-commands.php:82 +msgid "Choosing a less frequent schedule will also help reduce your server load." +msgstr "" + +#: dist/classes/commands/wp-security-file-scan-commands.php:88 +msgid "New scan completed: The plugin has detected that you have made changes to the \"File Types To Ignore\" or \"Files To Ignore\" fields." +msgstr "" + +#: dist/classes/commands/wp-security-file-scan-commands.php:88 +msgid "In order to ensure that future scan results are accurate, the old scan data has been refreshed." +msgstr "" + +#: dist/classes/commands/wp-security-file-scan-commands.php:95, dist/templates/wp-admin/scanner/file-change-detect.php:22 +msgid "Nothing is currently scheduled" +msgstr "" + +#: dist/classes/commands/wp-security-file-scan-commands.php:126, dist/classes/commands/wp-security-firewall-commands.php:386, dist/classes/commands/wp-security-log-commands.php:153, dist/classes/commands/wp-security-log-commands.php:199, dist/classes/commands/wp-security-tfa-commands.php:34, dist/classes/commands/wp-security-tfa-commands.php:63, dist/classes/commands/wp-security-tfa-commands.php:84, dist/classes/commands/wp-security-tfa-commands.php:108, dist/classes/commands/wp-security-tfa-commands.php:198 +msgid "Sorry, you do not have enough privilege to execute the requested action." +msgstr "" + +#: dist/classes/commands/wp-security-file-scan-commands.php:175 +msgid "No previous scan data was found; either run a manual scan or schedule regular file scans" +msgstr "" + +#: dist/classes/commands/wp-security-file-scan-commands.php:199 +msgid "There was an error during the file change detection scan." +msgstr "" + +#: dist/classes/commands/wp-security-file-scan-commands.php:199 +msgid "Please check the plugin debug logs." +msgstr "" + +#: dist/classes/commands/wp-security-file-scan-commands.php:212, dist/templates/wp-admin/scanner/file-change-detect.php:5 +msgid "The scan has detected that there was a change in your website's files." +msgstr "" + +#: dist/classes/commands/wp-security-file-scan-commands.php:212, dist/classes/commands/wp-security-file-scan-commands.php:207 +msgid "View the file scan results" +msgstr "" + +#: dist/classes/commands/wp-security-file-scan-commands.php:210 +msgid "The scan is complete - There were no file changes detected." +msgstr "" + +#: dist/classes/commands/wp-security-file-scan-commands.php:207 +msgid "This is your first file change detection scan." +msgstr "" + +#: dist/classes/commands/wp-security-file-scan-commands.php:207 +msgid "The details from this scan will be used for future scans." +msgstr "" + +#: dist/classes/commands/wp-security-file-scan-commands.php:208 +msgid "View last file scan results" +msgstr "" + +#: dist/classes/commands/wp-security-files-commands.php:44 +msgid "Unable to change permissions for %s : not in list of valid files" +msgstr "" + +#: dist/classes/commands/wp-security-files-commands.php:40 +msgid "Unable to change permissions for %s" +msgstr "" + +#: dist/classes/commands/wp-security-files-commands.php:38 +msgid "The permissions for %s were successfully changed to %s" +msgstr "" + +#: dist/classes/commands/wp-security-files-commands.php:86 +msgid "Disable PHP file editing failed: unable to modify or make a backup of the wp-config.php file." +msgstr "" + +#: dist/classes/commands/wp-security-files-commands.php:102 +msgid "Could not write to the .htaccess file." +msgstr "" + +#: dist/classes/commands/wp-security-files-commands.php:99 +msgid "The settings have been successfully updated" +msgstr "" + +#: dist/classes/commands/wp-security-files-commands.php:126 +msgid "The files have been deleted successfully." +msgstr "" + +#: dist/classes/commands/wp-security-files-commands.php:132 +msgid "Failed to delete the %s file(s)." +msgstr "" + +#: dist/classes/commands/wp-security-files-commands.php:132 +msgid "Please try to delete them manually." +msgstr "" + +#: dist/classes/commands/wp-security-files-commands.php:190 +msgid "No system logs were found." +msgstr "" + +#: dist/classes/commands/wp-security-firewall-commands.php:93 +msgid "The attempt to save the 'Block fake Googlebots' settings failed, because it was not possible to validate the Googlebot IP addresses:" +msgstr "" + +#: dist/classes/commands/wp-security-firewall-commands.php:210 +msgid "Could not write to the .htaccess file" +msgstr "" + +#: dist/classes/commands/wp-security-firewall-commands.php:271 +msgid "Could not write to the .htaccess file for the 5G firewall settings, please check the file permissions." +msgstr "" + +#: dist/classes/commands/wp-security-firewall-commands.php:430 +msgid "Firewall has been setup successfully." +msgstr "" + +#: dist/classes/commands/wp-security-firewall-commands.php:449 +msgid "Something went wrong please try again later." +msgstr "" + +#: dist/classes/commands/wp-security-firewall-commands.php:449 +msgid "Firewall has been downgraded successfully." +msgstr "" + +#. translators: %s URL entered by user. +#: dist/classes/commands/wp-security-firewall-commands.php:522 +msgid "%s is not a valid url." +msgstr "" + +#: dist/classes/commands/wp-security-firewall-commands.php:726 +msgid "We were unable to access the firewall's configuration file:" +msgstr "" + +#: dist/classes/commands/wp-security-firewall-commands.php:728 +msgid "As a result, the firewall will be unavailable." +msgstr "" + +#: dist/classes/commands/wp-security-firewall-commands.php:729 +msgid "Please check your PHP error log for further information." +msgstr "" + +#: dist/classes/commands/wp-security-firewall-commands.php:730 +msgid "If you're unable to locate your PHP log file, please contact your web hosting company to ask them where it can be found on their setup." +msgstr "" + +#: dist/classes/commands/wp-security-ip-commands.php:19, dist/classes/commands/wp-security-ip-commands.php:43, dist/classes/commands/wp-security-ip-commands.php:92, dist/classes/commands/wp-security-ip-commands.php:118 +msgid "No IP provided." +msgstr "" + +#: dist/classes/commands/wp-security-ip-commands.php:29 +msgid "The selected IP address was unlocked successfully." +msgstr "" + +#: dist/classes/commands/wp-security-ip-commands.php:27 +msgid "Failed to unlock the selected IP address." +msgstr "" + +#: dist/classes/commands/wp-security-ip-commands.php:53 +msgid "The selected IP address was unblacklisted successfully." +msgstr "" + +#: dist/classes/commands/wp-security-ip-commands.php:51 +msgid "Failed to unblacklist the selected IP address." +msgstr "" + +#: dist/classes/commands/wp-security-ip-commands.php:67 +msgid "Invalid blocked IP ID provided." +msgstr "" + +#: dist/classes/commands/wp-security-ip-commands.php:100 +msgid "No lockout reason provided." +msgstr "" + +#: dist/classes/commands/wp-security-ip-commands.php:105 +msgid "The selected IP address is now temporarily locked." +msgstr "" + +#: dist/classes/commands/wp-security-ip-commands.php:130 +msgid "The selected IP address has been added to the blacklist." +msgstr "" + +#: dist/classes/commands/wp-security-log-commands.php:19 +msgid "No audit log ID provided." +msgstr "" + +#: dist/classes/commands/wp-security-log-commands.php:38 +msgid "No locked IP record ID provided." +msgstr "" + +#: dist/classes/commands/wp-security-log-commands.php:61 +msgid "The debug logs have been cleared." +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:30 +msgid "Some of the security features could not be disabled." +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:141 +msgid "htaccess backup failed." +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:135 +msgid "Your .htaccess file was successfully backed up." +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:188 +msgid "The restoration .htaccess file has failed, please check the contents of the file you are trying to restore from." +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:183 +msgid "Your .htaccess file has successfully been restored." +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:180 +msgid "The restoration of the .htaccess file failed; please attempt to restore the .htaccess file manually using FTP." +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:170 +msgid "Please choose a valid .htaccess to restore from." +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:234 +msgid "The restoration of the wp-config.php file failed, please check the contents of the file you are trying to restore from." +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:230 +msgid "Your wp-config.php file has successfully been restored." +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:227 +msgid "The restoration of the wp-config.php file failed, please attempt to restore this file manually using FTP." +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:215 +msgid "Please choose a wp-config.php file to restore from." +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:306 +msgid "Your AIOS settings were successfully imported." +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:387 +msgid "The contents of your settings file are invalid, please check the contents of the file you are trying to import settings from." +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:355 +msgid "Import AIOS settings operation failed." +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:311 +msgid "Please choose a file to import your settings from." +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:532 +msgid "Default - if correct, then this is the best option" +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:533 +msgid "Only use if you're using Cloudflare." +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:546 +msgid "no value (i.e. empty) on your server" +msgstr "" + +#: dist/classes/commands/wp-security-settings-commands.php:543 +msgid "(current value: %s)" +msgstr "" + +#: dist/classes/commands/wp-security-tools-commands.php:39, dist/classes/commands/wp-security-tools-commands.php:33 +msgid "Nothing to show." +msgstr "" + +#: dist/classes/commands/wp-security-tools-commands.php:32 +msgid "Please enter a valid IP address or domain name to look up." +msgstr "" + +#: dist/classes/commands/wp-security-tools-commands.php:99 +msgid "The plugin was unable to write to the .htaccess file, please edit file manually." +msgstr "" + +#: dist/classes/commands/wp-security-tools-commands.php:71 +msgid "You must enter some .htaccess directives in the text box below" +msgstr "" + +#: dist/classes/commands/wp-security-tools-commands.php:183, dist/classes/commands/wp-security-tools-commands.php:226 +msgid "Querying %s: %s" +msgstr "" + +#: dist/classes/commands/wp-security-tools-commands.php:191, dist/classes/commands/wp-security-tools-commands.php:200, dist/classes/commands/wp-security-tools-commands.php:242 +msgid "Redirected to %s" +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:108 +msgid "Please enter a value for your username." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:104 +msgid "You entered an invalid username, please enter another value." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:73 +msgid "The database update operation of the user account failed." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:58 +msgid "Username: %s already exists, please enter another value." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:114 +msgid "The username has been successfully changed." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:211 +msgid "The following options had invalid values and have been set to the defaults: %s" +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:318 +msgid "You entered a non numeric or negative value for the logout time period field, it has been set to the default value." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:444 +msgid "Invalid action provided for logged in user." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:452 +msgid "No user ID was provided" +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:465 +msgid "You cannot log out a user from a different subsite." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:463 +msgid "Super admins cannot be logged out." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:461 +msgid "You cannot log yourself out" +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:459 +msgid "Invalid user ID provided." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:481 +msgid "Failed to log out the selected user." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:479 +msgid "The selected user has been logged out successfully." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:535 +msgid "Invalid action provided for registered user." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:544, dist/classes/commands/wp-security-user-security-commands.php:567 +msgid "No valid user ID was provided" +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:560 +msgid "The selected account could not be approved." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:556 +msgid "The selected account was approved successfully." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:579 +msgid "The selected account could not be deleted." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:575 +msgid "The selected account was deleted successfully." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:586 +msgid "No valid IP address was provided" +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:605 +msgid "The selected IP could not be added to the permanent block list." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:600 +msgid "The selected IP was successfully added to the permanent block list." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:682 +msgid "You don't have enough permissions to whitelist your IP address." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:700 +msgid "Your IP address could not be detected." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:708 +msgid "There was an error whitelisting your IP address, please try again." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:712 +msgid "Your IP address has been whitelisted successfully." +msgstr "" + +#: dist/classes/commands/wp-security-user-security-commands.php:693 +msgid "Your IP address is already whitelisted." +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:53 +msgid "Remove WP generator meta tag" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:62, dist/templates/wp-admin/user-security/partials/wp-username.php:23 +msgid "Change admin username" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:71 +msgid "Change display name" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:106, dist/templates/wp-admin/user-security/additional.php:19 +msgid "Disable application password" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:114 +msgid "Login Lockout IP whitelisting" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:123 +msgid "Registration approval" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:131 +msgid "Registration CAPTCHA" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:139 +msgid "Enable registration honeypot" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:147 +msgid "HTTP authentication for admin and frontend" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:176 +msgid "File editing" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:184 +msgid "WordPress files access" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:193 +msgid "IP and user agent blacklisting" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:202 +msgid "Enable basic firewall" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:211 +msgid "Enable pingback vulnerability protection" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:219, dist/templates/wp-admin/firewall/partials/block-debug-log.php:3 +msgid "Block access to debug log file" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:228, dist/templates/wp-admin/firewall/partials/listing-directory-contents.php:14 +msgid "Disable index views" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:237, dist/templates/wp-admin/firewall/partials/disable-trace.php:14 +msgid "Disable trace and track" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:246 +msgid "Forbid proxy comments" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:254 +msgid "Deny bad queries" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:262, dist/templates/wp-admin/firewall/partials/advanced-character-filter.php:3 +msgid "Advanced character string filter" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:270 +msgid "6G firewall" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:278, dist/templates/wp-admin/firewall/partials/fake-googlebots.php:29 +msgid "Block fake Googlebots" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:286, dist/templates/wp-admin/filesystem-security/partials/prevent-hotlinks.php:20 +msgid "Prevent image hotlinking" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:294 +msgid "Enable IP blocking for 404 detection" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:302 +msgid "Disable RSS and ATOM feeds" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:310, dist/templates/wp-admin/firewall/partials/upgrade-unsafe-http-calls.php:3 +msgid "Upgrade unsafe HTTP calls" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:319 +msgid "Enable rename login page" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:327, dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:59 +msgid "Enable brute force attack prevention" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:335 +msgid "Login CAPTCHA" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:343 +msgid "Lost password CAPTCHA" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:351 +msgid "Custom login CAPTCHA" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:359 +msgid "Password-protected CAPTCHA" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:367 +msgid "Login IP whitelisting" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:375 +msgid "Enable login honeypot" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:384 +msgid "Comment CAPTCHA" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:392 +msgid "Detect spambots" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:400 +msgid "Auto block spam ips" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:418 +msgid "Enable Copy Protection" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:426, dist/templates/wp-admin/filesystem-security/frames.php:21 +msgid "Enable iFrame protection" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:434 +msgid "Disable users enumeration" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:442, dist/templates/wp-admin/firewall/partials/wp-rest-api.php:35 +msgid "Disallow unauthorized REST requests" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:450, dist/templates/wp-admin/user-security/salt.php:30 +msgid "Enable salt postfix" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:459 +msgid "BuddyPress registration CAPTCHA" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:468 +msgid "bbPress new topic CAPTCHA" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:477 +msgid "Woo login CAPTCHA" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:486 +msgid "Woo lost password CAPTCHA" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:495 +msgid "Woo register CAPTCHA" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:504 +msgid "Woo Checkout CAPTCHA" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:514 +msgid "Ban POST requests that have blank user-agent and referer headers" +msgstr "" + +#. translators: %s: Plugin name +#: dist/classes/grade-system/wp-security-feature-item-manager.php:523 +msgid "%s CAPTCHA" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:532 +msgid "Enforce use of strong passwords by users" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:603 +msgid "Feature difficulty" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item-manager.php:605 +msgid "Security points" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item.php:64 +msgid "Advanced" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item.php:62 +msgid "Intermediate" +msgstr "" + +#: dist/classes/grade-system/wp-security-feature-item.php:60 +msgid "Basic" +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:183, dist/templates/admin/incompatible-plugin.php:6, dist/includes/simba-tfa/templates/user-settings.php:20 +msgid "Two Factor Authentication" +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:185 +msgid "Go here for your two factor authentication settings..." +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:419 +msgid "2FA" +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:441, dist/includes/simba-tfa/simba-tfa.php:1307 +msgid "Enabled" +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1064 +msgid "The \"encrypt secrets\" feature is currently enabled, but no encryption key has been found (set via the SIMBA_TFA_DB_ENCRYPTION_KEY constant)." +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1064 +msgid "This indicates that either setup failed, or your WordPress installation has been corrupted." +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1064 +msgid "Go here for the FAQs, which explain how a website owner can de-activate the plugin without needing to login." +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1065, dist/includes/simba-tfa/includes/login-form-integrations.php:128 +msgid "The one-time password (TFA code) you entered was incorrect." +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1212 +msgid "Incorrect TFA code attempts" +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1213 +msgid "There has been an incorrect TFA code entered for logging in to your account %s." +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1214 +msgid "Attempts" +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1216 +msgid "from" +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1218 +msgid "If the above attempts were not by you then someone else has your password." +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1219 +msgid "TFA codes are checked only after the password has been successfully checked." +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1220 +msgid "Please change your password urgently." +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1304 +msgid "N.B. This site is configured to forbid you to log in if you disable two-factor authentication after your account is %d days old" +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1307 +msgid "Enable two-factor authentication" +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1312 +msgid "(you must enter the current code: %s)" +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1310 +msgid "(Current code: %s)" +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1317 +msgid "Disable two-factor authentication" +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1423 +msgid "Do not require 2FA over XMLRPC (best option if you must use XMLRPC and your client does not support 2FA)" +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1424 +msgid "Do require 2FA over XMLRPC (best option if you do not use XMLRPC or are unsure)" +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1470 +msgid "The indicated user could not be found." +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1507 +msgid "The site owner has forbidden you to login without two-factor authentication. Please contact the site owner to re-gain access." +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1521 +msgid "You are attempting to log in to an account that has two-factor authentication enabled; this requires you to also have two-factor authentication enabled on the account whose credentials you are using." +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1595 +msgid "Click to enter One Time Password" +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1596 +msgid "You have to enter a username first." +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1597 +msgid "One Time Password (i.e. 2FA)" +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1598 +msgid "(check your OTP app to get this password)" +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1599 +msgid "Trust this device (allow login without 2FA for %d day)" +msgid_plural "Trust this device (allow login without TFA for %d days)" +msgstr[0] "" +msgstr[1] "" + +#: dist/includes/simba-tfa/simba-tfa.php:1600 +msgid "(Trusted device - no OTP code required)" +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1604 +msgid "An error has occurred. Site owners can check the JavaScript console for more details." +msgstr "" + +#: dist/includes/simba-tfa/simba-tfa.php:1664 +msgid "Template path not found:" +msgstr "" + +#: dist/templates/admin/incompatible-plugin.php:10, dist/includes/simba-tfa/templates/admin-settings.php:24 +msgid "Two Factor Authentication currently disabled" +msgstr "" + +#. translators: %s: Incompatible plugin name. +#: dist/templates/admin/incompatible-plugin.php:13, dist/templates/admin/incompatible-plugin.php:18 +msgid "Two factor authentication in All In One WP Security is currently disabled because the incompatible plugin %s is active." +msgstr "" + +#: dist/templates/info/ip-address-ip-range-info.php:2, dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:63, dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:100, dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:123, dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:145, dist/templates/wp-admin/firewall/5g.php:17, dist/templates/wp-admin/scanner/file-change-detect.php:100, dist/templates/wp-admin/scanner/file-change-detect.php:119, dist/templates/wp-admin/settings/advanced-settings.php:66, dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:46, dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:81, dist/templates/wp-admin/spam-prevention/comment-spam.php:25, dist/templates/wp-admin/spam-prevention/comment-spam.php:42, dist/templates/wp-admin/spam-prevention/comment-spam.php:86, dist/templates/wp-admin/user-security/login-lockout.php:117, dist/templates/wp-admin/user-security/salt.php:36, dist/templates/wp-admin/brute-force/partials/other-plugins.php:58, dist/templates/wp-admin/firewall/partials/advanced-character-filter.php:17, dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:17, dist/templates/wp-admin/firewall/partials/bad-query-strings.php:17, dist/templates/wp-admin/firewall/partials/basic-firewall-settings.php:17, dist/templates/wp-admin/firewall/partials/blank-ref-and-useragent.php:17, dist/templates/wp-admin/firewall/partials/block-debug-log.php:18, dist/templates/wp-admin/firewall/partials/disable-rss-atom.php:17, dist/templates/wp-admin/firewall/partials/disable-trace.php:18, dist/templates/wp-admin/firewall/partials/fake-googlebots.php:33, dist/templates/wp-admin/firewall/partials/firewall-setup.php:18, dist/templates/wp-admin/firewall/partials/listing-directory-contents.php:18, dist/templates/wp-admin/firewall/partials/ng.php:29, dist/templates/wp-admin/firewall/partials/proxy-comment.php:17, dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:18, dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:39 +msgid "More info" +msgstr "" + +#: dist/templates/info/ip-address-ip-range-info.php:5 +msgid "Each IP address must be on a new line." +msgstr "" + +#: dist/templates/info/ip-address-ip-range-info.php:6 +msgid "You can add comments to the IP entries by placing a '#' at the start of a line." +msgstr "" + +#: dist/templates/info/ip-address-ip-range-info.php:7 +msgid "This can be useful for annotating each IP address with notes (e.g., identifying the individual or system associated with the IP)." +msgstr "" + +#: dist/templates/info/ip-address-ip-range-info.php:8 +msgid "To specify an IPv4 range use a wildcard \"*\" character, acceptable ways to use wildcards is shown in the examples below:" +msgstr "" + +#: dist/templates/info/ip-address-ip-range-info.php:9 +msgid "Example 1: 195.47.89.*" +msgstr "" + +#: dist/templates/info/ip-address-ip-range-info.php:10 +msgid "Example 2: 195.47.*.*" +msgstr "" + +#: dist/templates/info/ip-address-ip-range-info.php:11 +msgid "Example 3: 195.*.*.*" +msgstr "" + +#: dist/templates/info/ip-address-ip-range-info.php:12 +msgid "To specify an IPv6 range use CIDR format as shown in the examples below:" +msgstr "" + +#: dist/templates/info/ip-address-ip-range-info.php:13 +msgid "Example 4: 2401:4900:54c3:af15:2:2:5dc0:0/112" +msgstr "" + +#: dist/templates/info/ip-address-ip-range-info.php:14 +msgid "Example 5: 2001:db8:1263::/48" +msgstr "" + +#: dist/templates/notices/cookie-based-brute-force-prevention-disabled.php:4 +msgid "Cookie based brute force login prevention currently disabled" +msgstr "" + +#: dist/templates/notices/cookie-based-brute-force-prevention-disabled.php:7 +msgid "Cookie based brute force login prevention is currently disabled via the AIOS_DISABLE_COOKIE_BRUTE_FORCE_PREVENTION constant (which is most likely to be defined in your %s)" +msgstr "" + +#: dist/templates/notices/custom-notice.php:13, dist/templates/notices/custom-notice.php:11, dist/templates/notices/firewall-setup-notice.php:29, dist/templates/notices/horizontal-notice.php:54, dist/templates/notices/horizontal-notice.php:52, dist/templates/notices/htaccess-to-php-feature-notice.php:12, dist/templates/notices/htaccess-to-php-feature-notice.php:10 +msgid "Dismiss" +msgstr "" + +#: dist/templates/notices/custom-notice.php:29, dist/templates/wp-admin/dashboard/may-also-like.php:83, dist/templates/wp-admin/dashboard/may-also-like.php:94, dist/templates/wp-admin/dashboard/may-also-like.php:105, dist/templates/wp-admin/dashboard/may-also-like.php:116, dist/templates/wp-admin/dashboard/may-also-like.php:127, dist/templates/wp-admin/dashboard/may-also-like.php:194, dist/templates/wp-admin/dashboard/may-also-like.php:205, dist/templates/wp-admin/dashboard/may-also-like.php:216, dist/templates/wp-admin/dashboard/may-also-like.php:227, dist/templates/wp-admin/dashboard/may-also-like.php:238, dist/templates/wp-admin/dashboard/may-also-like.php:259, dist/templates/wp-admin/dashboard/may-also-like.php:271, dist/templates/wp-admin/dashboard/may-also-like.php:283 +msgid "No" +msgstr "" + +#: dist/templates/notices/disable-login-whitelist.php:4 +msgid "Login whitelisting currently disabled" +msgstr "" + +#: dist/templates/notices/disable-login-whitelist.php:6 +msgid "Login whitelisting is currently disabled via the AIOS_DISABLE_LOGIN_WHITELIST constant (which is mostly likely to be defined in your wp-config.php)" +msgstr "" + +#: dist/templates/notices/firewall-installed-notice.php:5 +msgid "Your firewall has been installed with the highest level of protection." +msgstr "" + +#: dist/templates/notices/firewall-installed-notice.php:6 +msgid "You may have to wait 5 minutes for the changes to take effect." +msgstr "" + +#: dist/templates/notices/firewall-setup-notice.php:12 +msgid "Our PHP-based firewall has been created to give you even greater protection." +msgstr "" + +#: dist/templates/notices/firewall-setup-notice.php:13 +msgid "To ensure the PHP-based firewall runs before any potentially vulnerable code in your WordPress site can be reached, it will need to be set up." +msgstr "" + +#: dist/templates/notices/firewall-setup-notice.php:17 +msgid "If you already have our .htaccess-based firewall enabled, you will still need to set up the PHP-based firewall to benefit from its protection." +msgstr "" + +#: dist/templates/notices/firewall-setup-notice.php:20 +msgid "To set up the PHP-based firewall, press the 'Set up now' button below:" +msgstr "" + +#: dist/templates/notices/firewall-setup-notice.php:23 +msgid "Set up now" +msgstr "" + +#: dist/templates/notices/horizontal-notice.php:42, dist/templates/notices/horizontal-notice.php:9 +msgid "notice image" +msgstr "" + +#: dist/templates/notices/horizontal-notice.php:90 +msgid "Read more" +msgstr "" + +#: dist/templates/notices/horizontal-notice.php:88 +msgid "Learn more" +msgstr "" + +#: dist/templates/notices/horizontal-notice.php:86 +msgid "Go there" +msgstr "" + +#: dist/templates/notices/horizontal-notice.php:84 +msgid "Sign up" +msgstr "" + +#: dist/templates/notices/horizontal-notice.php:82 +msgid "Get Premium." +msgstr "" + +#: dist/templates/notices/horizontal-notice.php:80 +msgid "Get WP-Optimize" +msgstr "" + +#: dist/templates/notices/horizontal-notice.php:78 +msgid "Get UpdraftPlus" +msgstr "" + +#: dist/templates/notices/horizontal-notice.php:76 +msgid "Get UpdraftCentral" +msgstr "" + +#: dist/templates/notices/horizontal-notice.php:19 +msgid "Review" +msgstr "" + +#: dist/templates/notices/horizontal-notice.php:23 +msgid "Maybe later" +msgstr "" + +#: dist/templates/notices/horizontal-notice.php:27 +msgid "Never" +msgstr "" + +#. translators: %s: Number of months +#: dist/templates/notices/thanks-for-using-main-dash.php:5 +msgid "Dismiss (for %s months)" +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:11 +msgid "Thank you for using All-In-One Security!" +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:9 +msgid "Thank you for using All-In-One Security Premium!" +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:22 +msgid "Protect your investment with the ultimate in WordPress website security." +msgstr "" + +#. translators: %s 'AIOS Premium' URL +#: dist/templates/notices/thanks-for-using-main-dash.php:27 +msgid "Get malware scanning, country blocking, premium support and more advanced security features with %s." +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:28 +msgid "AIOS Premium" +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:33 +msgid "Explore more top-rated plugins" +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:37 +msgid "WP-Optimize Premium:" +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:40 +msgid "Unlock new ways to speed up your WordPress website." +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:42 +msgid "Optimize from the WP-CLI, cache multilingual and multi currency websites and more." +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:47 +msgid "UpdraftPlus Premium:" +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:50 +msgid "Schedule automatic backups, run backups before updates, and restore with ease." +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:55 +msgid "Burst Statistics:" +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:58 +msgid "Privacy-friendly analytics that lets you track traffic without collecting personal data." +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:63 +msgid "Internal Link Juicer:" +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:66 +msgid "Automatically build internal links to save time and boost SEO." +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:68 +msgid "You don’t have to be an SEO expert to use this plugin!" +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:73 +msgid "WP Overnight:" +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:76 +msgid "Premium WooCommerce add-ons built to optimize your store, improve UX, and increase revenue." +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:81 +msgid "Browse more" +msgstr "" + +#: dist/templates/notices/thanks-for-using-main-dash.php:81 +msgid "Premium WooCommerce plugins" +msgstr "" + +#: dist/templates/partials/non-apache-feature-notice.php:9, dist/templates/wp-admin/firewall/partials/xmlrpc-warning-notice.php:6 +msgid "Attention:" +msgstr "" + +#: dist/templates/partials/non-apache-feature-notice.php:9 +msgid "This feature works only on the Apache server." +msgstr "" + +#. translators: %s: Server software +#: dist/templates/partials/non-apache-feature-notice.php:11 +msgid "You are using the non-apache server %s, so this feature won't work on your site." +msgstr "" + +#. translators: %s: Multi user plugin directory +#: dist/includes/simba-tfa/includes/tfa-encryption-muplugin.php:73 +msgid "Encrypt secrets feature not enabled: no directory has been set." +msgstr "" + +#: dist/includes/simba-tfa/includes/tfa-encryption-muplugin.php:73 +msgid "Please check your %s constant is valid" +msgstr "" + +#. translators: %s: Multi user plugin directory +#: dist/includes/simba-tfa/includes/tfa-encryption-muplugin.php:82 +msgid "The encrypt secrets feature was not enabled: your mu-plugins directory could not be automatically created; therefore, please use your web hosting file manager or FTP to manually create this folder and then try again: %s" +msgstr "" + +#. translators: %s: File path. +#: dist/includes/simba-tfa/includes/tfa-encryption-muplugin.php:91 +msgid "The encrypt secrets feature was not enabled: attempting to write the mu-plugin file contents failed; therefore, please create the file manually." +msgstr "" + +#: dist/includes/simba-tfa/includes/tfa-encryption-muplugin.php:91 +msgid "Add the following code to the file %s" +msgstr "" + +#: dist/includes/simba-tfa/includes/tfa-encryption-muplugin.php:91 +msgid "Once you have added the above code then press the button to turn on encryption again" +msgstr "" + +#: dist/includes/simba-tfa/includes/tfa_frontend.php:75 +msgid "The TFA code you entered was incorrect." +msgstr "" + +#: dist/includes/simba-tfa/includes/tfa_frontend.php:67 +msgid "To enable TFA, you must enter the current code." +msgstr "" + +#: dist/includes/simba-tfa/includes/tfa_frontend.php:99 +msgid "a time based" +msgstr "" + +#: dist/includes/simba-tfa/includes/tfa_frontend.php:99 +msgid "an event based" +msgstr "" + +#: dist/includes/simba-tfa/includes/tfa_frontend.php:129 +msgid "No emergency codes left. Sorry." +msgstr "" + +#: dist/includes/simba-tfa/includes/tfa_frontend.php:138, dist/includes/simba-tfa/includes/tfa_frontend.php:152 +msgid "Save Settings" +msgstr "" + +#: dist/includes/simba-tfa/includes/tfa_frontend.php:182 +msgid "You have unsaved settings." +msgstr "" + +#: dist/includes/simba-tfa/includes/tfa_frontend.php:187, dist/includes/simba-tfa/providers/totp/loader.php:199 +msgid "Response:" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:8 +msgid "Two Factor Authentication - Admin Settings" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:26 +msgid "Two factor authentication is currently disabled via the TWO_FACTOR_DISABLE constant (which is mostly likely to be defined in your wp-config.php)" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:38 +msgid "N.B. These two-factor settings apply to your entire WordPress network. (i.e. They are not localised to one particular site)." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:50 +msgid "Make two factor authentication available" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:51 +msgid "Choose which user roles will have two factor authentication available." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:61 +msgid "Make two factor authentication compulsory" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:65 +msgid "Requiring users to use two-factor authentication is a feature of the Premium version of this plugin." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:71, dist/includes/simba-tfa/templates/admin-settings.php:193 +msgid "Trusted devices" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:75 +msgid "Choose which user roles are permitted to mark devices they login on as trusted. This feature requires browser cookies and an https (i.e. SSL) connection to the website to work." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:78 +msgid "Allowing users to mark a device as trusted so that a two-factor code is only needed once in a specified number of days (instead of every login) is a feature of the Premium version of this plugin." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:92 +msgid "XMLRPC requests" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:96 +msgid "XMLRPC is a feature within WordPress allowing other computers to talk to your WordPress install. For example, it could be used by an app on your tablet that allows you to blog directly from the app (instead of needing the WordPress dashboard)." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:99 +msgid "Unfortunately, XMLRPC also provides a way for attackers to perform actions on your WordPress site, using only a password (i.e. without a two-factor password). More unfortunately, authors of legitimate programmes using XMLRPC have not yet added two-factor support to their code." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:102 +msgid "i.e. XMLRPC requests coming in to WordPress (whether from a legitimate app, or from an attacker) can only be verified using the password - not with a two-factor code. As a result, there not be an ideal option to pick below. You may have to choose between the convenience of using your apps, or the security of two factor authentication." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:117 +msgid "Default algorithm for codes generated by user devices" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:118 +msgid "Your users can change this in their own settings if they want." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:138, dist/includes/simba-tfa/templates/admin-settings.php:130 +msgid "Encrypt keys in database" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:140 +msgid "Once turned on, this feature cannot be turned off (but there is no technical reason why this should discourage you from using it)." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:143 +msgid "This feature will encrypt all two factor authentication secret keys stored in the database, using an encryption key that is stored on your disk." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:144 +msgid "This means that in the event your database is compromised there's an additional layer of security (the attacker would need to compromise your on-disk data as well) protecting your two factor authentication secret keys." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:146 +msgid "Enable encryption of database keys" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:132 +msgid "Encryption of keys in the database has been enabled." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:132 +msgid "This feature cannot be turned off." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:158 +msgid "WooCommerce integration" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:160 +msgid "The Premium version of this plugin allows you to add a configuration tab for users in the WooCommerce \"My account\" area, and anti-bot protection on the WooCommerce login form." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:169 +msgid "Users' settings" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:175 +msgid "The Premium version of this plugin allows you to see and reset the TFA settings of other users." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:177 +msgid "Another way to do that is by using a user-switching plugin like this one." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:185 +msgid "Premium version" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:187 +msgid "If you want to say 'thank you' or help this plugin's development, or get extra features, then please take a look at the premium version of this plugin." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:187 +msgid "It comes with these extra features:" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:191, dist/includes/simba-tfa/providers/totp/loader.php:446 +msgid "Emergency codes" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:191 +msgid "provide your users with one-time codes to use in case they lose their device." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:192 +msgid "Make TFA compulsory" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:192 +msgid "require your users to set up TFA to be able to log in, after an optional grace period." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:193 +msgid "allow privileged (or all) users to mark a device as trusted and thereby only needing to supply a TFA code upon login every so-many days (e.g. every 30 days) instead of on each login." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:194 +msgid "Manage all users centrally" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:194 +msgid "enable, disable or see TFA codes for all your users from one central location." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:195 +msgid "More shortcodes" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:195 +msgid "flexible shortcodes allowing you to design your front-end settings page for your users exactly as you wish." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:196 +msgid "More WooCommerce features" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:196 +msgid "automatically add TFA settings in the WooCommerce account settings, and WooCommerce login form bot protection." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:197 +msgid "Elementor support" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:197 +msgid "adds support for Elementor login forms." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:198 +msgid "Any-form support" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:198 +msgid "adds support for any login form from any plugin via appending your TFA code onto the end of your password." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:199 +msgid "Personal support" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:199 +msgid "access to our personal support desk for 12 months." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:206 +msgid "Translations" +msgstr "" + +#. translators: %s: Plugin translation URL. +#: dist/includes/simba-tfa/templates/admin-settings.php:209 +msgid "If you want to translate this plugin, please go to %s" +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:209 +msgid "the wordpress.org translation website." +msgstr "" + +#: dist/includes/simba-tfa/templates/admin-settings.php:209 +msgid "Don't send us the translation file directly - plugin authors do not have access to the wordpress.org translation system (local language teams do)." +msgstr "" + +#: dist/includes/simba-tfa/templates/settings-intro-notices.php:5 +msgid "These are your personal settings." +msgstr "" + +#: dist/includes/simba-tfa/templates/settings-intro-notices.php:5 +msgid "Nothing you change here will have any effect on other users." +msgstr "" + +#: dist/includes/simba-tfa/templates/settings-intro-notices.php:17, dist/includes/simba-tfa/templates/settings-intro-notices.php:13 +msgid "The site-wide administration options are here." +msgstr "" + +#: dist/includes/simba-tfa/templates/settings-intro-notices.php:25 +msgid "If you activate two-factor authentication, then verify that your two-factor application and this page show the same One-Time Password (within a minute of each other) before you log out." +msgstr "" + +#: dist/includes/simba-tfa/templates/settings-intro-notices.php:28 +msgid "You should also bookmark the FAQs, which explain how to de-activate the plugin even if you cannot log in." +msgstr "" + +#: dist/includes/simba-tfa/templates/shortcode-tfa-user-settings.php:8 +msgid "Not logged in." +msgstr "" + +#: dist/includes/simba-tfa/templates/shortcode-tfa-user-settings.php:8 +msgid "Two factor authentication is not available for your user." +msgstr "" + +#: dist/includes/simba-tfa/templates/trusted-devices-inner-box.php:5 +msgid "Trusted devices are devices which have previously logged in with a second factor, belonging to users who have been permitted to mark devices as trusted, and for which the user checked the checkbox on the login form to trust the device." +msgstr "" + +#: dist/includes/simba-tfa/templates/trusted-devices-inner-box.php:14 +msgid "(none)" +msgstr "" + +#: dist/includes/simba-tfa/templates/trusted-devices-inner-box.php:21 +msgid "(unspecified)" +msgstr "" + +#: dist/includes/simba-tfa/templates/trusted-devices-inner-box.php:23 +msgid "User agent %s logged in from IP address %s and is trusted until %s" +msgstr "" + +#: dist/includes/simba-tfa/templates/trusted-devices-inner-box.php:23 +msgid "Remove trust" +msgstr "" + +#: dist/includes/simba-tfa/templates/user-settings.php:25 +msgid "Settings saved." +msgstr "" + +#: dist/includes/simba-tfa/templates/user-settings.php:36 +msgid "Activate two factor authentication" +msgstr "" + +#. translators: 1. UTC date. 2. Now date. +#: dist/includes/simba-tfa/templates/user-settings.php:42 +msgid "N.B. Getting your TFA app/device to generate the correct code depends upon a) you first setting it up by entering or scanning the code below into it, and b) upon your web-server and your TFA app/device agreeing upon the UTC time (within a minute or so). The current UTC time according to the server when this page loaded: %1$s, and in the time-zone you have configured in your WordPress settings: %2$s" +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:2 +msgid "404 detection configuration" +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:5 +msgid "A 404 or Not Found error occurs when somebody tries to access a non-existent page on your website." +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:6 +msgid "Typically, most 404 errors happen quite innocently when people have mis-typed a URL or used an old link to page which doesn't exist anymore." +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:7 +msgid "However, in some cases you may find many repeated 404 errors which occur in a relatively short space of time and from the same IP address which are all attempting to access a variety of non-existent page URLs." +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:8 +msgid "Such behaviour can mean that a hacker might be trying to find a particular page or URL for sinister reasons." +msgstr "" + +#. translators: %1$s - Open strong tag, %2$s - Close strong tag. +#: dist/templates/wp-admin/brute-force/404-detection.php:10 +msgid "With this feature enabled, you can use the table below to manually temporarily block IP addresses." +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:10 +msgid "The %1$s Smart 404 %2$s feature in Premium automatically detects and blocks these IP addresses." +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:18, dist/templates/wp-admin/dashboard/may-also-like.php:23, dist/templates/wp-admin/firewall/block-and-allow-lists.php:16 +msgid "All-In-One Security Premium" +msgstr "" + +#. translators: %s: Premium upgrade link +#: dist/templates/wp-admin/brute-force/404-detection.php:20, dist/templates/wp-admin/firewall/block-and-allow-lists.php:17 +msgid "You may also be interested in %s." +msgstr "" + +#. translators: 1: open strong tag, 2: close strong tag. +#: dist/templates/wp-admin/brute-force/404-detection.php:22 +msgid "This plugin adds a number of extra features including %1$s and %2$s." +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:22, dist/templates/wp-admin/firewall/block-and-allow-lists.php:18 +msgid "smart 404 blocking" +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:22, dist/templates/wp-admin/firewall/block-and-allow-lists.php:18 +msgid "country IP blocking" +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:33 +msgid "404 detection options" +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:44 +msgid "Enable 404 IP detection" +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:47 +msgid "Enable this option to detect IP addresses that return 404 errors." +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:53 +msgid "Enable 404 event logging" +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:56 +msgid "Check this if you want to enable the logging of 404 events" +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:61 +msgid "Time length of 404 lockout (minutes)" +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:63 +msgid "Set the length of time for which a blocked IP address will be prevented from visiting your site" +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:67 +msgid "404 lockout redirect URL" +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:69 +msgid "A blocked visitor will be automatically redirected to this URL." +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:73, dist/templates/wp-admin/brute-force/captcha-settings.php:62, dist/templates/wp-admin/brute-force/honeypot.php:50, dist/templates/wp-admin/brute-force/login-whitelist.php:63, dist/templates/wp-admin/brute-force/rename-login.php:52, dist/templates/wp-admin/filesystem-security/file-protection.php:59, dist/templates/wp-admin/filesystem-security/frames.php:30, dist/templates/wp-admin/firewall/block-and-allow-lists.php:82, dist/templates/wp-admin/scanner/file-change-detect.php:145, dist/templates/wp-admin/settings/advanced-settings.php:220, dist/templates/wp-admin/settings/delete-plugin-settings.php:37, dist/templates/wp-admin/settings/wp-version-info.php:35, dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:62, dist/templates/wp-admin/spam-prevention/comment-spam.php:97, dist/templates/wp-admin/user-security/additional.php:28, dist/templates/wp-admin/user-security/force-logout.php:36, dist/templates/wp-admin/user-security/hibp.php:32, dist/templates/wp-admin/user-security/http-authentication.php:103, dist/templates/wp-admin/user-security/login-lockout.php:141, dist/templates/wp-admin/user-security/login-lockout.php:184, dist/templates/wp-admin/user-security/manual-approval.php:30, dist/templates/wp-admin/user-security/salt.php:49, dist/templates/wp-admin/user-security/user-accounts.php:14, dist/templates/wp-admin/firewall/partials/upgrade-unsafe-http-calls.php:45 +msgid "Save settings" +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:79 +msgid "404 event logs" +msgstr "" + +#. translators: %1$d - Purge event records after number of days. +#: dist/templates/wp-admin/brute-force/404-detection.php:83 +msgid "This list displays the 404 event logs when somebody tries to access a non-existent page on your website." +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:83 +msgid "404 event logs that are older than %1$d days are purged automatically." +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:92, dist/templates/wp-admin/brute-force/captcha-settings.php:30, dist/templates/wp-admin/dashboard/audit-logs.php:13, dist/templates/wp-admin/dashboard/permanent-block.php:18, dist/templates/wp-admin/filesystem-security/file-protection.php:32, dist/templates/wp-admin/firewall/htaccess-firewall-rules.php:28, dist/templates/wp-admin/firewall/php-firewall-rules.php:51, dist/templates/wp-admin/user-security/manual-approval.php:51 +msgid "Search" +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:110 +msgid "Press this button if you wish to download this log in CSV format." +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:118, dist/templates/wp-admin/brute-force/404-detection.php:126 +msgid "Delete all 404 event logs" +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:123 +msgid "Press this button if you wish to purge all 404 event logs from the DB." +msgstr "" + +#: dist/templates/wp-admin/brute-force/404-detection.php:126 +msgid "Are you sure you want to delete all records?" +msgstr "" + +#: dist/templates/wp-admin/brute-force/captcha-provider.php:3 +msgid "CAPTCHA provider" +msgstr "" + +#: dist/templates/wp-admin/brute-force/captcha-provider.php:9 +msgid "CAPTCHA will not work because you have disabled login lockout by activating the AIOS_DISABLE_LOGIN_LOCKOUT constant value in a configuration file." +msgstr "" + +#: dist/templates/wp-admin/brute-force/captcha-provider.php:10 +msgid "To enable it, define AIOS_DISABLE_LOGIN_LOCKOUT constant value as false, or remove it." +msgstr "" + +#: dist/templates/wp-admin/brute-force/captcha-provider.php:18 +msgid "This feature allows you to add a CAPTCHA form on various WordPress login pages and forms." +msgstr "" + +#: dist/templates/wp-admin/brute-force/captcha-provider.php:18 +msgid "Adding a CAPTCHA form on a login page or form is another effective yet simple \"Brute Force\" prevention technique." +msgstr "" + +#: dist/templates/wp-admin/brute-force/captcha-provider.php:19 +msgid "You have the option of using either %s, %s or a plain maths CAPTCHA form." +msgstr "" + +#: dist/templates/wp-admin/brute-force/captcha-provider.php:20 +msgid "We recommend %s as a more privacy-respecting option than %s" +msgstr "" + +#: dist/templates/wp-admin/brute-force/captcha-provider.php:24 +msgid "Default CAPTCHA" +msgstr "" + +#: dist/templates/wp-admin/brute-force/captcha-provider.php:43, dist/templates/wp-admin/brute-force/captcha-provider.php:78 +msgid "Site key" +msgstr "" + +#: dist/templates/wp-admin/brute-force/captcha-provider.php:49, dist/templates/wp-admin/brute-force/captcha-provider.php:84 +msgid "Secret key" +msgstr "" + +#: dist/templates/wp-admin/brute-force/captcha-settings.php:6 +msgid "Wordpress forms" +msgstr "" + +#: dist/templates/wp-admin/brute-force/captcha-settings.php:9 +msgid "Woocommerce forms" +msgstr "" + +#: dist/templates/wp-admin/brute-force/captcha-settings.php:13 +msgid "Other forms" +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:2 +msgid "Brute force prevention firewall settings" +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:6 +msgid "A Brute Force Attack is when a hacker tries many combinations of usernames and passwords until they succeed in guessing the right combination." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:6 +msgid "Due to the fact that at any one time there may be many concurrent login attempts occurring on your site via malicious automated robots, this also has a negative impact on your server's memory and performance." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:6 +msgid "The features in this tab will stop the majority of brute force login attacks thus providing even better protection for your WP login page." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:11 +msgid "Read our tutorial on how to use the cookie-based brute force prevention feature" +msgstr "" + +#. translators: %s: Tutorial link. +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:13 +msgid "%s." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:26 +msgid "Cookie based brute force login prevention" +msgstr "" + +#. translators: %s: Notes link. +#. translators: %s: Notes URL. +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:38, dist/templates/wp-admin/brute-force/rename-login.php:32, dist/templates/wp-admin/firewall/block-and-allow-lists.php:39 +msgid "This feature can lock you out of admin if it doesn't work correctly on your site." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:38 +msgid "Before activating this feature, please read the following %s." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:38, dist/templates/wp-admin/brute-force/rename-login.php:32 +msgid "message" +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:62 +msgid "Enable this if you want to protect your login page from a brute force attack." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:67 +msgid "This feature will deny access to your WordPress login page for all people except those who have a special cookie in their browser." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:69 +msgid "To use this feature do the following:" +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:71 +msgid "1) Enable the checkbox." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:73 +msgid "2) Enter a secret word consisting of alphanumeric characters which will be difficult to guess." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:73 +msgid "This secret word will be useful whenever you need to know the special URL which you will use to access the login page (see point below)." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:75 +msgid "3) You will then be provided with a special login URL." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:75 +msgid "You will need to use this URL to login to your WordPress site instead of the usual login URL." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:77 +msgid "NOTE: The system will deposit a special cookie in your browser which will allow you access to the WordPress administration login page." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:79 +msgid "Any person trying to access your login page who does not have the special cookie in their browser will be automatically blocked." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:87 +msgid "Secret word" +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:89 +msgid "Choose a secret word consisting of alphanumeric characters which you can use to access your special URL." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:89 +msgid "You are highly encouraged to choose a word which will be difficult to guess." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:93 +msgid "Re-direct URL" +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:97 +msgid "Specify a URL to redirect a hacker to when they try to access your WordPress login page." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:104 +msgid "The URL specified here can be any site's URL and does not have to be your own." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:106 +msgid "This field will default to: http://127.0.0.1 if you do not enter a value." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:108 +msgid "Useful Tip:" +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:110 +msgid "It's a good idea to not redirect attempted brute force login attempts to your site because it increases the load on your server." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:112 +msgid "Redirecting a hacker or malicious bot back to \"http://127.0.0.1\" is ideal because it deflects them back to their own local host and puts the load on their server instead of yours." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:119 +msgid "My site has posts or pages which are password protected" +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:122 +msgid "Enable this if you are using the native WordPress password protection feature for some or all of your blog posts or pages." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:127 +msgid "In the cases where you are protecting some of your posts or pages using the in-built WordPress password protection feature, a few extra lines of directives and exceptions need to be added so that people trying to access pages are not automatically blocked." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:129 +msgid "By enabling this checkbox, the plugin will add the necessary rules and exceptions so that people trying to access these pages are not automatically blocked." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:131 +msgid "Helpful Tip:" +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:133 +msgid "If you do not use the WordPress password protection feature for your posts or pages then it is highly recommended that you leave this checkbox disabled." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:141 +msgid "My site has a theme or plugins which use AJAX" +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:144 +msgid "Enable this if your site uses AJAX functionality." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:149 +msgid "In the cases where your WordPress installation has a theme or plugin that uses AJAX, a few extra lines of directives and exceptions need to be added to prevent AJAX requests from being automatically blocked by the brute force prevention feature." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:151 +msgid "By enabling this checkbox, the plugin will add the necessary rules and exceptions so that AJAX operations will work as expected." +msgstr "" + +#: dist/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php:161 +msgid "Save feature settings" +msgstr "" + +#: dist/templates/wp-admin/brute-force/honeypot.php:4 +msgid "This feature allows you to add a special hidden \"honeypot\" field on WordPress login and registration pages." +msgstr "" + +#: dist/templates/wp-admin/brute-force/honeypot.php:4 +msgid "This will only be visible to robots and not humans." +msgstr "" + +#: dist/templates/wp-admin/brute-force/honeypot.php:4 +msgid "Since robots usually fill in every input field on a form, they will also submit a value for the special hidden honeypot field." +msgstr "" + +#: dist/templates/wp-admin/brute-force/honeypot.php:4 +msgid "The way honeypots work is that a hidden field is placed somewhere inside a form which only robots will submit." +msgstr "" + +#: dist/templates/wp-admin/brute-force/honeypot.php:4 +msgid "If that field contains a value when the form is submitted then a robot has most likely submitted the form and it is consequently dealt with." +msgstr "" + +#: dist/templates/wp-admin/brute-force/honeypot.php:4 +msgid "Therefore, if the plugin detects that this field has a value when the form is submitted, then the robot which is attempting to submit the form on your site will be redirected to its localhost address - http://127.0.0.1." +msgstr "" + +#: dist/templates/wp-admin/brute-force/honeypot.php:9 +msgid "Login form honeypot settings" +msgstr "" + +#: dist/templates/wp-admin/brute-force/honeypot.php:19 +msgid "Enable honeypot on login page" +msgstr "" + +#: dist/templates/wp-admin/brute-force/honeypot.php:22 +msgid "Enable this if you want the honeypot feature for the login page" +msgstr "" + +#: dist/templates/wp-admin/brute-force/honeypot.php:30 +msgid "Registration form honeypot settings" +msgstr "" + +#: dist/templates/wp-admin/brute-force/honeypot.php:40 +msgid "Enable honeypot on registration page" +msgstr "" + +#: dist/templates/wp-admin/brute-force/honeypot.php:43 +msgid "Enable this if you want the honeypot feature for the registration page" +msgstr "" + +#: dist/templates/wp-admin/brute-force/login-whitelist.php:5 +msgid "The All-In-One Security whitelist feature gives you the option of only allowing certain IP addresses or ranges to have access to your WordPress login page." +msgstr "" + +#: dist/templates/wp-admin/brute-force/login-whitelist.php:5 +msgid "This feature will deny login access for all IP addresses which are not in your whitelist as configured in the settings below." +msgstr "" + +#: dist/templates/wp-admin/brute-force/login-whitelist.php:5 +msgid "By allowing/blocking IP addresses, you are using the most secure first line of defence because login access will only be granted to whitelisted IP addresses and other addresses will be blocked as soon as they try to access your login page." +msgstr "" + +#. translators: %s: AIOS Constant. +#: dist/templates/wp-admin/brute-force/login-whitelist.php:11 +msgid "If you are locked out by the login whitelist feature and you do not have a static IP address, define the following constant %s in wp-config.php to disable the feature." +msgstr "" + +#: dist/templates/wp-admin/brute-force/login-whitelist.php:16 +msgid "Cookie-Based brute force login prevention" +msgstr "" + +#. translators: 1: Brute force link, 2: Rename login link 3: Open strong tag, 4: Close strong tag. +#: dist/templates/wp-admin/brute-force/login-whitelist.php:19 +msgid "Attention: If in addition to enabling the white list feature, you also have one of the %1$s or %2$s features enabled, %3$s you will still need to use your secret word or special slug in the URL when trying to access your WordPress login page %4$s" +msgstr "" + +#: dist/templates/wp-admin/brute-force/login-whitelist.php:19 +msgid "These features are NOT functionally related." +msgstr "" + +#: dist/templates/wp-admin/brute-force/login-whitelist.php:19 +msgid "Having both of them enabled on your site means you are creating 2 layers of security." +msgstr "" + +#: dist/templates/wp-admin/brute-force/login-whitelist.php:28 +msgid "Login IP whitelist settings" +msgstr "" + +#: dist/templates/wp-admin/brute-force/login-whitelist.php:39 +msgid "Enable IP whitelisting" +msgstr "" + +#: dist/templates/wp-admin/brute-force/login-whitelist.php:42, dist/templates/wp-admin/user-security/login-lockout.php:173 +msgid "Enable this if you want the whitelisting of selected IP addresses specified in the settings below" +msgstr "" + +#: dist/templates/wp-admin/brute-force/login-whitelist.php:47 +msgid "Your current IP address" +msgstr "" + +#: dist/templates/wp-admin/brute-force/login-whitelist.php:52, dist/templates/wp-admin/settings/advanced-settings.php:84, dist/templates/wp-admin/settings/advanced-settings.php:193 +msgid "getting..." +msgstr "" + +#: dist/templates/wp-admin/brute-force/login-whitelist.php:54 +msgid "You can copy and paste the above address(es) in the text box below if you want to include it in your login whitelist." +msgstr "" + +#: dist/templates/wp-admin/brute-force/login-whitelist.php:59, dist/templates/wp-admin/user-security/login-lockout.php:179 +msgid "Enter whitelisted IP addresses:" +msgstr "" + +#: dist/templates/wp-admin/brute-force/login-whitelist.php:59, dist/templates/wp-admin/user-security/login-lockout.php:179 +msgid "Enter one or more IP addresses or IP ranges you wish to include in your whitelist." +msgstr "" + +#: dist/templates/wp-admin/brute-force/login-whitelist.php:59 +msgid "Only the addresses specified here will have access to the WordPress login page." +msgstr "" + +#: dist/templates/wp-admin/brute-force/rename-login.php:4 +msgid "An effective Brute Force prevention technique is to change the default WordPress login page URL." +msgstr "" + +#: dist/templates/wp-admin/brute-force/rename-login.php:4 +msgid "Normally if you wanted to login to WordPress you would type your site's home URL followed by wp-login.php." +msgstr "" + +#: dist/templates/wp-admin/brute-force/rename-login.php:4 +msgid "This feature allows you to change the login URL by setting your own slug and renaming the last portion of the login URL which contains the wp-login.php to any string that you like." +msgstr "" + +#: dist/templates/wp-admin/brute-force/rename-login.php:4 +msgid "By doing this, malicious bots and hackers will not be able to access your login page because they will not know the correct login page URL." +msgstr "" + +#: dist/templates/wp-admin/brute-force/rename-login.php:7 +msgid "Login page white list" +msgstr "" + +#: dist/templates/wp-admin/brute-force/rename-login.php:10 +msgid "You may also be interested in the following alternative brute force prevention features:" +msgstr "" + +#: dist/templates/wp-admin/brute-force/rename-login.php:20 +msgid "Rename login page settings" +msgstr "" + +#: dist/templates/wp-admin/brute-force/rename-login.php:32 +msgid "Before activating this feature, you must read the following %s." +msgstr "" + +#: dist/templates/wp-admin/brute-force/rename-login.php:33 +msgid "NOTE: If you are hosting your site on WPEngine or a provider which performs server caching, you will need to ask the host support people to NOT cache your renamed login page." +msgstr "" + +#: dist/templates/wp-admin/brute-force/rename-login.php:38 +msgid "Enable rename login page feature" +msgstr "" + +#: dist/templates/wp-admin/brute-force/rename-login.php:41 +msgid "Enable this if you want the rename login page feature" +msgstr "" + +#: dist/templates/wp-admin/brute-force/rename-login.php:46 +msgid "Login page URL" +msgstr "" + +#: dist/templates/wp-admin/brute-force/rename-login.php:48 +msgid "Enter a string which will represent your secure login page slug." +msgstr "" + +#: dist/templates/wp-admin/brute-force/rename-login.php:48 +msgid "You are encouraged to choose something which is hard to guess and only you will remember." +msgstr "" + +#: dist/templates/wp-admin/dashboard/debug-logs.php:4 +msgid "Debug log options" +msgstr "" + +#: dist/templates/wp-admin/dashboard/debug-logs.php:7 +msgid "Clear logs" +msgstr "" + +#: dist/templates/wp-admin/dashboard/debug-logs.php:7 +msgid "Are you sure you want to clear all the debug logs?" +msgstr "" + +#: dist/templates/wp-admin/dashboard/debug-logs.php:13 +msgid "Debug logs" +msgstr "" + +#: dist/templates/wp-admin/dashboard/debug-logs.php:24 +msgid "This section displays information valuable for diagnosing conflicts, configuration discrepancies, or compatibility concerns with other plugins, themes, or the hosting environment." +msgstr "" + +#: dist/templates/wp-admin/dashboard/debug-logs.php:25 +msgid "You can use this information to help troubleshoot issues you may be experiencing with your WordPress site or send a report to the AIOS team." +msgstr "" + +#: dist/templates/wp-admin/dashboard/debug-logs.php:36 +msgid "Copy/send report" +msgstr "" + +#: dist/templates/wp-admin/dashboard/debug-logs.php:39 +msgid "All-In-One Security diagnostics report" +msgstr "" + +#: dist/templates/wp-admin/dashboard/debug-logs.php:40 +msgid "Copy to clipboard" +msgstr "" + +#: dist/templates/wp-admin/dashboard/locked-ip.php:5 +msgid "This tab displays the list of all IP addresses which are currently temporarily locked out." +msgstr "" + +#: dist/templates/wp-admin/dashboard/locked-ip.php:9 +msgid "Currently locked out IP addresses and ranges" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:5 +msgid "All-In-One Security Free vs Premium Comparison Chart" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:7 +msgid "FAQs" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:9 +msgid "Ask a pre-sales question" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:18 +msgid "All-In-One Security Free" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:19 +msgid "Free" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:30, dist/templates/wp-admin/dashboard/may-also-like.php:136, dist/templates/wp-admin/dashboard/may-also-like.php:247, dist/templates/wp-admin/dashboard/may-also-like.php:292 +msgid "Installed" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:33, dist/templates/wp-admin/dashboard/may-also-like.php:139, dist/templates/wp-admin/dashboard/may-also-like.php:250, dist/templates/wp-admin/dashboard/may-also-like.php:295 +msgid "Upgrade" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:38 +msgid "Login security feature suite" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:39 +msgid "Upgrade your WordPress security and protect against brute-force attacks with login and user security features." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:39 +msgid "Limit login attempts, rename the login page to hide it from bots, add CAPTCHA and more." +msgstr "" + +#. translators: %s: Features URL +#: dist/templates/wp-admin/dashboard/may-also-like.php:42, dist/templates/wp-admin/dashboard/may-also-like.php:148, dist/templates/wp-admin/dashboard/may-also-like.php:163 +msgid "%s" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:42 +msgid "See all login security features" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:45, dist/templates/wp-admin/dashboard/may-also-like.php:48, dist/templates/wp-admin/dashboard/may-also-like.php:61, dist/templates/wp-admin/dashboard/may-also-like.php:64, dist/templates/wp-admin/dashboard/may-also-like.php:72, dist/templates/wp-admin/dashboard/may-also-like.php:75, dist/templates/wp-admin/dashboard/may-also-like.php:86, dist/templates/wp-admin/dashboard/may-also-like.php:97, dist/templates/wp-admin/dashboard/may-also-like.php:108, dist/templates/wp-admin/dashboard/may-also-like.php:119, dist/templates/wp-admin/dashboard/may-also-like.php:130, dist/templates/wp-admin/dashboard/may-also-like.php:151, dist/templates/wp-admin/dashboard/may-also-like.php:154, dist/templates/wp-admin/dashboard/may-also-like.php:166, dist/templates/wp-admin/dashboard/may-also-like.php:169, dist/templates/wp-admin/dashboard/may-also-like.php:178, dist/templates/wp-admin/dashboard/may-also-like.php:181, dist/templates/wp-admin/dashboard/may-also-like.php:197, dist/templates/wp-admin/dashboard/may-also-like.php:208, dist/templates/wp-admin/dashboard/may-also-like.php:219, dist/templates/wp-admin/dashboard/may-also-like.php:230, dist/templates/wp-admin/dashboard/may-also-like.php:241, dist/templates/wp-admin/dashboard/may-also-like.php:262, dist/templates/wp-admin/dashboard/may-also-like.php:274, dist/templates/wp-admin/dashboard/may-also-like.php:286 +msgid "Yes" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:53 +msgid "Two-factor authentication (TFA)" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:58 +msgid "Supports Google Authenticator, Microsoft Authenticator, Authy and more." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:69 +msgid "Configure TFA by user role." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:80 +msgid "Control how often TFA is required on trusted devices." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:91 +msgid "Adjust the TFA design to match your brand." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:102 +msgid "Generate one-time use emergency codes to regain access if you lose your TFA device." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:113 +msgid "TFA works consistently in subsites of WordPress multisite networks." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:124 +msgid "Integrate TFA with third party login forms without additional coding." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:145 +msgid "Get PHP, .htaccess and 6G firewall rules." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:145 +msgid "Spot and block fake Google Bots and more!" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:148 +msgid "See all firewall features" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:159 +msgid "File and database security" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:160 +msgid "Block access to files like readme.html to hide key information from hackers." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:160 +msgid "Hide your WordPress database, scan critical folders and files to spot and fix insecure file permissions and more." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:163 +msgid "See all file and database security features" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:175 +msgid "Prevent annoying spam comments and reduce unnecessary server load." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:175 +msgid "Automatically and permanently block IP addresses that exceed a set number of spam comments." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:186 +msgid "Site Scanner" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:191 +msgid "Monitors and alerts you to file changes outside of normal operations." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:202 +msgid "Monitors and alerts you to infection by malware" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:213 +msgid "Monitors and alerts you to blacklisting by search engines." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:224 +msgid "Monitors and alerts you to downtime." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:235 +msgid "Monitors and alerts you to response time issues." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:255 +msgid "Smart 404 blocking" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:256 +msgid "Automatically block IP addresses based on how many 404 errors they generate." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:256 +msgid "Handy charts show how many 404s have occurred and where they’re coming from." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:267 +msgid "Country blocking" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:268 +msgid "Most attacks come from a handful of countries." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:268 +msgid "Prevent most of them by blocking traffic based on country of origin to 99.5% accuracy." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:279 +msgid "Premium support" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:280 +msgid "We can do more to support you via our own support channels than is allowed in the WordPress forums." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:280 +msgid "90% of tickets are responded to within 24 hours." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:303 +msgid "Our other plugins" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:323 +msgid "UpdraftPlus – the ultimate protection for your site, hard work and business" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:324 +msgid "Simplifies backups and restoration." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:324 +msgid "It is the world's highest ranking and most popular scheduled backup plugin, with over three million currently-active installs." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:325 +msgid "Learn more about UpdraftPlus" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:329 +msgid "WP-Optimize – keep your database fast and efficient" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:330 +msgid "Makes your site fast and efficient." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:330 +msgid "It cleans the database, compresses images and caches pages for ultimate speed." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:331 +msgid "Learn more about WP-Optimize" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:335 +msgid "UpdraftCentral – save hours managing multiple WP sites from one place" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:336 +msgid "Highly efficient way to manage, optimize, update and backup multiple websites from one place." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:337 +msgid "Learn more about UpdraftCentral" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:341 +msgid "Easy Updates Manager - keep your WordPress site up to date and bug free" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:344 +msgid "A light yet powerful plugin that allows you to manage all kinds of updates." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:345 +msgid "With a huge number of settings for endless customization." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:346 +msgid "Easy Updates Manager is an obvious choice for anyone wanting to take control of their website updates." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:350, dist/templates/wp-admin/dashboard/may-also-like.php:366, dist/templates/wp-admin/dashboard/may-also-like.php:381, dist/templates/wp-admin/dashboard/may-also-like.php:394 +msgid "Try for free" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:355 +msgid "Internal Link Juicer - a five-star rated internal linking plugin for WordPress" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:359 +msgid "This five-star rated plugin automates internal linking." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:360 +msgid "It strategically places relevant links within your content." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:364 +msgid "Improve your SEO with just a few clicks." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:370 +msgid "WP Overnight - quality plugins for your WooCommerce store. 5 star rated invoicing, order and product management tools" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:373 +msgid "WP Overnight is an independent plugin shop with a range of WooCommerce plugins." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:374 +msgid "Our range of plugins have over 7,500,000 downloads and thousands of loyal customers." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:378, dist/templates/wp-admin/dashboard/may-also-like.php:379 +msgid "Create PDF invoices, automations, barcodes, reports and so much more." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:385 +msgid "WPGetAPI - connect WordPress to APIs without a developer" +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:389 +msgid "The easiest way to connect your WordPress website to an external API." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:390 +msgid "WPGetAPI is free, powerful and easy to use." +msgstr "" + +#: dist/templates/wp-admin/dashboard/may-also-like.php:391 +msgid "Connect to virtually any REST API and retrieve data without writing a line of code." +msgstr "" + +#: dist/templates/wp-admin/dashboard/permanent-block.php:4 +msgid "This tab displays the list of all permanently blocked IP addresses." +msgstr "" + +#: dist/templates/wp-admin/dashboard/permanent-block.php:4 +msgid "NOTE: This feature does NOT use the .htaccess file to permanently block the IP addresses so it should be compatible with all web servers running WordPress." +msgstr "" + +#: dist/templates/wp-admin/dashboard/permanent-block.php:8 +msgid "Permanently blocked IP addresses" +msgstr "" + +#: dist/templates/wp-admin/database-security/database-backup.php:3 +msgid "Manual backup" +msgstr "" + +#: dist/templates/wp-admin/database-security/database-backup.php:10, dist/templates/wp-admin/database-security/database-backup.php:10 +msgid "UpdraftPlus Backup/Restore" +msgstr "" + +#: dist/templates/wp-admin/database-security/database-backup.php:10 +msgid "Your backups are on the UpdraftPlus Backup/Restore admin page." +msgstr "" + +#: dist/templates/wp-admin/database-security/database-backup.php:12 +msgid "Create database backup now" +msgstr "" + +#: dist/templates/wp-admin/database-security/database-backup.php:21 +msgid "Automated scheduled backups" +msgstr "" + +#: dist/templates/wp-admin/database-security/database-backup.php:26 +msgid "Automate backup in the UpdraftPlus plugin" +msgstr "" + +#: dist/templates/wp-admin/database-security/database-backup.php:29 +msgid "The automated backup feature in All-In-One Security was removed as of version 5.0.0." +msgstr "" + +#: dist/templates/wp-admin/database-security/database-backup.php:29 +msgid "For a reliable backup solution, we recommend" +msgstr "" + +#: dist/templates/wp-admin/database-security/database-prefix.php:2, dist/templates/wp-admin/database-security/database-prefix.php:55 +msgid "Change database prefix" +msgstr "" + +#: dist/templates/wp-admin/database-security/database-prefix.php:5 +msgid "Your WordPress database is the most important asset of your website because it contains a lot of your site's precious information." +msgstr "" + +#: dist/templates/wp-admin/database-security/database-prefix.php:5 +msgid "The database is also a target for hackers via methods such as SQL injections and malicious and automated code which targets certain tables." +msgstr "" + +#: dist/templates/wp-admin/database-security/database-prefix.php:5 +msgid "One way to add a layer of protection for your DB is to change the default WordPress table prefix from \"wp_\" to something else which will be difficult for hackers to guess." +msgstr "" + +#: dist/templates/wp-admin/database-security/database-prefix.php:5 +msgid "This feature allows you to easily change the prefix to a value of your choice or to a random value set by this plugin." +msgstr "" + +#: dist/templates/wp-admin/database-security/database-prefix.php:9 +msgid "Database prefix options" +msgstr "" + +#: dist/templates/wp-admin/database-security/database-prefix.php:19 +msgid "database backup" +msgstr "" + +#. translators: %s: Backup link. +#: dist/templates/wp-admin/database-security/database-prefix.php:21 +msgid "It is recommended that you perform a %s before using this feature" +msgstr "" + +#: dist/templates/wp-admin/database-security/database-prefix.php:30 +msgid "Current database table prefix" +msgstr "" + +#: dist/templates/wp-admin/database-security/database-prefix.php:36 +msgid "Your site is currently using the default WordPress database prefix value of \"wp_\"." +msgstr "" + +#: dist/templates/wp-admin/database-security/database-prefix.php:36 +msgid "To increase your site's security you should consider changing the database prefix value to another value." +msgstr "" + +#: dist/templates/wp-admin/database-security/database-prefix.php:43 +msgid "Generate new database table prefix" +msgstr "" + +#: dist/templates/wp-admin/database-security/database-prefix.php:47 +msgid "Enable this if you want the plugin to generate a random 6 character string for the table prefix" +msgstr "" + +#: dist/templates/wp-admin/database-security/database-prefix.php:48 +msgid "OR" +msgstr "" + +#: dist/templates/wp-admin/database-security/database-prefix.php:50 +msgid "Choose your own database prefix by specifying a string which contains letters and/or numbers and/or underscores, example: xyz_" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/copy-protection.php:3 +msgid "Disable the ability to copy text" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/copy-protection.php:14 +msgid "This feature allows you to disable the ability to select and copy text from your front end." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/copy-protection.php:15 +msgid "When admin user is logged in, the feature is automatically disabled for his session." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/copy-protection.php:20 +msgid "Enable copy protection" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/copy-protection.php:23 +msgid "Enable this to disable the \"Right click\", \"Text selection\" and \"Copy\" options on the front end of your site." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/copy-protection.php:29 +msgid "Save copy protection settings" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/file-permissions.php:2 +msgid "File permissions scan" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/file-permissions.php:5 +msgid "Your WordPress file and folder permission settings govern the accessibility and read/write privileges of the files and folders which make up your WP installation." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/file-permissions.php:5 +msgid "Your WP installation already comes with reasonably secure file permission settings for the filesystem." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/file-permissions.php:5 +msgid "However, sometimes people or other plugins modify the various permission settings of certain core WP folders or files such that they end up making their site less secure because they chose the wrong permission values." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/file-permissions.php:5 +msgid "This feature will scan the critical WP core folders and files and will highlight any permission settings which are insecure." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/file-permissions.php:19 +msgid "WP directory and file permissions scan results" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/file-permissions.php:12 +msgid "This plugin has detected that your site is running on a Windows server." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/file-permissions.php:13 +msgid "This feature is not applicable for Windows server installations." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/file-protection.php:5 +msgid "These features allow you to protect your files and assets." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/file-protection.php:6 +msgid "By protecting your files and assets, you can help prevent nefarious users gain key information and protect your server's resources." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/file-protection.php:14, dist/templates/wp-admin/filesystem-security/partials/wp-file-access.php:3 +msgid "Delete default WP files" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/file-protection.php:17, dist/templates/wp-admin/filesystem-security/partials/prevent-hotlinks.php:3 +msgid "Prevent hotlinking" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/file-protection.php:20, dist/templates/wp-admin/filesystem-security/partials/php-file-editing.php:3 +msgid "Disable PHP file editing" +msgstr "" + +#. translators: %s: File path. +#: dist/templates/wp-admin/filesystem-security/filesystem-log-result.php:20 +msgid "The file %s could not be read" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/filesystem-log-result.php:7 +msgid "Showing latest entries for file: %s" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/frames.php:4 +msgid "Prevent your site from being displayed in a frame" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/frames.php:15 +msgid "This feature allows you to prevent other sites from displaying any of your content via a frame or iframe." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/frames.php:16 +msgid "When enabled, this feature will set the \"X-Frame-Options\" parameter to \"sameorigin\" in the HTTP header." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/frames.php:24 +msgid "Enable this to stop other sites from displaying your content in a frame or iframe." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/host-system-logs.php:2 +msgid "System logs" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/host-system-logs.php:5 +msgid "Sometimes your hosting platform will produce error or warning logs in a file called \"error_log\"." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/host-system-logs.php:5 +msgid "Depending on the nature and cause of the error or warning, your hosting server can create multiple instances of this file in numerous directory locations of your WordPress installation." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/host-system-logs.php:5 +msgid "By occasionally viewing the contents of these logs files you can keep informed of any underlying problems on your system which you might need to address." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/host-system-logs.php:11 +msgid "View system logs" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/host-system-logs.php:13 +msgid "Please press the button below to view the latest system logs" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/host-system-logs.php:17 +msgid "Enter System Log File Name" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/host-system-logs.php:19 +msgid "Enter your system log file name. (Defaults to error_log)" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/host-system-logs.php:22 +msgid "View latest system logs" +msgstr "" + +#: dist/templates/wp-admin/firewall/5g.php:2 +msgid "Firewall settings" +msgstr "" + +#: dist/templates/wp-admin/firewall/5g.php:5 +msgid "5G firewall settings" +msgstr "" + +#: dist/templates/wp-admin/firewall/5g.php:8 +msgid "This feature is marked for deprecation and will be removed in a future version of the plugin." +msgstr "" + +#: dist/templates/wp-admin/firewall/5g.php:13 +msgid "Enable legacy 5G firewall protection" +msgstr "" + +#: dist/templates/wp-admin/firewall/5g.php:16 +msgid "Enable this to apply the 5G firewall protection from perishablepress.com to your site." +msgstr "" + +#: dist/templates/wp-admin/firewall/5g.php:20 +msgid "This setting will implement the 5G security firewall protection mechanisms on your site which include the following things:" +msgstr "" + +#: dist/templates/wp-admin/firewall/5g.php:21, dist/templates/wp-admin/firewall/partials/ng.php:33 +msgid "1) Block forbidden characters commonly used in exploitative attacks." +msgstr "" + +#: dist/templates/wp-admin/firewall/5g.php:22, dist/templates/wp-admin/firewall/partials/ng.php:34 +msgid "2) Block malicious encoded URL characters such as the \".css(\" string." +msgstr "" + +#: dist/templates/wp-admin/firewall/5g.php:23, dist/templates/wp-admin/firewall/partials/ng.php:35 +msgid "3) Guard against the common patterns and specific exploits in the root portion of targeted URLs." +msgstr "" + +#: dist/templates/wp-admin/firewall/5g.php:24, dist/templates/wp-admin/firewall/partials/ng.php:36 +msgid "4) Stop attackers from manipulating query strings by disallowing illicit characters." +msgstr "" + +#: dist/templates/wp-admin/firewall/5g.php:25, dist/templates/wp-admin/firewall/partials/ng.php:37 +msgid "....and much more." +msgstr "" + +#: dist/templates/wp-admin/firewall/5g.php:34 +msgid "Save 5G firewall settings" +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:2 +msgid "Ban IPs or user agents" +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:5 +msgid "The All-In-One Security blacklist feature gives you the option of banning certain host IP addresses or ranges and also user agents." +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:6 +msgid "This feature will deny total site access for users which have IP addresses or user agents matching those which you have configured in the settings below." +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:7 +msgid "Black-listed visitors will be blocked as soon as WordPress loads, preventing them from gaining any further access." +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:18 +msgid "This plugin adds a number of extra features including %s and %s." +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:26 +msgid "IP hosts and user agent blacklist settings" +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:38 +msgid "please read the following message" +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:39 +msgid "You %s before activating this feature." +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:45 +msgid "Enable IP or user agent blacklisting" +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:48 +msgid "Enable this if you want the banning (or blacklisting) of selected IP addresses and/or user agents specified in the settings below" +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:53, dist/templates/wp-admin/firewall/partials/allowlist.php:13 +msgid "Enter IP addresses:" +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:57, dist/templates/wp-admin/firewall/partials/allowlist.php:13 +msgid "Enter one or more IP addresses or IP ranges." +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:62 +msgid "Enter user agents:" +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:67 +msgid "Enter one or more user agent strings." +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:68, dist/templates/wp-admin/firewall/partials/upgrade-unsafe-http-calls.php:35 +msgid "More Info" +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:71 +msgid "The user agent string will be checked in a case-insensitive manner." +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:72 +msgid "Each user agent string must be on a new line." +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:73 +msgid "Example 1 - A single user agent string to block:" +msgstr "" + +#: dist/templates/wp-admin/firewall/block-and-allow-lists.php:75 +msgid "Example 2 - A list of more than 1 user agent strings to block" +msgstr "" + +#: dist/templates/wp-admin/firewall/htaccess-firewall-rules.php:2 +msgid ".htaccess firewall settings" +msgstr "" + +#: dist/templates/wp-admin/firewall/htaccess-firewall-rules.php:8, dist/templates/wp-admin/firewall/partials/basic-firewall-settings.php:3 +msgid "Basic firewall settings" +msgstr "" + +#: dist/templates/wp-admin/firewall/htaccess-firewall-rules.php:11 +msgid "Block debug log" +msgstr "" + +#: dist/templates/wp-admin/firewall/htaccess-firewall-rules.php:14 +msgid "Listing directory content" +msgstr "" + +#: dist/templates/wp-admin/firewall/htaccess-firewall-rules.php:25, dist/templates/wp-admin/firewall/php-firewall-rules.php:48 +msgid "Rules" +msgstr "" + +#: dist/templates/wp-admin/firewall/htaccess-firewall-rules.php:56 +msgid "Save .htaccess firewall settings" +msgstr "" + +#: dist/templates/wp-admin/firewall/php-firewall-rules.php:3 +msgid "PHP firewall settings" +msgstr "" + +#: dist/templates/wp-admin/firewall/php-firewall-rules.php:9 +msgid "Security enhancements" +msgstr "" + +#: dist/templates/wp-admin/firewall/php-firewall-rules.php:13 +msgid "Feed control" +msgstr "" + +#: dist/templates/wp-admin/firewall/php-firewall-rules.php:17 +msgid "Comment protection" +msgstr "" + +#: dist/templates/wp-admin/firewall/php-firewall-rules.php:21 +msgid "URL security" +msgstr "" + +#: dist/templates/wp-admin/firewall/php-firewall-rules.php:25 +msgid "String filtering" +msgstr "" + +#: dist/templates/wp-admin/firewall/php-firewall-rules.php:29 +msgid "nG firewall rules" +msgstr "" + +#: dist/templates/wp-admin/firewall/php-firewall-rules.php:33 +msgid "WP REST API" +msgstr "" + +#: dist/templates/wp-admin/firewall/php-firewall-rules.php:36, dist/templates/wp-admin/firewall/partials/internet-bots.php:3 +msgid "Internet bot settings" +msgstr "" + +#: dist/templates/wp-admin/firewall/php-firewall-rules.php:79 +msgid "Save PHP firewall settings" +msgstr "" + +#. translators: 1: Old location 2: New location +#: dist/templates/wp-admin/general/moved.php:24 +msgid "The %1$s feature is now located %2$s." +msgstr "" + +#: dist/templates/wp-admin/general/moved.php:24 +msgid "This page will be removed in a future release." +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:5 +msgid "View the scan results and clear this message" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:10 +msgid "If given an opportunity hackers can insert their code or files into your system which they can then use to carry out malicious acts on your site." +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:10 +msgid "Being informed of any changes in your files can be a good way to quickly prevent a hacker from causing damage to your website." +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:10 +msgid "In general, WordPress core and plugin files and file types such as \".php\" or \".js\" should not change often and when they do, it is important that you are made aware when a change occurs and which file was affected." +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:10 +msgid "The \"File Change Detection Feature\" will notify you of any file change which occurs on your system, including the addition and deletion of files by performing a regular automated or manual scan of your system's files." +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:10 +msgid "This feature also allows you to exclude certain files or folders from the scan in cases where you know that they change often as part of their normal operation. (For example log files and certain caching plugin files may change often and hence you may choose to exclude such files from the file change detection scan)" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:17 +msgid "Next file scan" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:31 +msgid "Previous file scan results" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:39 +msgid "No previous scan results" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:37 +msgid "View the last file scan results" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:50 +msgid "Time now" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:55 +msgid "Scan now" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:56 +msgid "or schedule regular file scans below." +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:65 +msgid "File change detection settings" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:76 +msgid "Enable automated file change detection scan" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:79 +msgid "Enable this if you want the system to automatically and periodically scan your files to check for file changes based on the settings below" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:84 +msgid "Scan time interval" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:87 +msgid "Hours" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:88 +msgid "Days" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:89 +msgid "Weeks" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:91 +msgid "Set the value for how often you would like a scan to occur" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:95 +msgid "File types to ignore" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:99 +msgid "Enter each file type or extension on a new line which you wish to exclude from the file change detection scan." +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:103 +msgid "You can exclude file types from the scan which would not normally pose any security threat if they were changed." +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:103 +msgid "These can include things such as image files." +msgstr "" + +#. translators: 1. JPG, 2. PNG, 3. BMP. +#: dist/templates/wp-admin/scanner/file-change-detect.php:105 +msgid "Example: If you want the scanner to ignore files of type %1$s, %2$s, and %3$s, then you would enter the following:" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:114 +msgid "Files/Directories to ignore" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:118 +msgid "Enter each file or directory on a new line which you wish to exclude from the file change detection scan." +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:122 +msgid "You can exclude specific files/directories from the scan which would not normally pose any security threat if they were changed." +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:122 +msgid "These can include things such as log files." +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:123 +msgid "Example: If you want the scanner to ignore certain files in different directories or whole directories, then you would enter the following:" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:125 +msgid "somedirectory" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:132 +msgid "Send email when change detected" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:136 +msgid "Enable this if you want the system to email you if a file change was detected" +msgstr "" + +#: dist/templates/wp-admin/scanner/file-change-detect.php:141 +msgid "Enter one or more email addresses on a new line." +msgstr "" + +#: dist/templates/wp-admin/scanner/malware-scan.php:4 +msgid "What is malware?" +msgstr "" + +#: dist/templates/wp-admin/scanner/malware-scan.php:5 +msgid "The word malware stands for malicious software." +msgstr "" + +#: dist/templates/wp-admin/scanner/malware-scan.php:5 +msgid "It can consist of things like trojan horses, adware, worms, spyware and any other undesirable code which a hacker will try to inject into your website." +msgstr "" + +#: dist/templates/wp-admin/scanner/malware-scan.php:5 +msgid "Often when malware code has been inserted into your site you will normally not notice anything out of the ordinary based on appearances, but it can have a dramatic effect on your site's search ranking." +msgstr "" + +#: dist/templates/wp-admin/scanner/malware-scan.php:5 +msgid "This is because the bots and spiders from search engines such as Google have the capability to detect malware when they are indexing the pages on your site, and consequently they can blacklist your website which will in turn affect your search rankings." +msgstr "" + +#: dist/templates/wp-admin/scanner/malware-scan.php:9 +msgid "Scanning for malware" +msgstr "" + +#: dist/templates/wp-admin/scanner/malware-scan.php:10 +msgid "Due to the constantly changing and complex nature of Malware, scanning for such things using a standalone plugin will not work reliably." +msgstr "" + +#: dist/templates/wp-admin/scanner/malware-scan.php:10 +msgid "This is something best done via an external scan of your site regularly." +msgstr "" + +#: dist/templates/wp-admin/scanner/malware-scan.php:10 +msgid "This is why we have created an easy-to-use scanning service which is hosted off our own server which will scan your site for malware weekly and notify you if it finds anything." +msgstr "" + +#: dist/templates/wp-admin/scanner/malware-scan.php:11 +msgid "This service is included with the premium plugin and provides the following:" +msgstr "" + +#: dist/templates/wp-admin/scanner/malware-scan.php:13 +msgid "Automatic weekly scans" +msgstr "" + +#: dist/templates/wp-admin/scanner/malware-scan.php:14 +msgid "Automatic malware and blacklist monitoring" +msgstr "" + +#: dist/templates/wp-admin/scanner/malware-scan.php:15 +msgid "Automatic email alerting" +msgstr "" + +#: dist/templates/wp-admin/scanner/malware-scan.php:16 +msgid "Site uptime monitoring" +msgstr "" + +#: dist/templates/wp-admin/scanner/malware-scan.php:17 +msgid "Site response time monitoring" +msgstr "" + +#: dist/templates/wp-admin/scanner/malware-scan.php:18 +msgid "We provide advice for malware cleanup" +msgstr "" + +#: dist/templates/wp-admin/scanner/malware-scan.php:19 +msgid "Blacklist removal" +msgstr "" + +#: dist/templates/wp-admin/scanner/malware-scan.php:20 +msgid "No contract (cancel anytime)" +msgstr "" + +#. translators: %s: Scanner URL. +#: dist/templates/wp-admin/scanner/malware-scan.php:23 +msgid "Learn more %s." +msgstr "" + +#: dist/templates/wp-admin/scanner/scan-result.php:3 +msgid "Latest file change scan results" +msgstr "" + +#: dist/templates/wp-admin/scanner/scan-result.php:8 +msgid "The following files were added to your website." +msgstr "" + +#: dist/templates/wp-admin/scanner/scan-result.php:9 +msgid "The following files were removed from your website." +msgstr "" + +#: dist/templates/wp-admin/scanner/scan-result.php:10 +msgid "The following files were changed on your website." +msgstr "" + +#: dist/templates/wp-admin/scanner/scan-result.php:20 +msgid "File" +msgstr "" + +#: dist/templates/wp-admin/scanner/scan-result.php:21 +msgid "File size" +msgstr "" + +#: dist/templates/wp-admin/scanner/scan-result.php:22 +msgid "File modified" +msgstr "" + +#: dist/templates/wp-admin/settings/advanced-settings.php:4 +msgid "IP address detection settings" +msgstr "" + +#: dist/templates/wp-admin/settings/advanced-settings.php:8 +msgid "The IP address detection settings allow you to specify how visitors' IP addresses are made known to PHP (and hence to WordPress and its plugins)." +msgstr "" + +#: dist/templates/wp-admin/settings/advanced-settings.php:9 +msgid "Usually, this is automatic and there is only one choice." +msgstr "" + +#: dist/templates/wp-admin/settings/advanced-settings.php:10 +msgid "However in some setups, such as those using proxies (including load-balancers and security firewalls like Cloudflare), it may be necessary to set this manually." +msgstr "" + +#: dist/templates/wp-admin/settings/advanced-settings.php:11, dist/templates/wp-admin/firewall/partials/fake-googlebots.php:12 +msgid "Attention" +msgstr "" + +#: dist/templates/wp-admin/settings/advanced-settings.php:11 +msgid "It is important to set this correctly - otherwise you may make it possible for a hacker to ban all your visitors (e.g. via banning Cloudflare from connecting to you) instead of the hacker being banned." +msgstr "" + +#: dist/templates/wp-admin/settings/advanced-settings.php:11 +msgid "The default is to use the REMOTE_ADDR PHP server variable." +msgstr "" + +#: dist/templates/wp-admin/settings/advanced-settings.php:11 +msgid "If this variable does not contain the visitor's IP address, then whilst you can make a different selection below, it is better to ask your web hosting company to have it correctly set." +msgstr "" + +#: dist/templates/wp-admin/settings/advanced-settings.php:12 +msgid "This is the most secure setup, because when set correctly it is immune from being spoofed by an attacker." +msgstr "" + +#: dist/templates/wp-admin/settings/advanced-settings.php:18 +msgid "You have no available IP address detection method(s); you must contact your web hosting company." +msgstr "" + +#. translators: %s: Cloudflare +#. translators: %s: IPIFY IPv4 +#. translators: %s: IPIFY IPv6 +#: dist/templates/wp-admin/settings/advanced-settings.php:25, dist/templates/wp-admin/settings/advanced-settings.php:31, dist/templates/wp-admin/settings/advanced-settings.php:37 +msgid "Your detected IP address according to %s:" +msgstr "" + +#: dist/templates/wp-admin/settings/advanced-settings.php:43 +msgid "If your site is setup on localhost, you won't see your external IP address using your server's IP detection setting; but on a localhost-served site (not available to the outside world), the setting is irrelevant and can be ignored." +msgstr "" + +#: dist/templates/wp-admin/settings/advanced-settings.php:64 +msgid "Choose a $_SERVER variable you would like to detect visitors' IP address using." +msgstr "" + +#: dist/templates/wp-admin/settings/advanced-settings.php:70 +msgid "If your chosen server variable fails the plugin will automatically fall back to retrieving the IP address from $_SERVER[\"REMOTE_ADDR\"]" +msgstr "" + +#: dist/templates/wp-admin/settings/advanced-settings.php:76 +msgid "Your IP address if using this setting:" +msgstr "" + +#: dist/templates/wp-admin/settings/advanced-settings.php:78 +msgid "fetching..." +msgstr "" + +#: dist/templates/wp-admin/settings/advanced-settings.php:92 +msgid "look-up possibly blocked by an ad-blocker or similar tool" +msgstr "" + +#: dist/templates/wp-admin/settings/delete-plugin-settings.php:3 +msgid "Manage delete plugin tasks" +msgstr "" + +#: dist/templates/wp-admin/settings/delete-plugin-settings.php:8 +msgid "NOTE: Even if these options are disabled, the plugin settings will still be inactive when the plugin is uninstalled, but they will be remembered for the next time the plugin is installed and activated." +msgstr "" + +#: dist/templates/wp-admin/settings/delete-plugin-settings.php:13 +msgid "Delete database tables" +msgstr "" + +#: dist/templates/wp-admin/settings/delete-plugin-settings.php:16 +msgid "Enable this to remove all database tables for this site when uninstalling the plugin." +msgstr "" + +#: dist/templates/wp-admin/settings/delete-plugin-settings.php:21 +msgid "Delete settings" +msgstr "" + +#: dist/templates/wp-admin/settings/delete-plugin-settings.php:24 +msgid "Enable this to remove all plugin settings for this site when uninstalling the plugin." +msgstr "" + +#: dist/templates/wp-admin/settings/delete-plugin-settings.php:27 +msgid "It will also remove all firewall rules that were added by this plugin." +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:3 +msgid "For information, updates and documentation, please visit" +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:3 +msgid "Page" +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:16 +msgid "Thank you for using the All-In-One Security plugin." +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:20 +msgid "There are a lot of security features in this plugin." +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:25 +msgid "To start, go through each security option and enable the \"basic\" options." +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:29 +msgid "The more features you enable, the more security points you will achieve." +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:32 +msgid "Before doing anything we advise taking a backup of your .htaccess file, database and wp-config.php." +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:35 +msgid "Backup your database" +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:36, dist/templates/wp-admin/settings/htaccess-file-operations.php:16 +msgid "Backup .htaccess file" +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:37, dist/templates/wp-admin/settings/wp-config-file-operations.php:16 +msgid "Backup wp-config.php file" +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:43 +msgid "Disable security features" +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:48 +msgid "If you think that some plugin functionality on your site is broken due to a security feature you enabled in this plugin, then use the following option to turn off all the security features of this plugin." +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:52 +msgid "Disable all security features" +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:58, dist/templates/wp-admin/settings/general-settings.php:67 +msgid "Disable all firewall rules" +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:63 +msgid "This feature will disable all firewall rules which are currently active in this plugin and it will also delete these rules from your .htaccess file." +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:63 +msgid "Use it if you think one of the firewall rules is causing an issue on your site." +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:73, dist/templates/wp-admin/settings/general-settings.php:87 +msgid "Reset settings" +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:78 +msgid "This feature will delete all of your settings related to the All-In-One Security plugin." +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:79 +msgid "This feature will reset/empty all the database tables of the security plugin also." +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:80 +msgid "Use this feature if you were locked out by the All-In-One Security plugin and/or you are having issues logging in when that plugin is activated." +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:81 +msgid "In addition to the settings it will also delete any directives which were added to the .htaccess file by the All-In-One Security Plugin." +msgstr "" + +#. translators: 1: Open strong tag, 2: Close strong tag. +#: dist/templates/wp-admin/settings/general-settings.php:83 +msgid "%1$sNOTE: %2$sAfter deleting the settings you will need to re-configure the All-In-One Security plugin." +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:96 +msgid "Debug settings" +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:101 +msgid "This setting allows you to enable/disable debug for this plugin." +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:106 +msgid "Enable debug" +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:109 +msgid "Enable debug mode." +msgstr "" + +#: dist/templates/wp-admin/settings/general-settings.php:109 +msgid "You should keep this option disabled after you have finished debugging the issue." +msgstr "" + +#: dist/templates/wp-admin/settings/htaccess-file-operations.php:2 +msgid ".htaccess file operations" +msgstr "" + +#: dist/templates/wp-admin/settings/htaccess-file-operations.php:5 +msgid "Your \".htaccess\" file is a key component of your website's security and it can be modified to implement various levels of protection mechanisms." +msgstr "" + +#: dist/templates/wp-admin/settings/htaccess-file-operations.php:6 +msgid "This feature allows you to backup and save your currently active .htaccess file should you need to re-use the the backed up file in the future." +msgstr "" + +#: dist/templates/wp-admin/settings/htaccess-file-operations.php:7 +msgid "You can also restore your site's .htaccess settings using a backed up .htaccess file." +msgstr "" + +#: dist/templates/wp-admin/settings/htaccess-file-operations.php:12 +msgid "Save the current .htaccess file" +msgstr "" + +#: dist/templates/wp-admin/settings/htaccess-file-operations.php:15 +msgid "Press the button below to backup and save the currently active .htaccess file." +msgstr "" + +#: dist/templates/wp-admin/settings/htaccess-file-operations.php:21 +msgid "Restore from a backed up .htaccess file" +msgstr "" + +#: dist/templates/wp-admin/settings/htaccess-file-operations.php:26 +msgid ".htaccess file to restore from" +msgstr "" + +#: dist/templates/wp-admin/settings/htaccess-file-operations.php:28 +msgid "Restore your .htaccess file" +msgstr "" + +#: dist/templates/wp-admin/settings/settings-file-operations.php:2 +msgid "Export or import your AIOS settings" +msgstr "" + +#: dist/templates/wp-admin/settings/settings-file-operations.php:5 +msgid "This section allows you to export or import your All-In-One Security settings." +msgstr "" + +#: dist/templates/wp-admin/settings/settings-file-operations.php:6 +msgid "This can be handy if you wanted to save time by applying the settings from one site to another site." +msgstr "" + +#: dist/templates/wp-admin/settings/settings-file-operations.php:7 +msgid "NOTE: Before importing, it is your responsibility to know what settings you are trying to import." +msgstr "" + +#: dist/templates/wp-admin/settings/settings-file-operations.php:7 +msgid "Importing settings blindly can cause you to be locked out of your site." +msgstr "" + +#: dist/templates/wp-admin/settings/settings-file-operations.php:8 +msgid "For Example: If a settings item relies on the domain URL then it may not work correctly when imported into a site with a different domain." +msgstr "" + +#: dist/templates/wp-admin/settings/settings-file-operations.php:13, dist/templates/wp-admin/settings/settings-file-operations.php:21 +msgid "Export AIOS settings" +msgstr "" + +#: dist/templates/wp-admin/settings/settings-file-operations.php:18 +msgid "To export your All-In-One Security settings press the button below." +msgstr "" + +#: dist/templates/wp-admin/settings/settings-file-operations.php:26 +msgid "Import AIOS settings" +msgstr "" + +#: dist/templates/wp-admin/settings/settings-file-operations.php:31 +msgid "Use this section to import your All-In-One Security settings from a file." +msgstr "" + +#: dist/templates/wp-admin/settings/settings-file-operations.php:33 +msgid "Settings file to restore from" +msgstr "" + +#: dist/templates/wp-admin/settings/settings-file-operations.php:36 +msgid "Select your import settings file" +msgstr "" + +#: dist/templates/wp-admin/settings/wp-config-file-operations.php:2 +msgid "wp-config.php file operations" +msgstr "" + +#: dist/templates/wp-admin/settings/wp-config-file-operations.php:5 +msgid "Your \"wp-config.php\" file is one of the most important files in your WordPress installation." +msgstr "" + +#: dist/templates/wp-admin/settings/wp-config-file-operations.php:5 +msgid "It is a primary configuration file and contains crucial things such as details of your database and other critical components." +msgstr "" + +#: dist/templates/wp-admin/settings/wp-config-file-operations.php:6 +msgid "This feature allows you to backup and save your currently active wp-config.php file should you need to re-use the the backed up file in the future." +msgstr "" + +#: dist/templates/wp-admin/settings/wp-config-file-operations.php:7 +msgid "You can also restore your site's wp-config.php settings using a backed up wp-config.php file." +msgstr "" + +#: dist/templates/wp-admin/settings/wp-config-file-operations.php:12 +msgid "Save the current wp-config.php file" +msgstr "" + +#: dist/templates/wp-admin/settings/wp-config-file-operations.php:15 +msgid "Press the button below to backup and download the contents of the currently active wp-config.php file." +msgstr "" + +#: dist/templates/wp-admin/settings/wp-config-file-operations.php:21 +msgid "Restore from a backed up wp-config file" +msgstr "" + +#: dist/templates/wp-admin/settings/wp-config-file-operations.php:26 +msgid "wp-config file to restore from" +msgstr "" + +#: dist/templates/wp-admin/settings/wp-config-file-operations.php:28 +msgid "Restore your wp-config file" +msgstr "" + +#: dist/templates/wp-admin/settings/wp-version-info.php:2 +msgid "WP generator meta tag and version info" +msgstr "" + +#: dist/templates/wp-admin/settings/wp-version-info.php:5 +msgid "WordPress generator automatically adds some meta information inside the \"head\" tags of every page on your site's front end, below is an example of this:" +msgstr "" + +#: dist/templates/wp-admin/settings/wp-version-info.php:7 +msgid "The above meta information shows which version of WordPress your site is currently running and thus can help hackers or crawlers scan your site to see if you have an older version of WordPress or one with a known exploit." +msgstr "" + +#: dist/templates/wp-admin/settings/wp-version-info.php:8 +msgid "There are also other ways Wordpress reveals version info such as during style and script loading, an example of this is:" +msgstr "" + +#: dist/templates/wp-admin/settings/wp-version-info.php:11 +msgid "This feature will allow you to remove the WP generator meta info and other version info from your site's pages." +msgstr "" + +#: dist/templates/wp-admin/settings/wp-version-info.php:16 +msgid "WP generator meta info" +msgstr "" + +#: dist/templates/wp-admin/settings/wp-version-info.php:27 +msgid "Remove WP generator meta info" +msgstr "" + +#: dist/templates/wp-admin/settings/wp-version-info.php:30 +msgid "Enable this if you want to remove the version and meta info produced by WP from all pages" +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:3 +msgid "Auto block spammer IPs" +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:7 +msgid "spam comment detection" +msgstr "" + +#. translators: %s: Feature URL. +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:9 +msgid "This feature has detected that %s is not active." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:9 +msgid "It is highly recommended that you activate to make the most of this feature." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:22 +msgid "This feature allows you to automatically and permanently block IP addresses which have exceeded a certain number of spam comments." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:22 +msgid "Comments are considered spam if the \"Spam comment detection\" feature is enabled or an administrator manually marks a comment as \"spam\" from the WordPress Comments menu." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:35 +msgid "Enable auto block of spam comment IPs" +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:38 +msgid "Enable this if you want this plugin to automatically block IP addresses which submit spam comments." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:43 +msgid "Minimum number of spam comments" +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:45 +msgid "Specify the minimum number of spam comments for an IP address before it is permanently blocked." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:49 +msgid "Example 1: Setting this value to \"1\" will block ALL IP addresses which were used to submit at least one spam comment." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:50 +msgid "Example 2: Setting this value to \"5\" will block only those IP addresses which were used to submit 5 spam comments or more on your site." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:67 +msgid "List spammer IP addresses" +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:71 +msgid "This section displays a list of the IP addresses of the people or bots who have left spam comments on your site." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:71 +msgid "This information can be handy for identifying the most persistent IP addresses or ranges used by spammers." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:71 +msgid "By inspecting the IP address data coming from spammers you will be in a better position to determine which addresses or address ranges you should block by adding them to the permanent block list." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:71 +msgid "To add one or more of the IP addresses displayed in the table below to your blacklist, simply press the \"Block\" link for the individual row or select more than one address using the checkboxes and then choose the \"block\" option from the Bulk Actions dropdown list and press the \"Apply\" button." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:77 +msgid "Minimum number of spam comments per IP" +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:80 +msgid "This field allows you to list only those IP addresses which have been used to post X or more spam comments." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:84 +msgid "Example 1: Setting this value to \"1\" will list ALL IP addresses which were used to submit at least 1 spam comment." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:85 +msgid "Example 2: Setting this value to \"5\" will list only those IP addresses which were used to submit 5 spam comments or more on your site." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:91 +msgid "Find IP addresses" +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:96 +msgid "Spammer IP address results" +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:101 +msgid "Only the \"superadmin\" can block IP addresses from the main site." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php:101 +msgid "Take note of the IP addresses you want blocked and ask the superadmin to add these to the blacklist using the \"Blacklist Manager\" on the main site." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:2 +msgid "Comment spam settings" +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:6 +msgid "Spam comment detect" +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:10 +msgid "A large portion of WordPress blog comment spam is produced by automated bots rather than by humans." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:10 +msgid "This feature will reduce the useless and unnecessary traffic and load on your server resulting from spam comments." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:10 +msgid "In other words, if the comment was not submitted by a human, the request will be discarded or marked as spam." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:10 +msgid "This feature uses cookies and JavaScript." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:10 +msgid "If your visitors have either cookies or JavaScript disabled, their comments will automatically be discarded or marked as spam." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:21 +msgid "Detect spambots posting comments" +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:24 +msgid "Enable this if you want to detect comments originating from spambots." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:28 +msgid "This feature will detect comment attempts which originate from spambots." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:29 +msgid "A legitimate comment is one which is submitted by a human who physically fills out the comment form and presses the submit button." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:30 +msgid "A comment submitted by a spambot is done by directly calling the wp-comments-post.php file." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:31 +msgid "This feature will detect these comments and either discard them completely or mark them as spam." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:38 +msgid "Use cookies to detect comment spam" +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:41 +msgid "Using cookies may prevent caches from caching pages containing comment forms." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:45 +msgid "This feature uses cookies." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:45 +msgid "Unless your cache (e.g. Cloudflare) is configured to ignore these cookies, it may decide to not cache any of these pages." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:46 +msgid "Cloudflare detects that the set-cookie header is set and will not cache the page by default." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:54 +msgid "Comment processing" +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:59 +msgid "Spam comments detected should be" +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:63 +msgid "Discarded" +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:64 +msgid "Marked as spam" +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:66 +msgid "Select the value for how you would like a comment detected as spam to be processed" +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:71 +msgid "Trash spam comments" +msgstr "" + +#. translators: %s: Spam comments day threshold. +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:81 +msgid "Move spam comments to trash after %s days." +msgstr "" + +#: dist/templates/wp-admin/spam-prevention/comment-spam.php:89 +msgid "Enable this feature in order to move the spam comments to trash after given number of days." +msgstr "" + +#: dist/templates/wp-admin/tools/custom-htaccess.php:2 +msgid "Custom .htaccess rules settings" +msgstr "" + +#: dist/templates/wp-admin/tools/custom-htaccess.php:8 +msgid "This feature can be used to apply your own custom .htaccess rules and directives." +msgstr "" + +#: dist/templates/wp-admin/tools/custom-htaccess.php:9 +msgid "It is useful for when you want to tweak our existing firewall rules or when you want to add your own." +msgstr "" + +#: dist/templates/wp-admin/tools/custom-htaccess.php:10 +msgid "NOTE: This feature can only be used if your site is hosted using the Apache webserver, or another that uses .htaccess files." +msgstr "" + +#. translators: %s: Warning +#: dist/templates/wp-admin/tools/custom-htaccess.php:18 +msgid "%s: Only use this feature if you know what you are doing." +msgstr "" + +#: dist/templates/wp-admin/tools/custom-htaccess.php:18 +msgid "Warning" +msgstr "" + +#: dist/templates/wp-admin/tools/custom-htaccess.php:19 +msgid "Incorrect .htaccess rules or directives can break or prevent access to your site." +msgstr "" + +#: dist/templates/wp-admin/tools/custom-htaccess.php:20 +msgid "It is your responsibility to ensure that you are entering the correct code!" +msgstr "" + +#: dist/templates/wp-admin/tools/custom-htaccess.php:21 +msgid "If you break your site you will need to access your server via FTP or something similar and then edit your .htaccess file and delete the changes you made." +msgstr "" + +#: dist/templates/wp-admin/tools/custom-htaccess.php:32 +msgid "Enable custom .htaccess rules" +msgstr "" + +#: dist/templates/wp-admin/tools/custom-htaccess.php:35 +msgid "Enable this to activate the custom rules entered in the text box below" +msgstr "" + +#: dist/templates/wp-admin/tools/custom-htaccess.php:40 +msgid "Place custom rules at the top" +msgstr "" + +#: dist/templates/wp-admin/tools/custom-htaccess.php:43 +msgid "Enable this if you want to place your custom rules at the beginning of all the rules applied by this plugin" +msgstr "" + +#: dist/templates/wp-admin/tools/custom-htaccess.php:48 +msgid "Enter custom .htaccess rules:" +msgstr "" + +#: dist/templates/wp-admin/tools/custom-htaccess.php:52 +msgid "Enter your custom .htaccess rules/directives." +msgstr "" + +#: dist/templates/wp-admin/tools/custom-htaccess.php:57 +msgid "Save custom rules" +msgstr "" + +#: dist/templates/wp-admin/tools/password-tool.php:5 +msgid "Poor password selection is one of the most common weak points of many sites and is usually the first thing a hacker will try to exploit when attempting to break into your site." +msgstr "" + +#: dist/templates/wp-admin/tools/password-tool.php:6 +msgid "Many people fall into the trap of using a simple word or series of numbers as their password." +msgstr "" + +#: dist/templates/wp-admin/tools/password-tool.php:6 +msgid "Such a predictable and simple password would take a competent hacker merely minutes to guess your password by using a simple script which cycles through the easy and most common combinations." +msgstr "" + +#: dist/templates/wp-admin/tools/password-tool.php:7 +msgid "The longer and more complex your password is the harder it is for hackers to \"crack\" because more complex passwords require much greater computing power and time." +msgstr "" + +#: dist/templates/wp-admin/tools/password-tool.php:8 +msgid "This section contains a useful password strength tool which you can use to check whether your password is sufficiently strong enough." +msgstr "" + +#: dist/templates/wp-admin/tools/password-tool.php:12 +msgid "Password strength tool" +msgstr "" + +#: dist/templates/wp-admin/tools/password-tool.php:14 +msgid "This password tool uses an algorithm which calculates how long it would take for your password to be cracked using the computing power of an off-the-shelf current model desktop PC with high end processor, graphics card and appropriate password cracking software." +msgstr "" + +#: dist/templates/wp-admin/tools/password-tool.php:16 +msgid "Start typing a password." +msgstr "" + +#: dist/templates/wp-admin/tools/password-tool.php:24 +msgid "It would take a desktop PC approximately %s to crack your password!" +msgstr "" + +#: dist/templates/wp-admin/tools/password-tool.php:24, dist/templates/wp-admin/user-security/http-authentication.php:80 +msgid "1 sec" +msgstr "" + +#. translators: %s HIBP link. +#: dist/templates/wp-admin/tools/password-tool.php:26, dist/templates/wp-admin/user-security/http-authentication.php:85 +msgid "Pwned according to %s" +msgstr "" + +#: dist/templates/wp-admin/tools/visitor-lockout.php:3 +msgid "General visitor lockout" +msgstr "" + +#: dist/templates/wp-admin/tools/visitor-lockout.php:8 +msgid "This feature allows you to put your site into \"maintenance mode\" by locking down the front-end to all visitors except logged in users with super admin privileges." +msgstr "" + +#: dist/templates/wp-admin/tools/visitor-lockout.php:9 +msgid "Locking your site down to general visitors can be useful if you are investigating some issues on your site or perhaps you might be doing some maintenance and wish to keep out all traffic for security reasons." +msgstr "" + +#: dist/templates/wp-admin/tools/visitor-lockout.php:17 +msgid "Enable this if you want all visitors except those who are logged in as an administrator to be locked out of the front-end of your site." +msgstr "" + +#: dist/templates/wp-admin/tools/visitor-lockout.php:22 +msgid "Enter a message:" +msgstr "" + +#: dist/templates/wp-admin/tools/visitor-lockout.php:34 +msgid "Enter a message you wish to display to visitors when your site is in maintenance mode." +msgstr "" + +#: dist/templates/wp-admin/tools/visitor-lockout.php:39 +msgid "Save site lockout settings" +msgstr "" + +#: dist/templates/wp-admin/tools/whois-lookup.php:3 +msgid "The WHOIS lookup feature gives you a way to look up who owns an IP address or domain name." +msgstr "" + +#: dist/templates/wp-admin/tools/whois-lookup.php:3 +msgid "You can use this to investigate users engaging in malicious activity on your site." +msgstr "" + +#: dist/templates/wp-admin/tools/whois-lookup.php:6 +msgid "WHOIS lookup on IP or domain" +msgstr "" + +#: dist/templates/wp-admin/tools/whois-lookup.php:12 +msgid "IP address or domain name:" +msgstr "" + +#: dist/templates/wp-admin/tools/whois-lookup.php:19 +msgid "Look up IP or domain" +msgstr "" + +#: dist/templates/wp-admin/user-security/additional.php:4 +msgid "WordPress 5.6 introduced a new feature called \"Application passwords\"." +msgstr "" + +#: dist/templates/wp-admin/user-security/additional.php:5 +msgid "This allows you to create a token from the WordPress dashboard which then can be used in the authorization header." +msgstr "" + +#: dist/templates/wp-admin/user-security/additional.php:5 +msgid "This feature allows you to disable application passwords as they can leave your site vulnerable to social engineering and phishing scams." +msgstr "" + +#: dist/templates/wp-admin/user-security/additional.php:22 +msgid "Enable this if you want to disable the application password." +msgstr "" + +#: dist/templates/wp-admin/user-security/force-logout.php:4 +msgid "Setting an expiry period for your administration session is a simple way to protect against unauthorized access to your site from your computer." +msgstr "" + +#: dist/templates/wp-admin/user-security/force-logout.php:5 +msgid "This feature allows you to specify a time period in minutes after which the admin session will expire and the user will be forced to log back in." +msgstr "" + +#: dist/templates/wp-admin/user-security/force-logout.php:10 +msgid "Force user logout options" +msgstr "" + +#: dist/templates/wp-admin/user-security/force-logout.php:21 +msgid "Enable force user logout" +msgstr "" + +#: dist/templates/wp-admin/user-security/force-logout.php:24 +msgid "Enable this if you want to force a user to be logged out after a configured amount of time" +msgstr "" + +#: dist/templates/wp-admin/user-security/force-logout.php:29 +msgid "Logout the user after X minutes" +msgstr "" + +#: dist/templates/wp-admin/user-security/force-logout.php:31 +msgid "(Minutes) The user will be forced to log back in after this time period has elapased." +msgstr "" + +#: dist/templates/wp-admin/user-security/hibp.php:4 +msgid "%s (Have I Been Pwned?) is a website that allows people to check if their email or password has shown up in a data breach." +msgstr "" + +#: dist/templates/wp-admin/user-security/hibp.php:8 +msgid "HIBP password settings" +msgstr "" + +#: dist/templates/wp-admin/user-security/hibp.php:16 +msgid "Enforce on profile update" +msgstr "" + +#: dist/templates/wp-admin/user-security/hibp.php:19 +msgid "Enable this if you want to enforce passwords not being in the HIBP database when updating user profiles." +msgstr "" + +#: dist/templates/wp-admin/user-security/hibp.php:24 +msgid "Enforce on password reset" +msgstr "" + +#: dist/templates/wp-admin/user-security/hibp.php:27 +msgid "Enable this if you want to enforce passwords not being in the HIBP database when resetting passwords." +msgstr "" + +#: dist/templates/wp-admin/user-security/http-authentication.php:3 +msgid "The HTTP authentication feature gives you a way to add a login username and password to your site through the use of the WWW-Authenticate header." +msgstr "" + +#: dist/templates/wp-admin/user-security/http-authentication.php:3 +msgid "Only enable this feature for the frontend of your site if you don't want your site to be public." +msgstr "" + +#: dist/templates/wp-admin/user-security/http-authentication.php:5 +msgid "The username and password will only be secure if you're enforcing the use of TLS(https) on your site." +msgstr "" + +#: dist/templates/wp-admin/user-security/http-authentication.php:7 +msgid "Your site is currently using https." +msgstr "" + +#: dist/templates/wp-admin/user-security/http-authentication.php:22 +msgid "If you are locked out by the HTTP authentication feature, define the following constant %s in wp-config.php to disable the feature." +msgstr "" + +#: dist/templates/wp-admin/user-security/http-authentication.php:16 +msgid "HTTP authentication is currently disabled via the AIOS_DISABLE_HTTP_AUTHENTICATION constant (which is mostly likely to be defined in your wp-config.php)" +msgstr "" + +#: dist/templates/wp-admin/user-security/http-authentication.php:29 +msgid "Your web browser is already sending a username/password." +msgstr "" + +#: dist/templates/wp-admin/user-security/http-authentication.php:29 +msgid "If this is because you previously activated this feature then no action is required." +msgstr "" + +#: dist/templates/wp-admin/user-security/http-authentication.php:30 +msgid "However, if this is because you have HTTP authentication set up elsewhere, such as another plugin or at the webserver level, then this feature either shouldn't be activated, or should only be activated with the same username/password." +msgstr "" + +#: dist/templates/wp-admin/user-security/http-authentication.php:37 +msgid "HTTP authentication for WordPress dashboard and frontend" +msgstr "" + +#: dist/templates/wp-admin/user-security/http-authentication.php:46 +msgid "Enable for WordPress dashboard:" +msgstr "" + +#: dist/templates/wp-admin/user-security/http-authentication.php:50 +msgid "Check this if you want to protect the WordPress dashboard area of your site with HTTP authentication." +msgstr "" + +#: dist/templates/wp-admin/user-security/http-authentication.php:56 +msgid "Enable for frontend:" +msgstr "" + +#: dist/templates/wp-admin/user-security/http-authentication.php:60 +msgid "Check this if you want to protect the frontend of your site with HTTP authentication." +msgstr "" + +#: dist/templates/wp-admin/user-security/http-authentication.php:66 +msgid "Username:" +msgstr "" + +#: dist/templates/wp-admin/user-security/http-authentication.php:84 +msgid "%s to crack by a desktop PC according to the %s." +msgstr "" + +#: dist/templates/wp-admin/user-security/http-authentication.php:90 +msgid "Failure message:" +msgstr "" + +#: dist/templates/wp-admin/user-security/logged-in-users.php:3 +msgid "Refresh logged in user data" +msgstr "" + +#: dist/templates/wp-admin/user-security/logged-in-users.php:6, dist/templates/wp-admin/user-security/manual-approval.php:38 +msgid "Refresh data" +msgstr "" + +#: dist/templates/wp-admin/user-security/logged-in-users.php:12 +msgid "This tab displays all users who are currently logged into your site." +msgstr "" + +#: dist/templates/wp-admin/user-security/logged-in-users.php:13 +msgid "If you suspect there is a user or users who are logged in which should not be, you can block them by inspecting the IP addresses from the data below and adding them to your blacklist." +msgstr "" + +#: dist/templates/wp-admin/user-security/logged-in-users.php:14 +msgid "You can also instantly log them out by pressing on the \"Force logout\" link when you hover over the row in the user id column." +msgstr "" + +#: dist/templates/wp-admin/user-security/logged-in-users.php:19 +msgid "Currently logged in users" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:2 +msgid "Login lockout configuration" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:5 +msgid "Cookie-based brute force login prevention" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:6 +msgid "One of the ways hackers try to compromise sites is via a" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:6 +msgid "Brute force login attack" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:6 +msgid "This is where attackers use repeated login attempts until they guess the password." +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:7 +msgid "Apart from choosing strong passwords, monitoring and blocking IP addresses which are involved in repeated login failures in a short period of time is a very effective way to stop these types of attacks." +msgstr "" + +#. translators: %s: Brute force feature link. +#: dist/templates/wp-admin/user-security/login-lockout.php:9 +msgid "You may also want to checkout our %s feature for another secure way to protect against these types of attacks." +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:13 +msgid "Login lockout options" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:24 +msgid "Enable login lockout feature" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:27 +msgid "Enable this to turn on the login lockout feature" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:32 +msgid "Allow unlock requests" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:35 +msgid "Enable this if you want to allow users to generate an automated unlock request link which will unlock their account" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:40 +msgid "Max login attempts" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:42 +msgid "Set the value for the maximum login retries before IP address is locked out" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:46 +msgid "Login retry time period (min)" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:48 +msgid "If the maximum number of failed login attempts for a particular IP address occur within this time period the plugin will lock out that address" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:53 +msgid "Minimum lockout time length" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:59 +msgid "Set the minimum time period in minutes of lockout." +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:59 +msgid "This failed login lockout time will be tripled on each failed login." +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:66 +msgid "Maximum lockout time length" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:71 +msgid "Set the maximum time period in minutes of lockout." +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:71 +msgid "No IP address will be blocked for more than this time period after making a failed login attempt." +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:76 +msgid "Display generic error message" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:79 +msgid "Enable this if you want to show a generic error message when a login attempt fails" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:84 +msgid "Instantly lockout invalid usernames" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:87 +msgid "Enable this if you want to instantly lockout login attempts with usernames which do not exist on your system" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:93 +msgid "Instantly lockout specific usernames" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:103 +msgid "Insert one username per line." +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:103 +msgid "Existing usernames are not blocked even if present in the list." +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:108 +msgid "Notify by email" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:112 +msgid "Enable this if you want to receive an email when someone has been locked out due to maximum failed login attempts" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:116 +msgid "Fill in one email address per line." +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:120 +msgid "Each email address must be on a new line." +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:121 +msgid "If a valid email address has not been filled in, it will not be saved." +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:122 +msgid "The valid email address format is userid@example.com" +msgstr "" + +#. translators: %s: Email example. +#: dist/templates/wp-admin/user-security/login-lockout.php:124 +msgid "Example: %s" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:131 +msgid "Enable PHP backtrace in email" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:135 +msgid "Enable this if you want to include the PHP backtrace in notification emails." +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:147 +msgid "Currently locked out IP address ranges" +msgstr "" + +#. translators: %s: Locked IP link. +#: dist/templates/wp-admin/user-security/login-lockout.php:153 +msgid "To see a list of all locked IP addresses and ranges go to the %s tab in the dashboard menu." +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:159 +msgid "Login lockout IP whitelist settings" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:170 +msgid "Enable login lockout IP whitelist" +msgstr "" + +#: dist/templates/wp-admin/user-security/login-lockout.php:179 +msgid "The addresses specified here will never be blocked by the login lockout feature." +msgstr "" + +#: dist/templates/wp-admin/user-security/manual-approval.php:2 +msgid "User registration settings" +msgstr "" + +#: dist/templates/wp-admin/user-security/manual-approval.php:4 +msgid "Manually approve new registrations" +msgstr "" + +#: dist/templates/wp-admin/user-security/manual-approval.php:8 +msgid "If your site allows people to create their own accounts via the WordPress registration form, then you can minimize spam or bogus registrations by manually approving each registration." +msgstr "" + +#: dist/templates/wp-admin/user-security/manual-approval.php:9 +msgid "This feature will automatically set a newly registered account to \"pending\" until the administrator activates it." +msgstr "" + +#: dist/templates/wp-admin/user-security/manual-approval.php:9 +msgid "Therefore undesirable registrants will be unable to log in without your express approval." +msgstr "" + +#: dist/templates/wp-admin/user-security/manual-approval.php:10 +msgid "You can view all accounts which have been newly registered via the handy table below and you can also perform bulk activation/deactivation/deletion tasks on each account." +msgstr "" + +#: dist/templates/wp-admin/user-security/manual-approval.php:22 +msgid "Enable manual approval of new registrations" +msgstr "" + +#: dist/templates/wp-admin/user-security/manual-approval.php:25 +msgid "Enable this if you want to automatically disable all newly registered accounts so that you can approve them manually." +msgstr "" + +#: dist/templates/wp-admin/user-security/manual-approval.php:35 +msgid "Refresh manual approval data" +msgstr "" + +#: dist/templates/wp-admin/user-security/manual-approval.php:43 +msgid "Approve registered users" +msgstr "" + +#: dist/templates/wp-admin/user-security/salt.php:4 +msgid "Add salt postfix" +msgstr "" + +#: dist/templates/wp-admin/user-security/salt.php:15 +msgid "WordPress \"salts\" are secret phrases which are combined with user passwords when those passwords are stored, with the end result that they become much harder for an attacker to crack even if he managed to steal the database of your website." +msgstr "" + +#: dist/templates/wp-admin/user-security/salt.php:15 +msgid "Learn more about WordPress Salts." +msgstr "" + +#: dist/templates/wp-admin/user-security/salt.php:21 +msgid "When you enable this feature, you and all other logged-in users will be logged out so that AIOS can append the additional code (the salt) to all users’ login information." +msgstr "" + +#: dist/templates/wp-admin/user-security/salt.php:35 +msgid "Enable this if you want to activate the salt postfix feature." +msgstr "" + +#: dist/templates/wp-admin/user-security/salt.php:39 +msgid "This setting will suffix the salt with an additional 64 characters." +msgstr "" + +#: dist/templates/wp-admin/user-security/salt.php:39 +msgid "It improves your WordPress site's cryptographic mechanism." +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:196 +msgid "Updating..." +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:209 +msgid "(update)" +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:223, dist/includes/simba-tfa/providers/totp/loader.php:573 +msgid "TOTP (time based - most common algorithm; used by Google Authenticator)" +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:224, dist/includes/simba-tfa/providers/totp/loader.php:573 +msgid "HOTP (event based)" +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:254 +msgid "Choose which algorithm for One Time Passwords you want to use." +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:260 +msgid "Your counter on the server is currently on" +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:343 +msgid "Warning: if you reset this key you will have to update your apps with the new one. Are you sure you want this?" +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:343, dist/includes/simba-tfa/providers/totp/loader.php:436 +msgid "Reset private key" +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:376 +msgid "Current codes (login: %s)" +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:395, dist/includes/simba-tfa/providers/totp/loader.php:384 +msgid "Current one-time password" +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:413 +msgid "Setting up" +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:410 +msgid "Setting up - either scan the code, or type in the private key" +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:419 +msgid "For OTP apps that support using a camera to scan a setup code (below), that is the quickest way to set the app up (e.g. with Duo Mobile, Google Authenticator)." +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:421 +msgid "Otherwise, you can type the textual private key (shown below) into your app. Always keep private keys secret." +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:424 +msgid "You are currently using %s, %s" +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:424 +msgid "a time based algorithm" +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:424 +msgid "an event based algorithm" +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:448 +msgid "One-time emergency codes are a feature of the Premium version of this plugin." +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:524 +msgid "Two Factor Authentication re-sync needed" +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:526 +msgid "You need to resync your device for Two Factor Authentication since the OTP you last used is many steps ahead of the server." +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:528 +msgid "Please re-sync or you might not be able to log in if you generate more OTPs without logging in." +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:530 +msgid "Click here and re-scan the QR-Code" +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:732 +msgid "Encrypt secrets feature not enabled: unable to get private keys from the database." +msgstr "" + +#: dist/includes/simba-tfa/providers/totp/loader.php:807 +msgid "There are no emergency codes left. You will need to reset your private key to generate new ones." +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/cookie-test-container.php:4 +msgid "Before using this feature, you must perform a cookie test first." +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/cookie-test-container.php:6 +msgid "This ensures that your browser cookie is working correctly and that you won't lock yourself out." +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/cookie-test-container.php:11 +msgid "Perform cookie test" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/other-plugins.php:3 +msgid "Other forms CAPTCHA settings" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/other-plugins.php:14 +msgid "Enable CAPTCHA on BuddyPress registration form" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/other-plugins.php:17 +msgid "Enable this if you want to insert a CAPTCHA field on the %s registration forms." +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/other-plugins.php:34 +msgid "Enable CAPTCHA on bbPress new topic form" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/other-plugins.php:37 +msgid "Enable this if you want to insert a CAPTCHA field on the %s new topic forms." +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/other-plugins.php:54 +msgid "Enable CAPTCHA on %s" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/other-plugins.php:57 +msgid "Enable this if you want to insert a CAPTCHA field on %s forms." +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/other-plugins.php:61 +msgid "%s will automatically try to insert a CAPTCHA field before the form's submit button" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/other-plugins.php:62 +msgid "For the exact placement of the CAPTCHA you can use the following shortcode in your %s template" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/other-plugins.php:64 +msgid "This feature requires %s version %s or greater" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/other-plugins.php:65 +msgid "The validation message will be displayed only when using %s version %s or greater" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/rename-login-notice.php:5 +msgid "Your WordPress login page URL has been renamed." +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/rename-login-notice.php:6 +msgid "Your current login URL is:" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/woo-captcha.php:3 +msgid "WooCommerce forms CAPTCHA settings" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/woo-captcha.php:14 +msgid "Enable CAPTCHA on WooCommerce login form" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/woo-captcha.php:17 +msgid "Enable this if you want to insert CAPTCHA on a %s login form." +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/woo-captcha.php:30 +msgid "Enable CAPTCHA on WooCommerce lost password form" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/woo-captcha.php:33 +msgid "Enable this if you want to insert CAPTCHA on a %s lost password form." +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/woo-captcha.php:46 +msgid "Enable CAPTCHA on WooCommerce registration form" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/woo-captcha.php:49 +msgid "Enable this if you want to insert CAPTCHA on a %s registration form." +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/woo-captcha.php:69 +msgid "Guest checkout allows a customer to place an order without an account or being logged in." +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/woo-captcha.php:66 +msgid "Guest checkout is not enabled in your WooCommerce settings." +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/woo-captcha.php:66 +msgid "Therefore, the setting below is not relevant." +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/woo-captcha.php:76 +msgid "Enable CAPTCHA on the WooCommerce checkout page" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/woo-captcha.php:79 +msgid "Enable this if you want to insert a CAPTCHA on the %s checkout page when a guest places an order." +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/wordpress-forms.php:3 +msgid "Wordpress forms CAPTCHA settings" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/wordpress-forms.php:13 +msgid "Enable CAPTCHA on login page" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/wordpress-forms.php:16 +msgid "Enable this if you want to insert a CAPTCHA form on the login page." +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/wordpress-forms.php:31 +msgid "Enable CAPTCHA on registration page" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/wordpress-forms.php:34 +msgid "Enable this if you want to insert a CAPTCHA form on the WordPress user registration page (if you allow user registration)." +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/wordpress-forms.php:50 +msgid "Enable CAPTCHA on lost password page" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/wordpress-forms.php:53 +msgid "Enable this if you want to insert a CAPTCHA form on the lost password page." +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/wordpress-forms.php:69 +msgid "Enable CAPTCHA on custom login form" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/wordpress-forms.php:72 +msgid "Enable this if you want to insert CAPTCHA on a custom login form generated by the following WP function: %s" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/wordpress-forms.php:87 +msgid "Enable CAPTCHA on comment forms" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/wordpress-forms.php:90 +msgid "Enable this if you want to insert a CAPTCHA field on the comment forms." +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/wordpress-forms.php:105 +msgid "Enable CAPTCHA on password protected pages/posts" +msgstr "" + +#: dist/templates/wp-admin/brute-force/partials/wordpress-forms.php:108 +msgid "Enable this if you want to insert a CAPTCHA field on password-protected posts and pages." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/partials/php-file-editing.php:7 +msgid "The WordPress Dashboard by default allows administrators to edit PHP files, such as plugin and theme files." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/partials/php-file-editing.php:7 +msgid "This is often the first tool an attacker will use if able to login, since it allows code execution." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/partials/php-file-editing.php:7 +msgid "This feature will disable the ability for people to edit PHP files via the dashboard." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/partials/php-file-editing.php:16 +msgid "The DISALLOW_FILE_EDIT constant has already been defined, please remove it before enabling this feature." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/partials/php-file-editing.php:16 +msgid "The constant is likely already defined in your wp-config.php file." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/partials/php-file-editing.php:22 +msgid "Disable ability to edit PHP files" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/partials/php-file-editing.php:25 +msgid "Enable this to remove the ability for people to edit PHP files via the WP dashboard" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/partials/prevent-hotlinks.php:7 +msgid "A hotlink is where someone displays an image on their site which is actually located on your site by using a direct link to the source of the image on your server." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/partials/prevent-hotlinks.php:8 +msgid "Due to the fact that the image being displayed on the other person's site is coming from your server, this can cause leaking of bandwidth and resources for you because your server has to present this image for the people viewing it on someone elses's site." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/partials/prevent-hotlinks.php:9 +msgid "This feature will prevent people from directly hotlinking images from your site's pages by writing some directives in your .htaccess file." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/partials/prevent-hotlinks.php:23 +msgid "Enable this to prevent hotlinking to images on your site." +msgstr "" + +#. translators: 1: readme.txt, 2: license text, 3: wp-config-sample.php +#: dist/templates/wp-admin/filesystem-security/partials/wp-file-access.php:8 +msgid "This feature allows you to auto delete files such as %1$s, %2$s and %3$s which are delivered with all WP installations." +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/partials/wp-file-access.php:10 +msgid "By deleting these files you are hiding some key pieces of information (such as WordPress version info) from potential hackers." +msgstr "" + +#. translators: 1: readme.txt, 2: license text, 3: wp-config-sample.php +#: dist/templates/wp-admin/filesystem-security/partials/wp-file-access.php:23 +msgid "Delete %1$s, %2$s, and %3$s:" +msgstr "" + +#: dist/templates/wp-admin/filesystem-security/partials/wp-file-access.php:28 +msgid "Automatically delete the files after a WP core update." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-character-filter.php:13 +msgid "Enable advanced character string filter" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-character-filter.php:16 +msgid "This will block character sequences which resemble XSS attacks." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-character-filter.php:21 +msgid "This is an advanced character string filter to prevent malicious string attacks on your site coming from Cross Site Scripting (XSS)." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-character-filter.php:22 +msgid "This setting matches for common malicious string patterns and exploits and will produce a 403 error for the hacker attempting the query." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-character-filter.php:23 +msgid "NOTE: Some strings for this setting might break some functionality." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:2 +msgid "Block request methods" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:3 +msgid "HTTP request methods are used by browsers and clients to communicate with servers to get responses." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:3 +msgid "The below request methods are not necessary for every site to function and you may disable all HTTP request methods that are not essential for your site to function." +msgstr "" + +#. translators: %s: Block method +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:11 +msgid "Block %s method" +msgstr "" + +#. translators: %s: Block request method +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:15 +msgid "Check this to block the %s request method" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:20 +msgid "Some WooCommerce extensions use the PUT request method in addition to GET and POST." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:20 +msgid "This means WooCommerce users shouldn't block the PUT request method." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:21 +msgid "A few REST requests use the PUT request method." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:21 +msgid "If your site is communicated by the WP REST API, you should not block the PUT request method." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:31 +msgid "Other settings" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:32 +msgid "The 6G firewall provides other settings for blocking malicious query strings, request strings, referers and user-agents; you can configure their settings below." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:38 +msgid "Block query strings" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:41 +msgid "Enable this to block all query strings recommended by 6G" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:46 +msgid "Block request strings" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:49 +msgid "Enable this to block all request strings recommended by 6G" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:54 +msgid "Block referers" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:57 +msgid "Enable this to block all referers recommended by 6G" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:62 +msgid "Block user-agents" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/advanced-settings-6g.php:65 +msgid "Enable this to block all user-agents recommended by 6G" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/allowlist.php:2 +msgid "Allow list" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/allowlist.php:6 +msgid "This option allows you to add IP addresses to your allow list." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/allowlist.php:7 +msgid "All IPs in your allow list will no longer be affected by the firewall's rules." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/allowlist.php:16 +msgid "Save allow list" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/bad-query-strings.php:3 +msgid "Bad query strings" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/bad-query-strings.php:16 +msgid "This will help protect you against malicious queries via XSS." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/bad-query-strings.php:21 +msgid "This feature will prevent malicious string attacks on your site using XSS." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/bad-query-strings.php:22 +msgid "NOTE: Some of these strings might be used for plugins or themes and hence this might break some functionality." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/basic-firewall-settings.php:13 +msgid "Enable basic firewall protection" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/basic-firewall-settings.php:16 +msgid "Enable this to apply basic firewall protection to your site." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/basic-firewall-settings.php:20 +msgid "This setting will implement the following basic firewall protection mechanisms on your site:" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/basic-firewall-settings.php:21 +msgid "1) Protect your htaccess file by denying access to it." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/basic-firewall-settings.php:22 +msgid "2) Disable the server signature." +msgstr "" + +#. translators: %s: Upload limit. +#: dist/templates/wp-admin/firewall/partials/basic-firewall-settings.php:24 +msgid "3) Limit file upload size (%sMB)." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/basic-firewall-settings.php:25 +msgid "4) Protect your wp-config.php file by denying access to it." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/basic-firewall-settings.php:26 +msgid "The above firewall features will be applied via your .htaccess file and should not affect your site's overall functionality." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/basic-firewall-settings.php:27 +msgid "You are still advised to take a backup of your active .htaccess file just in case." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/basic-firewall-settings.php:34 +msgid "Max file upload size (MB)" +msgstr "" + +#. translators: %s: Upload limit. +#: dist/templates/wp-admin/firewall/partials/basic-firewall-settings.php:37 +msgid "The value for the maximum file upload size used in the .htaccess file. (Defaults to %sMB if left blank)" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/blank-ref-and-useragent.php:13 +msgid "Ban POST requests that have a blank user-agent and referer" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/blank-ref-and-useragent.php:16 +msgid "Enable this if you want to ban POST requests that have a blank user-agent and referer." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/blank-ref-and-useragent.php:20 +msgid "This feature will check whether the user-agent and referer HTTP headers are blank." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/blank-ref-and-useragent.php:21 +msgid "If they are both blank, the IP address associated with the request will be added to your permanent block list." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/block-debug-log.php:14 +msgid "Block access to debug.log file" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/block-debug-log.php:17 +msgid "Enable this if you want to block access to the debug.log file that WordPress creates when debug logging is enabled." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/block-debug-log.php:21 +msgid "WordPress has an option to turn on the debug logging to a file located in wp-content/debug.log." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/block-debug-log.php:21 +msgid "This file may contain sensitive information." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/block-debug-log.php:22 +msgid "Using this option will block external access to this file." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/block-debug-log.php:22 +msgid "You can still access this file by logging into your site via FTP." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/disable-rss-atom.php:3 +msgid "Disable WordPress RSS and ATOM feeds" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/disable-rss-atom.php:13 +msgid "Disable RSS and ATOM feeds:" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/disable-rss-atom.php:16 +msgid "Enable this if you do not want users using feeds." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/disable-rss-atom.php:16 +msgid "RSS and ATOM feeds are used to read content from your site." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/disable-rss-atom.php:20 +msgid "Most users will want to share their site content widely, but some may prefer to prevent automated site scraping." +msgstr "" + +#. translators: %s: FAQ URL. +#: dist/templates/wp-admin/firewall/partials/disable-rss-atom.php:22 +msgid "For more information, check the %s" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/disable-rss-atom.php:22 +msgid "documentation" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/disable-trace.php:3 +msgid "Trace and track" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/disable-trace.php:17 +msgid "Enable this to disable trace and track." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/disable-trace.php:22 +msgid "HTTP Trace attack (XST) can be used to return header requests and grab cookies and other information." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/disable-trace.php:24 +msgid "This hacking technique is usually used together with cross site scripting attacks (XSS)." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/disable-trace.php:26 +msgid "Disabling trace and track on your site will help prevent HTTP Trace attacks." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/fake-googlebots.php:4 +msgid "This feature allows you to block bots which are impersonating as a Googlebot but actually aren't. (In other words they are fake Google bots)" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/fake-googlebots.php:5 +msgid "Googlebots have a unique identity which cannot easily be forged and this feature will identify any fake Google bots and block them from reading your site's pages." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/fake-googlebots.php:12 +msgid "Sometimes non-malicious Internet organizations might have bots which impersonate as a \"Googlebot\"." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/fake-googlebots.php:13 +msgid "Just be aware that if you activate this feature the plugin will block all bots which use the \"Googlebot\" string in their User Agent information but are NOT officially from Google (irrespective of whether they are malicious or not)." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/fake-googlebots.php:14 +msgid "All other bots from other organizations such as \"Yahoo\", \"Bing\" etc will not be affected by this feature." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/fake-googlebots.php:32 +msgid "Enable this if you want to block all fake Googlebots." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/fake-googlebots.php:36 +msgid "This feature will check if the User Agent information of a bot contains the string \"Googlebot\"." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/fake-googlebots.php:37 +msgid "It will then perform a few tests to verify if the bot is legitimately from Google and if so it will allow the bot to proceed." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/fake-googlebots.php:38 +msgid "If the bot fails the checks then the plugin will mark it as being a fake Googlebot and it will block it" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/firewall-downgrade-button.php:4, dist/templates/wp-admin/firewall/partials/firewall-setup.php:22 +msgid "Downgrade firewall" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/firewall-set-up-button.php:4, dist/templates/wp-admin/firewall/partials/firewall-setup.php:20 +msgid "Set up firewall" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/firewall-setup.php:3 +msgid "Firewall setup" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/firewall-setup.php:7 +msgid "This option allows you to set up or downgrade the firewall." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/firewall-setup.php:8 +msgid "We recommend you set up the firewall for greater protection, but if for whatever reason you wish to downgrade the firewall, then you can do so here." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/firewall-setup.php:20 +msgid "This will attempt to set up the firewall in order to give you the highest level of protection it has to offer." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/firewall-setup.php:22 +msgid "This will undo the changes performed by the set-up mechanism." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/firewall-setup.php:24 +msgid "The firewall will still be active if it is downgraded or not set up, but you will have reduced protection." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/internet-bots.php:8 +msgid "What is an Internet Bot" +msgstr "" + +#. translators: s%: Wiki URL. +#: dist/templates/wp-admin/firewall/partials/internet-bots.php:10 +msgid "%s?" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/internet-bots.php:12 +msgid "A bot is a piece of software which runs on the Internet and performs automatic tasks." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/internet-bots.php:12 +msgid "For example when Google indexes your pages it uses bots to achieve this task." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/internet-bots.php:13 +msgid "A lot of bots are legitimate and non-malicious but not all bots are good and often you will find some which try to impersonate legitimate bots such as \"Googlebot\" but in reality they have nohing to do with Google at all." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/internet-bots.php:14 +msgid "Although most of the bots out there are relatively harmless sometimes website owners want to have more control over which bots they allow into their site." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/listing-directory-contents.php:3 +msgid "Listing of directory contents" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/listing-directory-contents.php:17 +msgid "Enable this if you want to disable directory and file listing." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/listing-directory-contents.php:22 +msgid "By default, an Apache server will allow the listing of the contents of a directory if it doesn't contain an index.php file." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/listing-directory-contents.php:24 +msgid "This feature will prevent the listing of contents for all directories." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/listing-directory-contents.php:26 +msgid "NOTE: In order for this feature to work \"AllowOverride\" of the Indexes directive must be enabled in your httpd.conf file." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/listing-directory-contents.php:26 +msgid "Ask your hosting provider to check this if you don't have access to httpd.conf" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/ng.php:4 +msgid "6G firewall settings" +msgstr "" + +#. translators: 1: 8G URL, 2: 5G URL, 3: Perishable Press URL +#: dist/templates/wp-admin/firewall/partials/ng.php:9 +msgid "This feature allows you to activate the %1$s (or legacy %2$s) firewall security protection rules designed and produced by %3$s." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/ng.php:10 +msgid "The 6G firewall is an updated and improved version of the 5G firewall that is PHP-based and doesn't use a .htaccess file." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/ng.php:10 +msgid "If you have the 5G firewall active, you might consider activating the 6G firewall instead." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/ng.php:11 +msgid "The 6G firewall is a simple, flexible blacklist that helps reduce the number of malicious URL requests that hit your website." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/ng.php:12 +msgid "The added advantage of applying the 6G firewall to your site is that it has been tested and confirmed by the people at PerishablePress.com to be an optimal and least disruptive set of security rules for general WP sites." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/ng.php:25 +msgid "Enable 6G firewall protection" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/ng.php:28 +msgid "Enable this to apply the recommended 6G firewall protection." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/ng.php:32 +msgid "This setting will implement the 6G security firewall protection mechanisms on your site which include the following things:" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/ng.php:47 +msgid "Show advanced options" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/ng.php:48 +msgid "Hide advanced options" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/proxy-comment.php:3 +msgid "Proxy comment posting" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/proxy-comment.php:16 +msgid "Enable this if you want to forbid proxy comment posting." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/proxy-comment.php:21 +msgid "This setting will deny any requests that use a proxy server when posting comments." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/proxy-comment.php:22 +msgid "By forbidding proxy comments you are in effect eliminating some spam and other proxy requests." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/rest-route-whitelist.php:3 +msgid "%s this REST route allows websites to display core content, such as posts, pages, and other WordPress data." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/rest-route-whitelist.php:3 +msgid "This route is essential for the WordPress block editor and API integrations." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/rest-route-whitelist.php:3 +msgid "Disabling it may break plugins and themes." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/rest-route-whitelist.php:4 +msgid "%s this REST route enables embedding content from your site on external platforms (e.g., Twitter, Facebook, and WordPress embeds)." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/rest-route-whitelist.php:4 +msgid "Disabling this may prevent your site's content from being embedded in social media and other platforms." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/rest-route-whitelist.php:10 +msgid "Whitelist REST routes" +msgstr "" + +#. translators: 1: Bold unsafe function name, 2: Bold safe function name. +#: dist/templates/wp-admin/firewall/partials/upgrade-unsafe-http-calls.php:15 +msgid "This feature allows you to upgrade all unsafe HTTP calls on your site using %1$s to %2$s." +msgstr "" + +#. translators: %s Bold unsafe function name. +#: dist/templates/wp-admin/firewall/partials/upgrade-unsafe-http-calls.php:17 +msgid "You can also specify a list of URLs that are allowed to be contacted with the unsafe %s calls." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/upgrade-unsafe-http-calls.php:22 +msgid "Enable" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/upgrade-unsafe-http-calls.php:30 +msgid "URL exceptions" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/upgrade-unsafe-http-calls.php:34 +msgid "Enter URL exceptions." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/upgrade-unsafe-http-calls.php:38 +msgid "Each URL must be on a new line." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/upgrade-unsafe-http-calls.php:39 +msgid "All localhost URLs are already an exception." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/wp-rest-api.php:7 +msgid "WP REST API settings" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/wp-rest-api.php:18 +msgid "This feature allows you to block WordPress REST API access for unauthorized requests." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/wp-rest-api.php:19 +msgid "When enabled this feature will only allow REST requests to be processed if the user is logged in." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/wp-rest-api.php:20 +msgid "Only REST requests made by logged-in users with a role permitted below will succeed, unless the REST API endpoint has been white-listed for others to also use." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/wp-rest-api.php:21 +msgid "You can whitelist REST routes by selecting from the list of all registered rest routes for all users, including those who are not logged in." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/wp-rest-api.php:28 +msgid "You do not have any registered REST API routes to block unauthorized access." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/wp-rest-api.php:38 +msgid "Enable this to stop REST API access for non-logged in requests." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/wp-rest-api.php:43 +msgid "User roles allowed access when logged in" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:3 +msgid "WordPress XMLRPC and pingback vulnerability protection" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:14 +msgid "Completely block access to XMLRPC" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:17 +msgid "Enable this if you are not using the WP XML-RPC functionality and you want to completely block external access to XMLRPC." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:21 +msgid "This setting will disable access to the WordPress xmlrpc.php file which is responsible for the XML-RPC functionality in WordPress." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:22 +msgid "Hackers can exploit various vulnerabilities in the WordPress XML-RPC API in a number of ways such as:" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:23 +msgid "1) Denial of Service (DoS) attacks" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:24 +msgid "2) Hacking internal routers." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:25 +msgid "3) Scanning ports in internal networks to get info from various hosts." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:26 +msgid "Apart from the security protection benefit, this feature may also help reduce load on your server, particularly if your site currently has a lot of unwanted traffic hitting the XML-RPC API on your installation." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:27 +msgid "NOTE: You should only enable this feature if you are not currently using the XML-RPC functionality on your WordPress installation." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:28 +msgid "Leave this feature disabled and use the feature below if you want pingback protection but you still need XMLRPC." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:35 +msgid "Disable pingback functionality from XMLRPC" +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:38 +msgid "If you use Jetpack or WP iOS or other apps which need WP XML-RPC functionality then check this." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:38 +msgid "This will enable protection against WordPress pingback vulnerabilities." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:42 +msgid "NOTE: If you use Jetpack or the Wordpress iOS or other apps then you should enable this feature but leave the \"Completely Block Access To XMLRPC\" checkbox unchecked." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:43 +msgid "The feature will still allow XMLRPC functionality on your site but will disable the pingback methods." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php:44 +msgid "This feature will also remove the \"X-Pingback\" header if it is present." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-warning-notice.php:6 +msgid "You have enabled the \"Completely Block Access To XMLRPC\" checkbox which means all XMLRPC functionality will be blocked." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-warning-notice.php:7 +msgid "By leaving this feature enabled you will prevent Jetpack or Wordpress iOS or other apps which need XMLRPC from working correctly on your site." +msgstr "" + +#: dist/templates/wp-admin/firewall/partials/xmlrpc-warning-notice.php:8 +msgid "If you still need XMLRPC then uncheck the \"Completely Block Access To XMLRPC\" checkbox and enable only the \"Disable Pingback Functionality From XMLRPC\" checkbox." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/display-name.php:2 +msgid "Display name security" +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/display-name.php:5 +msgid "When you submit a post or answer a comment, WordPress will usually display your \"nickname\"." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/display-name.php:6 +msgid "By default the nickname is set to the login (or user) name of your account." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/display-name.php:7 +msgid "From a security perspective, leaving your nickname the same as your user name is bad practice because it gives a hacker at least half of your account's login credentials." +msgstr "" + +#. translators: 1. Open strong tag, 2. Close strong tag. +#: dist/templates/wp-admin/user-security/partials/display-name.php:9 +msgid "Therefore to further tighten your site's security you are advised to change your %1$snickname%2$s and %1$sDisplay name%2$s to be different from your %1$sUsername%2$s." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/display-name.php:14 +msgid "Modify accounts with identical login name and display name" +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/display-name.php:37, dist/templates/wp-admin/user-security/partials/wp-username-content.php:21 +msgid "No action required." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/display-name.php:37 +msgid "Your site does not have a user account where the display name is identical to the username." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/display-name.php:22 +msgid "Your site currently has the following accounts with identical login and display names." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/display-name.php:22 +msgid "Follow the link to edit the user profile of that particular user account, change Nickname, choose a different Display name compared to Username, and press the \"Update Profile\" button." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/enforce-strong-password.php:3, dist/templates/wp-admin/user-security/partials/enforce-strong-password.php:19 +msgid "Enforce strong password" +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/enforce-strong-password.php:13 +msgid "This feature allows you to enforce the use of strong user passwords" +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/enforce-strong-password.php:14 +msgid "When enabled, this feature will hide the \"confirm weak password\" checkbox on forms." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/enforce-strong-password.php:22 +msgid "Enable this if you want to force your users to use a strong password." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/user-enumeration.php:3 +msgid "Prevent user enumeration" +msgstr "" + +#. translators: 1: Author example, 2: REST API prefix. +#: dist/templates/wp-admin/user-security/partials/user-enumeration.php:14 +msgid "This feature allows you to prevent external users/bots from fetching the user info with URLs like \"%1$s\", \"%2$s\", oEmbed request." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/user-enumeration.php:15 +msgid "When enabled, this feature will print a \"forbidden\" error rather than the user information." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/user-enumeration.php:20 +msgid "Disable user enumeration" +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/user-enumeration.php:23 +msgid "Enable this if you want to stop user enumeration." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/wp-username-content.php:23 +msgid "Your site does not have any account which uses the \"admin\" username." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/wp-username-content.php:24 +msgid "This is good security practice." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/wp-username-content.php:3 +msgid "Your site currently has an account which uses the \"admin\" username." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/wp-username-content.php:3 +msgid "It is highly recommended that you change this name to something else." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/wp-username-content.php:3 +msgid "Use the following field to change the admin username." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/wp-username-content.php:8 +msgid "New admin username" +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/wp-username-content.php:10 +msgid "Choose a new username for admin." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/wp-username-content.php:14 +msgid "Change username" +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/wp-username-content.php:16 +msgid "NOTE: If you are currently logged in as \"admin\" you will be automatically logged out after changing your username and will be required to log back in." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/wp-username.php:2 +msgid "Admin user security" +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/wp-username.php:5 +msgid "Depending on how you installed WordPress, you could have a default administrator with the username \"admin\"." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/wp-username.php:6 +msgid "Hackers can try to take advantage of this information by attempting \"Brute force login attacks\" where they repeatedly try to guess the password by using \"admin\" for username." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/wp-username.php:7 +msgid "From a security perspective, changing the username \"admin\" is one of the first and smartest things you should do on your site." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/wp-username.php:8 +msgid "This feature will allow you to change your \"admin\" username to a more secure name of your choosing." +msgstr "" + +#: dist/templates/wp-admin/user-security/partials/wp-username.php:14 +msgid "List of administrator accounts" +msgstr "" diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/index.html b/wp-content/plugins/all-in-one-wp-security-and-firewall/languages/index.html new file mode 100755 index 00000000..e69de29b diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/lib/index.html b/wp-content/plugins/all-in-one-wp-security-and-firewall/lib/index.html new file mode 100755 index 00000000..e69de29b diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/license.txt b/wp-content/plugins/all-in-one-wp-security-and-firewall/license.txt new file mode 100755 index 00000000..7dc2abcc --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/license.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright © 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright © + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright © + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/logs/index.html b/wp-content/plugins/all-in-one-wp-security-and-firewall/logs/index.html new file mode 100755 index 00000000..e69de29b diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/logs/wp-security-log-cron-job.txt b/wp-content/plugins/all-in-one-wp-security-and-firewall/logs/wp-security-log-cron-job.txt new file mode 100755 index 00000000..e69de29b diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/logs/wp-security-log.txt b/wp-content/plugins/all-in-one-wp-security-and-firewall/logs/wp-security-log.txt new file mode 100755 index 00000000..e69de29b diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/other-includes/index.html b/wp-content/plugins/all-in-one-wp-security-and-firewall/other-includes/index.html new file mode 100755 index 00000000..e69de29b diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/other-includes/wp-security-rename-login-feature-pre-5-2.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/other-includes/wp-security-rename-login-feature-pre-5-2.php new file mode 100755 index 00000000..a54f1705 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/other-includes/wp-security-rename-login-feature-pre-5-2.php @@ -0,0 +1,1138 @@ +` element. + * Default 'Log In'. + * @param string $message Optional. Message to display in header. Default empty. + * @param WP_Error $wp_error Optional. The error to pass. Default empty. + */ +function login_header($title = 'Log In', $message = '', $wp_error = '') { +global $error, $interim_login, $action; + +// Don't index any of these forms +add_action('login_head', 'wp_no_robots'); + +add_action('login_head', 'wp_login_viewport_meta'); + +if (empty($wp_error)) + $wp_error = new WP_Error(); + +// Shake it! +$shake_error_codes = array('empty_password', 'empty_email', 'invalid_email', 'invalidcombo', 'empty_username', 'invalid_username', 'incorrect_password'); +/** + * Filter the error codes array for shaking the login form. + * + * @since 3.0.0 + * + * @param array $shake_error_codes Error codes that shake the login form. + */ +$shake_error_codes = apply_filters('shake_error_codes', $shake_error_codes); + +if ($shake_error_codes && $wp_error->get_error_code() && in_array($wp_error->get_error_code(), $shake_error_codes)) + add_action('login_head', 'wp_shake_js', 12); + +$login_title = get_bloginfo('name', 'display'); + +/* translators: Login screen title. 1: Login screen name, 2: Network or site name */ +$login_title = sprintf(__('%1$s ‹ %2$s — WordPress'), $title, $login_title); + +/** + * Filters the title tag content for login page. + * + * @since 4.9.0 + * + * @param string $login_title The page title, with extra context added. + * @param string $title The original page title. + */ +$login_title = apply_filters('login_title', $login_title, $title); + +?> + + +> + + + + <?php echo esc_html($login_title); ?> + get_error_code()) { + ?> + + site_name; + } else { + $login_header_url = __('https://wordpress.org/'); + $login_header_title = __('Powered by WordPress'); + } + + /** + * Filter link URL of the header logo above login form. + * + * @since 2.1.0 + * + * @param string $login_header_url Login header logo URL. + */ + $login_header_url = apply_filters('login_headerurl', $login_header_url); + + /** + * Filter the title attribute of the header logo above login form. + * + * @since 2.1.0 + * + * @param string $login_header_title Login header logo title attribute. + */ + $login_header_title = apply_filters('login_headertitle', $login_header_title); + + /* + * To match the URL/title set above, Multisite sites have the blog name, + * while single sites get the header title. + */ + if (is_multisite()) { + $login_header_text = get_bloginfo('name', 'display'); + } else { + $login_header_text = $login_header_title; + } + + $classes = array('login-action-' . $action, 'wp-core-ui'); + if (is_rtl()) + $classes[] = 'rtl'; + if ($interim_login) { + $classes[] = 'interim-login'; + ?> + + + + + +
            +

            + add('error', $error); + unset($error); + } + + if ($wp_error->get_error_code()) { + $errors = ''; + $messages = ''; + foreach ($wp_error->get_error_codes() as $code) { + $severity = $wp_error->get_error_data($code); + foreach ($wp_error->get_error_messages($code) as $error_message) { + if ('message' == $severity) { + $messages .= ' ' . $error_message . "
            \n"; + } else { + $errors .= ' ' . $error_message . "
            \n"; + } + } + } + if (! empty($errors)) { + /** + * Filter the error messages displayed above the login form. + * + * @since 2.1.0 + * + * @param string $errors Login error message. + */ + echo '
            ' . wp_kses_post(apply_filters('login_errors', $errors)) . "
            \n"; + } + if (! empty($messages)) { + /** + * Filter instructional messages displayed above the login form. + * + * @since 2.5.0 + * + * @param string $messages Login messages. + */ + echo '

            ' . wp_kses_post(apply_filters('login_messages', $messages)) . "

            \n"; + } + } + } // End of login_header() + + /** + * Outputs the footer for the login page. + * + * @param string $input_id Which input to auto-focus + */ + function login_footer($input_id = '') { + global $interim_login; + + // Don't allow interim logins to navigate away from the page. + if (!$interim_login) : ?> +

            + ', '
            '); + } + ?> + + +
            + + + + + + +
            + + + + + + +add('empty_username', __('ERROR: Enter a username or email address.')); + } elseif (strpos(sanitize_email(wp_unslash($_POST['user_login'])), '@')) { + $user_data = get_user_by('email', trim(sanitize_email(wp_unslash($_POST['user_login'])))); + if (empty($user_data)) + $errors->add('invalid_email', __('ERROR: There is no account with that username or email address.')); + } else { + $login = trim(sanitize_email(wp_unslash($_POST['user_login']))); + $user_data = get_user_by('login', $login); + } + // phpcs:enable WordPress.Security.NonceVerification.Missing -- No nonce available. + + /** + * Fires before errors are returned from a password reset request. + * + * @since 2.1.0 + * @since 4.4.0 Added the `$errors` parameter. + * + * @param WP_Error $errors A WP_Error object containing any errors generated + * by using invalid credentials. + */ + do_action('lostpassword_post', $errors); + + if ($errors->get_error_code()) + return $errors; + + if (!$user_data) { + $errors->add('invalidcombo', __('ERROR: There is no account with that username or email address.')); + return $errors; + } + + // Redefining user_login ensures we return the right case in the email. + $user_login = $user_data->user_login; + $user_email = $user_data->user_email; + $key = get_password_reset_key($user_data); + + if (is_wp_error($key)) { + return $key; + } + + if (is_multisite()) { + $site_name = get_network()->site_name; + } else { + /* + * The blogname option is escaped with esc_html on the way into the database + * in sanitize_option we want to reverse this for the plain text arena of emails. + */ + $site_name = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); + } + + $message = __('Someone has requested a password reset for the following account:') . "\r\n\r\n"; + /* translators: %s: site name */ + $message .= sprintf(__('Site Name: %s'), $site_name) . "\r\n\r\n"; + /* translators: %s: user login */ + $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n"; + $message .= __('If this was a mistake, just ignore this email and nothing will happen.') . "\r\n\r\n"; + $message .= __('To reset your password, visit the following address:') . "\r\n\r\n"; + $message .= '<' . network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login') . ">\r\n"; + + // translators: Password reset email subject. %s: Site name + $title = sprintf(__('[%s] Password Reset'), $site_name); + + /** + * Filters the subject of the password reset email. + * + * @since 2.8.0 + * @since 4.4.0 Added the `$user_login` and `$user_data` parameters. + * + * @param string $title Default email title. + * @param string $user_login The username for the user. + * @param WP_User $user_data WP_User object. + */ + $title = apply_filters('retrieve_password_title', $title, $user_login, $user_data); + + /** + * Filter the message body of the password reset mail. + * + * If the filtered message is empty, the password reset email will not be sent. + * + * @since 2.8.0 + * @since 4.1.0 Added `$user_login` and `$user_data` parameters. + * + * @param string $message Default mail message. + * @param string $key The activation key. + * @param string $user_login The username for the user. + * @param WP_User $user_data WP_User object. + */ + $message = apply_filters('retrieve_password_message', $message, $key, $user_login, $user_data); + + if ($message && !wp_mail($user_email, wp_specialchars_decode($title), $message)) + wp_die(esc_html__('The email could not be sent.') . "
            \n" . esc_html__('Possible reason: your host may have disabled the mail() function.')); + + return true; +} + +// +// Main +// +// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No nonce available. +$action = isset($_REQUEST['action']) ? sanitize_text_field(wp_unslash($_REQUEST['action'])) : 'login'; +$errors = new WP_Error(); + +if (isset($_GET['key'])) + $action = 'resetpass'; + +// validate action so as to default to the login screen +if (!in_array($action, array('postpass', 'logout', 'lostpassword', 'retrievepassword', 'resetpass', 'rp', 'register', 'login', 'confirmaction'), true) && false === has_filter('login_form_' . $action)) + $action = 'login'; + +nocache_headers(); + +header('Content-Type: '.get_bloginfo('html_type').'; charset='.get_bloginfo('charset')); + +if (defined('RELOCATE') && RELOCATE) { // Move flag is set + $path_info = isset($_SERVER['PATH_INFO']) ? sanitize_text_field(wp_unslash($_SERVER['PATH_INFO'])) : ''; + $php_self = isset($_SERVER['PHP_SELF']) ? sanitize_text_field(wp_unslash($_SERVER['PHP_SELF'])) : ''; + + if ('' !== $path_info && ($path_info != $php_self)) + $_SERVER['PHP_SELF'] = str_replace($path_info, '', $php_self); + + $url = dirname(set_url_scheme('http://' . isset($_SERVER['HTTP_HOST']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'])) : '' . $php_self)); + if (get_option('siteurl') != $url) + update_option('siteurl', $url); +} + +setcookie(TEST_COOKIE, 'WP Cookie check', 0, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true); +if (SITECOOKIEPATH != COOKIEPATH) + setcookie(TEST_COOKIE, 'WP Cookie check', 0, SITECOOKIEPATH, COOKIE_DOMAIN, is_ssl(), true); + +$lang = ! empty($_GET['wp_lang']) ? sanitize_text_field(wp_unslash($_GET['wp_lang'])) : ''; +$switched_locale = false; + +if (function_exists('switch_to_locale')) { + $switched_locale = switch_to_locale($lang); +} + +/** + * Fires when the login form is initialized. + * + * @since 3.2.0 + */ +do_action('login_init'); + +/** + * Fires before a specified login form action. + * + * The dynamic portion of the hook name, `$action`, refers to the action + * that brought the visitor to the login form. Actions include 'postpass', + * 'logout', 'lostpassword', etc. + * + * @since 2.8.0 + */ +do_action("login_form_{$action}"); + +$http_post = ('POST' == isset($_SERVER['REQUEST_METHOD']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_METHOD'])) : ''); +$interim_login = isset($_REQUEST['interim-login']); + +/** + * Filters the separator used between login form navigation links. + * + * @since 4.9.0 + * + * @param string $login_link_separator The separator used between login form navigation links. + */ +$login_link_separator = apply_filters('login_link_separator', ' | '); + +switch ($action) { + + case 'postpass': + if (! array_key_exists('post_password', $_POST)) { + wp_safe_redirect(wp_get_referer()); + exit(); + } + + require_once ABSPATH . WPINC . '/class-phpass.php'; + $hasher = new PasswordHash(8, true); + + /** + * Filter the life span of the post password cookie. + * + * By default, the cookie expires 10 days from creation. To turn this + * into a session cookie, return 0. + * + * @since 3.7.0 + * + * @param int $expires The expiry time, as passed to setcookie(). + */ + $expire = apply_filters('post_password_expires', time() + 10 * DAY_IN_SECONDS); + + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitizing password not recommended. It's going to be hashed anyway. + setcookie('wp-postpass_' . COOKIEHASH, $hasher->HashPassword(wp_unslash($_POST['post_password'])), $expire, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true); + + if ($switched_locale) { + restore_previous_locale(); + } + + wp_safe_redirect(wp_get_referer()); + exit(); + case 'logout': + check_admin_referer('log-out'); + + $user = wp_get_current_user(); + + wp_logout(); + + if (! empty($_REQUEST['redirect_to'])) { + $redirect_to = $requested_redirect_to = sanitize_text_field(wp_unslash($_REQUEST['redirect_to'])); + } else { + $redirect_to = 'wp-login.php?loggedout=true'; + $requested_redirect_to = ''; + } + + if ($switched_locale) { + restore_previous_locale(); + } + + /** + * Filter the log out redirect URL. + * + * @since 4.2.0 + * + * @param string $redirect_to The redirect destination URL. + * @param string $requested_redirect_to The requested redirect destination URL passed as a parameter. + * @param WP_User $user The WP_User object for the user that's logging out. + */ + $redirect_to = apply_filters('logout_redirect', $redirect_to, $requested_redirect_to, $user); + + wp_safe_redirect($redirect_to); + exit(); + + case 'lostpassword': + case 'retrievepassword': + if ($http_post) { + $errors = retrieve_password(); + if (!is_wp_error($errors)) { + $redirect_to = !empty($_REQUEST['redirect_to']) ? sanitize_text_field(wp_unslash($_REQUEST['redirect_to'])) : 'wp-login.php?checkemail=confirm'; + wp_safe_redirect($redirect_to); + exit(); + } + } + + if (isset($_GET['error'])) { + if ('invalidkey' == $_GET['error']) { + $errors->add('invalidkey', __('Your password reset link appears to be invalid. Please request a new link below.')); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + } elseif ('expiredkey' == $_GET['error']) { + $errors->add('expiredkey', __('Your password reset link has expired. Please request a new link below.')); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + } + } + + $lostpassword_redirect = ! empty($_REQUEST['redirect_to']) ? sanitize_text_field(wp_unslash($_REQUEST['redirect_to'])) : ''; + /** + * Filter the URL redirected to after submitting the lostpassword/retrievepassword form. + * + * @since 3.0.0 + * + * @param string $lostpassword_redirect The redirect destination URL. + */ + $redirect_to = apply_filters('lostpassword_redirect', $lostpassword_redirect); + + /** + * Fires before the lost password form. + * + * @since 1.5.1 + */ + do_action('lost_password'); + + login_header(__('Lost Password'), '

            ' . __('Please enter your username or email address. You will receive a link to create a new password via email.') . '

            ', $errors); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + + $user_login = ''; + + if (isset($_POST['user_login']) && is_string($_POST['user_login'])) { + $user_login = sanitize_text_field(wp_unslash($_POST['user_login'])); + } + + ?> + +
            +

            + +

            + + +

            +
            + + + + get_error_code() === 'expired_key') { + wp_redirect(site_url('wp-login.php?action=lostpassword&error=expiredkey')); + } else { + wp_redirect(site_url('wp-login.php?action=lostpassword&error=invalidkey')); + } + exit; + } + + $errors = new WP_Error(); + + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Not recommended to sanitize password. + if (isset($_POST['pass1']) && wp_unslash($_POST['pass1']) != isset($_POST['pass2']) ? wp_unslash($_POST['pass2']) : '') + $errors->add('password_reset_mismatch', __('The passwords do not match.')); + + /** + * Fires before the password reset procedure is validated. + * + * @since 3.5.0 + * + * @param object $errors WP Error object. + * @param WP_User|WP_Error $user WP_User object if the login and reset key match. WP_Error object otherwise. + */ + do_action('validate_password_reset', $errors, $user); + + if ((! $errors->get_error_code()) && isset($_POST['pass1']) && !empty($_POST['pass1'])) { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Not recommended to sanitize password. + reset_password($user, wp_unslash($_POST['pass1'])); + setcookie($rp_cookie, ' ', time() - YEAR_IN_SECONDS, $rp_path, COOKIE_DOMAIN, is_ssl(), true); + login_header(__('Password Reset'), '

            ' . __('Your password has been reset.') . ' ' . __('Log in') . '

            '); + login_footer(); + exit; + } + + wp_enqueue_script('utils'); + wp_enqueue_script('user-profile'); + + login_header(__('Reset Password'), '

            ' . __('Enter your new password below.') . '

            ', $errors); + ?> +
            + + +
            +

            + +

            + +
            +
            + + + + +
            +
            +
            +
            + +
            +
            +

            +
            + +

            + +

            +
            + + + +

            +
            + + + + ' . __('Register For This Site') . '

            ', $errors); + ?> + +
            +

            + +

            +

            + +

            + +

            +
            + +

            +
            + + + + ID)) { + $secure_cookie = true; + force_ssl_admin(true); + } + } + } + + if (isset($_REQUEST['redirect_to'])) { + $redirect_to = sanitize_text_field(wp_unslash($_REQUEST['redirect_to'])); + // Redirect to https if user wants ssl + if ($secure_cookie && false !== strpos($redirect_to, 'wp-admin')) + $redirect_to = preg_replace('|^http://|', 'https://', $redirect_to); + } else { + $redirect_to = admin_url(); + } + + $reauth = empty($_REQUEST['reauth']) ? false : true; + + $user = wp_signon(array(), $secure_cookie); + + if (empty($_COOKIE[LOGGED_IN_COOKIE])) { + if (headers_sent()) { + // translators: 1: Browser cookie documentation URL, 2: Support forums URL + $user = new WP_Error('test_cookie', sprintf(__('ERROR: Cookies are blocked due to unexpected output. For help, please see this documentation or try the support forums.'), esc_url(__('https://codex.wordpress.org/Cookies')), esc_url(__('https://wordpress.org/support/')))); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + } elseif (isset($_POST['testcookie']) && empty($_COOKIE[TEST_COOKIE])) { + // If cookies are disabled we can't log in even with a valid user+pass + // translators: 1: Browser cookie documentation URL + $user = new WP_Error('test_cookie', sprintf(__('ERROR: Cookies are blocked or not supported by your browser. You must enable cookies to use WordPress.'), esc_url(__('https://codex.wordpress.org/Cookies')))); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + } + } + + $requested_redirect_to = isset($_REQUEST['redirect_to']) ? sanitize_text_field(wp_unslash($_REQUEST['redirect_to'])) : ''; + /** + * Filter the login redirect URL. + * + * @since 3.0.0 + * + * @param string $redirect_to The redirect destination URL. + * @param string $requested_redirect_to The requested redirect destination URL passed as a parameter. + * @param WP_User|WP_Error $user WP_User object if login was successful, WP_Error object otherwise. + */ + $redirect_to = apply_filters('login_redirect', $redirect_to, $requested_redirect_to, $user); + + if (!is_wp_error($user) && !$reauth) { + if ($interim_login) { + $message = '

            ' . __('You have logged in successfully.') . '

            '; + $interim_login = 'success'; + login_header('', $message); ?> +
            + + + + + + ID) && !is_super_admin($user->ID)) + $redirect_to = user_admin_url(); + elseif (is_multisite() && !$user->has_cap('read')) + $redirect_to = get_dashboard_url($user->ID); + elseif (!$user->has_cap('edit_posts')) + $redirect_to = $user->has_cap('read') ? admin_url('profile.php') : home_url(); + + wp_redirect($redirect_to); + exit(); + } + wp_safe_redirect($redirect_to); + exit(); + } + + $errors = $user; + // Clear errors if loggedout is set. + if (!empty($_GET['loggedout']) || $reauth) + $errors = new WP_Error(); + + if ($interim_login) { + if (! $errors->get_error_code()) + $errors->add('expired', __('Your session has expired. Please log in to continue where you left off.'), 'message'); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + } else { + // Some parts of this script use the main login form to display a message + if (isset($_GET['loggedout']) && true == $_GET['loggedout']) + $errors->add('loggedout', __('You are now logged out.'), 'message'); + elseif (isset($_GET['registration']) && 'disabled' == $_GET['registration']) + $errors->add('registerdisabled', __('User registration is currently not allowed.')); + elseif (isset($_GET['checkemail']) && 'confirm' == $_GET['checkemail']) + $errors->add('confirm', __('Check your email for the confirmation link.'), 'message'); + elseif (isset($_GET['checkemail']) && 'newpass' == $_GET['checkemail']) + $errors->add('newpass', __('Check your email for your new password.'), 'message'); + elseif (isset($_GET['checkemail']) && 'registered' == $_GET['checkemail']) + $errors->add('registered', __('Registration complete. Please check your email.'), 'message'); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + elseif (strpos($redirect_to, 'about.php?updated')) + $errors->add('updated', __('You have successfully updated WordPress! Please log back in to see what’s new.'), 'message'); + } + + /** + * Filter the login page errors. + * + * @since 3.6.0 + * + * @param object $errors WP Error object. + * @param string $redirect_to Redirect destination URL. + */ + $errors = apply_filters('wp_login_errors', $errors, $redirect_to); + + // Clear any stale cookies. + if ($reauth) + wp_clear_auth_cookie(); + + login_header(__('Log In'), '', $errors); + + if (isset($_POST['log'])) + $user_login = ('incorrect_password' == $errors->get_error_code() || 'empty_password' == $errors->get_error_code()) ? esc_attr(sanitize_text_field(wp_unslash($_POST['log']))) : ''; + $rememberme = ! empty($_POST['rememberme']); + + if (! empty($errors->errors)) { + $aria_describedby_error = ' aria-describedby="login_error"'; + } else { + $aria_describedby_error = ''; + } + + //aiowps - this check is necessary because otherwise if variables are undefined we get a warning! + if (empty($user_login)) { + $user_login = ''; + } + + if (empty($error)) { + $error = ''; + } +?> + +
            +

            + +

            +

            + +

            + +

            +

            + + + + + + + + + + +

            +
            + + + + + + + +` element. + * Default 'Log In'. + * @param string $message Optional. Message to display in header. Default empty. + * @param WP_Error $wp_error Optional. The error to pass. Default is a WP_Error instance. + */ +function login_header($title = 'Log In', $message = '', $wp_error = null) { + global $error, $interim_login, $action; + + // Don't index any of these forms. + add_action('login_head', 'wp_sensitive_page_meta'); + + add_action('login_head', 'wp_login_viewport_meta'); + + if (! is_wp_error($wp_error)) { + $wp_error = new WP_Error(); + } + + // Shake it! + $shake_error_codes = array('empty_password', 'empty_email', 'invalid_email', 'invalidcombo', 'empty_username', 'invalid_username', 'incorrect_password', 'retrieve_password_email_failure'); + /** + * Filters the error codes array for shaking the login form. + * + * @since 3.0.0 + * + * @param array $shake_error_codes Error codes that shake the login form. + */ + $shake_error_codes = apply_filters('shake_error_codes', $shake_error_codes); + + if ($shake_error_codes && $wp_error->has_errors() && in_array($wp_error->get_error_code(), $shake_error_codes, true)) { + add_action('login_footer', 'wp_shake_js', 12); + } + + $login_title = get_bloginfo('name', 'display'); + + /* translators: Login screen title. 1: Login screen name, 2: Network or site name. */ + $login_title = sprintf(__('%1$s ‹ %2$s — WordPress'), $title, $login_title); + + if (wp_is_recovery_mode()) { + /* translators: %s: Login screen title. */ + $login_title = sprintf(__('Recovery Mode — %s'), $login_title); + } + + /** + * Filters the title tag content for login page. + * + * @since 4.9.0 + * + * @param string $login_title The page title, with extra context added. + * @param string $title The original page title. + */ + $login_title = apply_filters('login_title', $login_title, $title); + + ?> + > + + + <?php echo esc_html($login_title); ?> + get_error_code()) { + ?> + + + + + + + + +
            +

            + add('error', $error); + unset($error); + } + + if ($wp_error->has_errors()) { + $errors = ''; + $messages = ''; + + foreach ($wp_error->get_error_codes() as $code) { + $severity = $wp_error->get_error_data($code); + foreach ($wp_error->get_error_messages($code) as $error_message) { + if ('message' === $severity) { + $messages .= ' ' . $error_message . "
            \n"; + } else { + $errors .= ' ' . $error_message . "
            \n"; + } + } + } + + if (! empty($errors)) { + /** + * Filters the error messages displayed above the login form. + * + * @since 2.1.0 + * + * @param string $errors Login error message. + */ + echo '
            ' . wp_kses_post(apply_filters('login_errors', $errors)) . "
            \n"; + } + + if (! empty($messages)) { + /** + * Filters instructional messages displayed above the login form. + * + * @since 2.5.0 + * + * @param string $messages Login messages. + */ + echo '

            ' . wp_kses_post(apply_filters('login_messages', $messages)) . "

            \n"; + } + } +} // End of login_header(). + +/** + * Outputs the footer for the login page. + * + * @since 3.1.0 + * + * @global bool|string $interim_login Whether interim login modal is being displayed. String 'success' + * upon successful login. + * + * @param string $input_id Which input to auto-focus. + */ +function login_footer($input_id = '') { + global $interim_login; + + // Don't allow interim logins to navigate away from the page. + if (! $interim_login) { + ?> +

            + +

            + ', '
            '); + } + + ?> +
            . ?> + + + + +
            + + + + + + + add('empty_username', __('Error: Please enter a username or email address.')); + } elseif (strpos($_POST['user_login'], '@')) { + $user_data = get_user_by('email', trim(wp_unslash($_POST['user_login']))); + if (empty($user_data)) { + $errors->add('invalid_email', __('Error: There is no account with that username or email address.')); + } + } else { + $login = trim(wp_unslash($_POST['user_login'])); + $user_data = get_user_by('login', $login); + } + + /** + * Fires before errors are returned from a password reset request. + * + * @since 2.1.0 + * @since 4.4.0 Added the `$errors` parameter. + * @since 5.4.0 Added the `$user_data` parameter. + * + * @param WP_Error $errors A WP_Error object containing any errors generated + * by using invalid credentials. + * @param WP_User|false $user_data WP_User object if found, false if the user does not exist. + */ + do_action('lostpassword_post', $errors, $user_data); + + /** + * Filters the errors encountered on a password reset request. + * + * The filtered WP_Error object may, for example, contain errors for an invalid + * username or email address. A WP_Error object should always be returned, + * but may or may not contain errors. + * + * If any errors are present in $errors, this will abort the password reset request. + * + * @since 5.5.0 + * + * @param WP_Error $errors A WP_Error object containing any errors generated + * by using invalid credentials. + * @param WP_User|false $user_data WP_User object if found, false if the user does not exist. + */ + $errors = apply_filters('lostpassword_errors', $errors, $user_data); + + if ($errors->has_errors()) { + return $errors; + } + + if (! $user_data) { + $errors->add('invalidcombo', __('Error: There is no account with that username or email address.')); + return $errors; + } + + // Redefining user_login ensures we return the right case in the email. + $user_login = $user_data->user_login; + $user_email = $user_data->user_email; + $key = get_password_reset_key($user_data); + + if (is_wp_error($key)) { + return $key; + } + + if (is_multisite()) { + $site_name = get_network()->site_name; + } else { + /* + * The blogname option is escaped with esc_html on the way into the database + * in sanitize_option. We want to reverse this for the plain text arena of emails. + */ + $site_name = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); + } + + $message = __('Someone has requested a password reset for the following account:') . "\r\n\r\n"; + /* translators: %s: Site name. */ + $message .= sprintf(__('Site Name: %s'), $site_name) . "\r\n\r\n"; + /* translators: %s: User login. */ + $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n"; + $message .= __('If this was a mistake, ignore this email and nothing will happen.') . "\r\n\r\n"; + $message .= __('To reset your password, visit the following address:') . "\r\n\r\n"; + $message .= network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login') . "\r\n\r\n"; + + $requester_ip = $_SERVER['REMOTE_ADDR']; + if ($requester_ip) { + $message .= sprintf( + /* translators: %s: IP address of password reset requester. */ + __('This password reset request originated from the IP address %s.'), + $requester_ip + ) . "\r\n"; + } + + /* translators: Password reset notification email subject. %s: Site title. */ + $title = sprintf(__('[%s] Password Reset'), $site_name); + + /** + * Filters the subject of the password reset email. + * + * @since 2.8.0 + * @since 4.4.0 Added the `$user_login` and `$user_data` parameters. + * + * @param string $title Email subject. + * @param string $user_login The username for the user. + * @param WP_User $user_data WP_User object. + */ + $title = apply_filters('retrieve_password_title', $title, $user_login, $user_data); + + /** + * Filters the message body of the password reset mail. + * + * If the filtered message is empty, the password reset email will not be sent. + * + * @since 2.8.0 + * @since 4.1.0 Added `$user_login` and `$user_data` parameters. + * + * @param string $message Email message. + * @param string $key The activation key. + * @param string $user_login The username for the user. + * @param WP_User $user_data WP_User object. + */ + $message = apply_filters('retrieve_password_message', $message, $key, $user_login, $user_data); + + if ($message && ! wp_mail($user_email, wp_specialchars_decode($title), $message)) { + $errors->add( + 'retrieve_password_email_failure', + sprintf( + /* translators: %s: Documentation URL. */ + __('Error: The email could not be sent. Your site may not be correctly configured to send emails. Get support for resetting your password.'), // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + esc_url(__('https://wordpress.org/support/article/resetting-your-password/')) + ) + ); + return $errors; + } + + return true; +} + +// +// Main. +// + +$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'login'; +$errors = new WP_Error(); + +if (isset($_GET['key'])) { + $action = 'resetpass'; +} + +if (isset($_GET['checkemail'])) { + $action = 'checkemail'; +} + +$default_actions = array( + 'confirm_admin_email', + 'postpass', + 'logout', + 'lostpassword', + 'retrievepassword', + 'resetpass', + 'rp', + 'register', + 'checkemail', + 'confirmaction', + 'login', + WP_Recovery_Mode_Link_Service::LOGIN_ACTION_ENTERED, +); + +// Validate action so as to default to the login screen. +if (! in_array($action, $default_actions, true) && false === has_filter('login_form_' . $action)) { + $action = 'login'; +} + +nocache_headers(); + +header('Content-Type: ' . get_bloginfo('html_type') . '; charset=' . get_bloginfo('charset')); + +if (defined('RELOCATE') && RELOCATE) { // Move flag is set. + if (isset($_SERVER['PATH_INFO']) && ($_SERVER['PATH_INFO'] !== $_SERVER['PHP_SELF'])) { + $_SERVER['PHP_SELF'] = str_replace($_SERVER['PATH_INFO'], '', $_SERVER['PHP_SELF']); + } + + $url = dirname(set_url_scheme('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'])); + + if (get_option('siteurl') !== $url) { + update_option('siteurl', $url); + } +} + +setcookie(TEST_COOKIE, 'WP Cookie check', 0, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true); + +if (SITECOOKIEPATH !== COOKIEPATH) { + setcookie(TEST_COOKIE, 'WP Cookie check', 0, SITECOOKIEPATH, COOKIE_DOMAIN, is_ssl(), true); +} + +/** + * Fires when the login form is initialized. + * + * @since 3.2.0 + */ +do_action('login_init'); + +/** + * Fires before a specified login form action. + * + * The dynamic portion of the hook name, `$action`, refers to the action + * that brought the visitor to the login form. Actions include 'postpass', + * 'logout', 'lostpassword', etc. + * + * @since 2.8.0 + */ +do_action("login_form_{$action}"); + +$http_post = ('POST' === $_SERVER['REQUEST_METHOD']); +$interim_login = isset($_REQUEST['interim-login']); + +/** + * Filters the separator used between login form navigation links. + * + * @since 4.9.0 + * + * @param string $login_link_separator The separator used between login form navigation links. + */ +$login_link_separator = apply_filters('login_link_separator', ' | '); + +switch ($action) { + + case 'confirm_admin_email': + /* + * Note that `is_user_logged_in()` will return false immediately after logging in + * as the current user is not set, see wp-includes/pluggable.php. + * However this action runs on a redirect after logging in. + */ + if (! is_user_logged_in()) { + wp_safe_redirect(wp_login_url()); + exit; + } + + if (! empty($_REQUEST['redirect_to'])) { + $redirect_to = $_REQUEST['redirect_to']; + } else { + $redirect_to = admin_url(); + } + + if (current_user_can('manage_options')) { + $admin_email = get_option('admin_email'); + } else { + wp_safe_redirect($redirect_to); + exit; + } + + /** + * Filters the interval for dismissing the admin email confirmation screen. + * + * If `0` (zero) is returned, the "Remind me later" link will not be displayed. + * + * @since 5.3.1 + * + * @param int $interval Interval time (in seconds). Default is 3 days. + */ + $remind_interval = (int) apply_filters('admin_email_remind_interval', 3 * DAY_IN_SECONDS); + + if (! empty($_GET['remind_me_later'])) { + if (! wp_verify_nonce($_GET['remind_me_later'], 'remind_me_later_nonce')) { + wp_safe_redirect(wp_login_url()); + exit; + } + + if ($remind_interval > 0) { + update_option('admin_email_lifespan', time() + $remind_interval); + } + + $redirect_to = add_query_arg('admin_email_remind_later', 1, $redirect_to); + wp_safe_redirect($redirect_to); + exit; + } + + if (! empty($_POST['correct-admin-email'])) { + if (! check_admin_referer('confirm_admin_email', 'confirm_admin_email_nonce')) { + wp_safe_redirect(wp_login_url()); + exit; + } + + /** + * Filters the interval for redirecting the user to the admin email confirmation screen. + * + * If `0` (zero) is returned, the user will not be redirected. + * + * @since 5.3.0 + * + * @param int $interval Interval time (in seconds). Default is 6 months. + */ + $admin_email_check_interval = (int) apply_filters('admin_email_check_interval', 6 * MONTH_IN_SECONDS); + + if ($admin_email_check_interval > 0) { + update_option('admin_email_lifespan', time() + $admin_email_check_interval); + } + + wp_safe_redirect($redirect_to); + exit; + } + + login_header(__('Confirm your administration email'), '', $errors); + + /** + * Fires before the admin email confirm form. + * + * @since 5.3.0 + * + * @param WP_Error $errors A `WP_Error` object containing any errors generated by using invalid + * credentials. Note that the error object may not contain any errors. + */ + do_action('admin_email_confirm', $errors); + ?> + +
            + + + +

            + +

            +

            + administration email for this website is still correct.'); ?> + %s', __('(opens in a new tab)')); + + printf( + '%s%s', + esc_url($admin_email_help_url), + esc_html__('Why is this important?'), + wp_kses_post($accessibility_text) + ); + ?> +

            +

            + ' . esc_html($admin_email) . '' + ); + ?> +

            +

            + +

            + +
            +
            + + + +
            + 0) : ?> +
            + 'confirm_admin_email', + 'remind_me_later' => wp_create_nonce('remind_me_later_nonce'), + ), + $remind_me_link + ); + ?> + +
            + +
            +
            + + HashPassword(wp_unslash($_POST['post_password'])), $expire, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true); + + wp_safe_redirect(wp_get_referer()); + exit; + + case 'logout': + check_admin_referer('log-out'); + + $user = wp_get_current_user(); + + wp_logout(); + + if (! empty($_REQUEST['redirect_to'])) { + $redirect_to = $_REQUEST['redirect_to']; + $requested_redirect_to = $redirect_to; + } else { + $redirect_to = add_query_arg( + array( + 'loggedout' => 'true', + 'wp_lang' => get_user_locale($user), + ), + wp_login_url() + ); + + $requested_redirect_to = ''; + } + + /** + * Filters the log out redirect URL. + * + * @since 4.2.0 + * + * @param string $redirect_to The redirect destination URL. + * @param string $requested_redirect_to The requested redirect destination URL passed as a parameter. + * @param WP_User $user The WP_User object for the user that's logging out. + */ + $redirect_to = apply_filters('logout_redirect', $redirect_to, $requested_redirect_to, $user); + + wp_safe_redirect($redirect_to); + exit; + + case 'lostpassword': + case 'retrievepassword': + if ($http_post) { + $errors = retrieve_password(); + + if (! is_wp_error($errors)) { + $redirect_to = ! empty($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : 'wp-login.php?checkemail=confirm'; + wp_safe_redirect($redirect_to); + exit; + } + } + + if (isset($_GET['error'])) { + if ('invalidkey' === $_GET['error']) { + $errors->add('invalidkey', __('Your password reset link appears to be invalid. Please request a new link below.')); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + } elseif ('expiredkey' === $_GET['error']) { + $errors->add('expiredkey', __('Your password reset link has expired. Please request a new link below.')); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + } + } + + $lostpassword_redirect = ! empty($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : ''; + /** + * Filters the URL redirected to after submitting the lostpassword/retrievepassword form. + * + * @since 3.0.0 + * + * @param string $lostpassword_redirect The redirect destination URL. + */ + $redirect_to = apply_filters('lostpassword_redirect', $lostpassword_redirect); + + /** + * Fires before the lost password form. + * + * @since 1.5.1 + * @since 5.1.0 Added the `$errors` parameter. + * + * @param WP_Error $errors A `WP_Error` object containing any errors generated by using invalid + * credentials. Note that the error object may not contain any errors. + */ + do_action('lost_password', $errors); + + login_header(__('Lost Password'), '

            ' . __('Please enter your username or email address. You will receive an email message with instructions on how to reset your password.') . '

            ', $errors); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + + $user_login = ''; + + if (isset($_POST['user_login']) && is_string($_POST['user_login'])) { + $user_login = wp_unslash($_POST['user_login']); + } + + ?> + +
            +

            + + +

            + + +

            + +

            +
            + + + get_error_code() === 'expired_key') { + wp_redirect(site_url('wp-login.php?action=lostpassword&error=expiredkey')); + } else { + wp_redirect(site_url('wp-login.php?action=lostpassword&error=invalidkey')); + } + + exit; + } + + $errors = new WP_Error(); + + if (isset($_POST['pass1']) && $_POST['pass1'] !== $_POST['pass2']) { + $errors->add('password_reset_mismatch', __('The passwords do not match.')); + } + + /** + * Fires before the password reset procedure is validated. + * + * @since 3.5.0 + * + * @param WP_Error $errors WP Error object. + * @param WP_User|WP_Error $user WP_User object if the login and reset key match. WP_Error object otherwise. + */ + do_action('validate_password_reset', $errors, $user); + + if ((! $errors->has_errors()) && isset($_POST['pass1']) && ! empty($_POST['pass1'])) { + reset_password($user, $_POST['pass1']); + setcookie($rp_cookie, ' ', time() - YEAR_IN_SECONDS, $rp_path, COOKIE_DOMAIN, is_ssl(), true); + login_header(__('Password Reset'), '

            ' . __('Your password has been reset.') . ' ' . __('Log in') . '

            '); + login_footer(); + exit; + } + + wp_enqueue_script('utils'); + wp_enqueue_script('user-profile'); + + login_header(__('Reset Password'), '

            ' . __('Enter your new password below.') . '

            ', $errors); + ?> +
            + + +
            +

            + +

            + +
            + + + +
            +
            +
            + + +
            +
            + +

            + + +

            + +

            +
            + + + +

            + +

            +
            + + + ' . __('Register For This Site') . '

            ', $errors); + ?> +
            +

            + + +

            +

            + + +

            + +

            + +

            +
            + +

            + +

            +
            + + + add( + 'confirm', + sprintf( + /* translators: %s: Link to the login page. */ + __('Check your email for the confirmation link, then visit the login page.'), + wp_login_url() + ), + 'message' + ); + } elseif ('registered' === $_GET['checkemail']) { + $errors->add( + 'registered', + sprintf( + /* translators: %s: Link to the login page. */ + __('Registration complete. Please check your email, then visit the login page.'), // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + wp_login_url() + ), + 'message' + ); + } + + // This action is documented in wp-login.php + $errors = apply_filters('wp_login_errors', $errors, $redirect_to); + + login_header(__('Check your email'), '', $errors); + login_footer(); + break; + + case 'confirmaction': + if (! isset($_GET['request_id'])) { + wp_die(esc_html__('Missing request ID.')); + } + + if (! isset($_GET['confirm_key'])) { + wp_die(esc_html__('Missing confirm key.')); + } + + $request_id = (int) $_GET['request_id']; + $key = sanitize_text_field(wp_unslash($_GET['confirm_key'])); + $result = wp_validate_user_request_key($request_id, $key); + + if (is_wp_error($result)) { + wp_die($result); + } + + /** + * Fires an action hook when the account action has been confirmed by the user. + * + * Using this you can assume the user has agreed to perform the action by + * clicking on the link in the confirmation email. + * + * After firing this action hook the page will redirect to wp-login a callback + * redirects or exits first. + * + * @since 4.9.6 + * + * @param int $request_id Request ID. + */ + do_action('user_request_action_confirmed', $request_id); + + $message = _wp_privacy_account_request_confirmed_message($request_id); + + login_header(__('User action confirmed.'), $message); + login_footer(); + exit; + + case 'login': + default: + $secure_cookie = ''; + $customize_login = isset($_REQUEST['customize-login']); + + if ($customize_login) { + wp_enqueue_script('customize-base'); + } + + // If the user wants SSL but the session is not SSL, force a secure cookie. + if (! empty($_POST['log']) && ! force_ssl_admin()) { + $user_name = sanitize_user(wp_unslash($_POST['log'])); + $user = get_user_by('login', $user_name); + + if (! $user && strpos($user_name, '@')) { + $user = get_user_by('email', $user_name); + } + + if ($user) { + if (get_user_option('use_ssl', $user->ID)) { + $secure_cookie = true; + force_ssl_admin(true); + } + } + } + + if (isset($_REQUEST['redirect_to'])) { + $redirect_to = $_REQUEST['redirect_to']; + // Redirect to HTTPS if user wants SSL. + if ($secure_cookie && false !== strpos($redirect_to, 'wp-admin')) { + $redirect_to = preg_replace('|^http://|', 'https://', $redirect_to); + } + } else { + $redirect_to = admin_url(); + } + + $reauth = empty($_REQUEST['reauth']) ? false : true; + + $user = wp_signon(array(), $secure_cookie); + + if (empty($_COOKIE[LOGGED_IN_COOKIE])) { + if (headers_sent()) { + $user = new WP_Error( + 'test_cookie', + sprintf( + /* translators: 1: Browser cookie documentation URL, 2: Support forums URL. */ + __('Error: Cookies are blocked due to unexpected output. For help, please see this documentation or try the support forums.'), // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + esc_url(__('https://wordpress.org/support/article/cookies/')), + esc_url(__('https://wordpress.org/support/forums/')) + ) + ); + } elseif (isset($_POST['testcookie']) && empty($_COOKIE[TEST_COOKIE])) { + // If cookies are disabled, we can't log in even with a valid user and password. + $user = new WP_Error( + 'test_cookie', + sprintf( + /* translators: %s: Browser cookie documentation URL. */ + __('Error: Cookies are blocked or not supported by your browser. You must enable cookies to use WordPress.'), // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + esc_url(__('https://wordpress.org/support/article/cookies/#enable-cookies-in-your-browser')) + ) + ); + } + } + + $requested_redirect_to = isset($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : ''; + /** + * Filters the login redirect URL. + * + * @since 3.0.0 + * + * @param string $redirect_to The redirect destination URL. + * @param string $requested_redirect_to The requested redirect destination URL passed as a parameter. + * @param WP_User|WP_Error $user WP_User object if login was successful, WP_Error object otherwise. + */ + $redirect_to = apply_filters('login_redirect', $redirect_to, $requested_redirect_to, $user); + + if (! is_wp_error($user) && ! $reauth) { + if ($interim_login) { + $message = '

            ' . __('You have logged in successfully.') . '

            '; + $interim_login = 'success'; + login_header('', $message); + ?> +
            + + + + + exists() && $user->has_cap('manage_options')) { + $admin_email_lifespan = (int) get_option('admin_email_lifespan'); + + // If `0` (or anything "falsey" as it is cast to int) is returned, the user will not be redirected + // to the admin email confirmation screen. + // This filter is documented in wp-login.php + $admin_email_check_interval = (int) apply_filters('admin_email_check_interval', 6 * MONTH_IN_SECONDS); + + if ($admin_email_check_interval > 0 && time() > $admin_email_lifespan) { + $redirect_to = add_query_arg( + array( + 'action' => 'confirm_admin_email', + 'wp_lang' => get_user_locale($user), + ), + wp_login_url($redirect_to) + ); + } + } + + if ((empty($redirect_to) || 'wp-admin/' === $redirect_to || admin_url() === $redirect_to)) { + // If the user doesn't belong to a blog, send them to user admin. If the user can't edit posts, send them to their profile. + if (is_multisite() && ! get_active_blog_for_user($user->ID) && ! is_super_admin($user->ID)) { + $redirect_to = user_admin_url(); + } elseif (is_multisite() && ! $user->has_cap('read')) { + $redirect_to = get_dashboard_url($user->ID); + } elseif (! $user->has_cap('edit_posts')) { + $redirect_to = $user->has_cap('read') ? admin_url('profile.php') : home_url(); + } + + wp_redirect($redirect_to); + exit; + } + + wp_safe_redirect($redirect_to); + exit; + } + + $errors = $user; + // Clear errors if loggedout is set. + if (! empty($_GET['loggedout']) || $reauth) { + $errors = new WP_Error(); + } + + if (empty($_POST) && $errors->get_error_codes() === array('empty_username', 'empty_password')) { + $errors = new WP_Error('', ''); + } + + if ($interim_login) { + if (! $errors->has_errors()) { + $errors->add('expired', __('Your session has expired. Please log in to continue where you left off.'), 'message'); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + } + } else { + // Some parts of this script use the main login form to display a message. + if (isset($_GET['loggedout']) && $_GET['loggedout']) { + $errors->add('loggedout', __('You are now logged out.'), 'message'); + } elseif (isset($_GET['registration']) && 'disabled' === $_GET['registration']) { + $errors->add('registerdisabled', __('User registration is currently not allowed.')); + } elseif (strpos($redirect_to, 'about.php?updated')) { + $errors->add('updated', __('You have successfully updated WordPress! Please log back in to see what’s new.'), 'message'); + } elseif (WP_Recovery_Mode_Link_Service::LOGIN_ACTION_ENTERED === $action) { + $errors->add('enter_recovery_mode', __('Recovery Mode Initialized. Please log in to continue.'), 'message'); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- This is a WordPress translation. + } elseif (isset($_GET['redirect_to']) && false !== strpos($_GET['redirect_to'], 'wp-admin/authorize-application.php')) { + $query_component = wp_parse_url($_GET['redirect_to'], PHP_URL_QUERY); + parse_str($query_component, $query); + + if (! empty($query['app_name'])) { + /* translators: 1: Website name, 2: Application name. */ + $message = sprintf('Please log in to %1$s to authorize %2$s to connect to your account.', get_bloginfo('name', 'display'), '' . esc_html($query['app_name']) . ''); + } else { + /* translators: %s: Website name. */ + $message = sprintf('Please log in to %s to proceed with authorization.', get_bloginfo('name', 'display')); + } + + $errors->add('authorize_application', $message, 'message'); + } + } + + /** + * Filters the login page errors. + * + * @since 3.6.0 + * + * @param WP_Error $errors WP Error object. + * @param string $redirect_to Redirect destination URL. + */ + $errors = apply_filters('wp_login_errors', $errors, $redirect_to); + + // Clear any stale cookies. + if ($reauth) { + wp_clear_auth_cookie(); + } + + login_header(__('Log In'), '', $errors); + + if (isset($_POST['log'])) { + $user_login = ('incorrect_password' === $errors->get_error_code() || 'empty_password' === $errors->get_error_code()) ? esc_attr(wp_unslash($_POST['log'])) : ''; + } + + $rememberme = ! empty($_POST['rememberme']); + + if ($errors->has_errors()) { + $aria_describedby_error = ' aria-describedby="login_error"'; + } else { + $aria_describedby_error = ''; + } + + wp_enqueue_script('user-profile'); + + //aiowps - this check is necessary because otherwise if variables are undefined we get a warning! + if (empty($user_login)) { + $user_login = ''; + } + if (empty($error)) { + $error = ''; + } + ?> + +
            +

            + + class="input" value="" size="20" autocapitalize="off" /> +

            + +
            + +
            + class="input password-input" value="" size="20" /> + +
            +
            + +

            />

            +

            + + + + + + + + + +

            +
            + + + + get_error_code() === 'invalid_username') { + $login_script .= 'd.value = "";'; + } + } + + $login_script .= 'd.focus(); d.select();'; + $login_script .= '} catch(er) {}'; + $login_script .= '}, 200);'; + $login_script .= "}\n"; // End of wp_attempt_focus(). + + /** + * Filters whether to print the call to `wp_attempt_focus()` on the login screen. + * + * @since 4.8.0 + * + * @param bool $print Whether to print the function call. Default true. + */ + if (apply_filters('enable_login_autofocus', true) && ! $error) { + $login_script .= "wp_attempt_focus();\n"; + } + + // Run `wpOnload()` if defined. + $login_script .= "if (typeof wpOnload === 'function') { wpOnload() }"; + ?> + + + + ` element. + * Default 'Log In'. + * @param string $message Optional. Message to display in header. Default empty. + * @param WP_Error $wp_error Optional. The error to pass. Default is a WP_Error instance. + */ +function login_header($title = 'Log In', $message = '', $wp_error = null) { + global $error, $interim_login, $action; + + // Don't index any of these forms. + add_filter('wp_robots', 'wp_robots_sensitive_page'); + add_action('login_head', 'wp_strict_cross_origin_referrer'); + + add_action('login_head', 'wp_login_viewport_meta'); + + if (! is_wp_error($wp_error)) { + $wp_error = new WP_Error(); + } + + // Shake it! + $shake_error_codes = array('empty_password', 'empty_email', 'invalid_email', 'invalidcombo', 'empty_username', 'invalid_username', 'incorrect_password', 'retrieve_password_email_failure'); + /** + * Filters the error codes array for shaking the login form. + * + * @since 3.0.0 + * + * @param array $shake_error_codes Error codes that shake the login form. + */ + $shake_error_codes = apply_filters('shake_error_codes', $shake_error_codes); + + if ($shake_error_codes && $wp_error->has_errors() && in_array($wp_error->get_error_code(), $shake_error_codes, true)) { + add_action('login_footer', 'wp_shake_js', 12); + } + + $login_title = get_bloginfo('name', 'display'); + + /* translators: Login screen title. 1: Login screen name, 2: Network or site name. */ + $login_title = sprintf(__('%1$s ‹ %2$s — WordPress'), $title, $login_title); + + if (wp_is_recovery_mode()) { + /* translators: %s: Login screen title. */ + $login_title = sprintf(__('Recovery Mode — %s'), $login_title); + } + + /** + * Filters the title tag content for login page. + * + * @since 4.9.0 + * + * @param string $login_title The page title, with extra context added. + * @param string $title The original page title. + */ + $login_title = apply_filters('login_title', $login_title, $title); + + ?> + > + + + <?php echo esc_html($login_title); ?> + get_error_code()) { + ?> + + + + + + + + +
            +

            + add('error', $error); + unset($error); + } + + if ($wp_error->has_errors()) { + $errors = ''; + $messages = ''; + + foreach ($wp_error->get_error_codes() as $code) { + $severity = $wp_error->get_error_data($code); + foreach ($wp_error->get_error_messages($code) as $error_message) { + if ('message' === $severity) { + $messages .= ' ' . $error_message . "
            \n"; + } else { + $errors .= ' ' . $error_message . "
            \n"; + } + } + } + + if (! empty($errors)) { + /** + * Filters the error messages displayed above the login form. + * + * @since 2.1.0 + * + * @param string $errors Login error message. + */ + echo '
            ' . wp_kses_post(apply_filters('login_errors', $errors)) . "
            \n"; + } + + if (! empty($messages)) { + /** + * Filters instructional messages displayed above the login form. + * + * @since 2.5.0 + * + * @param string $messages Login messages. + */ + echo '

            ' . wp_kses_post(apply_filters('login_messages', $messages)) . "

            \n"; + } + } +} // End of login_header(). + +/** + * Outputs the footer for the login page. + * + * @since 3.1.0 + * + * @global bool|string $interim_login Whether interim login modal is being displayed. String 'success' + * upon successful login. + * @global AIO_WP_Security $aio_wp_security + * + * @param string $input_id Which input to auto-focus. + */ +function login_footer($input_id = '') { + global $interim_login, $aio_wp_security; + + // Don't allow interim logins to navigate away from the page. + if (! $interim_login) { + ?> +

            + +

            + ', '
            '); + } + + ?> +
            . ?> + + +
            +
            + + + + 'language-switcher-locales', + 'name' => 'wp_lang', + 'selected' => determine_locale(), + 'show_available_translations' => false, + 'explicit_option_en_us' => true, + 'languages' => $languages, + ); + + /** + * Filters default arguments for the Languages select input on the login screen. + * + * The arguments get passed to the wp_dropdown_languages() function. + * + * @since 5.9.0 + * + * @param array $args Arguments for the Languages select input on the login screen. + */ + wp_dropdown_languages(apply_filters('login_language_dropdown_args', $args)); + ?> + + + + + + + + + + + + + + + + + + + + + +
            +
            + + + + + +
            + + + + + + + 0) { + update_option('admin_email_lifespan', time() + $remind_interval); + } + + $redirect_to = add_query_arg('admin_email_remind_later', 1, $redirect_to); + wp_safe_redirect($redirect_to); + exit; + } + + if (! empty($_POST['correct-admin-email'])) { + if (! check_admin_referer('confirm_admin_email', 'confirm_admin_email_nonce')) { + wp_safe_redirect(wp_login_url()); + exit; + } + + /** + * Filters the interval for redirecting the user to the admin email confirmation screen. + * + * If `0` (zero) is returned, the user will not be redirected. + * + * @since 5.3.0 + * + * @param int $interval Interval time (in seconds). Default is 6 months. + */ + $admin_email_check_interval = (int) apply_filters('admin_email_check_interval', 6 * MONTH_IN_SECONDS); + + if ($admin_email_check_interval > 0) { + update_option('admin_email_lifespan', time() + $admin_email_check_interval); + } + + wp_safe_redirect($redirect_to); + exit; + } + + login_header(__('Confirm your administration email'), '', $errors); + + /** + * Fires before the admin email confirm form. + * + * @since 5.3.0 + * + * @param WP_Error $errors A `WP_Error` object containing any errors generated by using invalid + * credentials. Note that the error object may not contain any errors. + */ + do_action('admin_email_confirm', $errors); + ?> + +
            + + + +

            + +

            +

            + administration email for this website is still correct.'); ?> + %s', __('(opens in a new tab)')); + + printf( + '%s%s', + esc_url($admin_email_help_url), + esc_html__('Why is this important?'), + wp_kses_post($accessibility_text) + ); + ?> +

            +

            + ' . esc_html($admin_email) . '' + ); + ?> +

            +

            + +

            + +
            +
            + + + +
            + 0) : ?> +
            + 'confirm_admin_email', + 'remind_me_later' => wp_create_nonce('remind_me_later_nonce'), + ), + $remind_me_link + ); + ?> + +
            + +
            +
            + + HashPassword(wp_unslash($_POST['post_password'])), $expire, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true); + + wp_safe_redirect(wp_get_referer()); + exit; + + case 'logout': + check_admin_referer('log-out'); + + $user = wp_get_current_user(); + + wp_logout(); + + if (! empty($_REQUEST['redirect_to'])) { + $redirect_to = sanitize_url(wp_unslash($_REQUEST['redirect_to'])); + $requested_redirect_to = $redirect_to; + } else { + $redirect_to = add_query_arg( + array( + 'loggedout' => 'true', + 'wp_lang' => get_user_locale($user), + ), + wp_login_url() + ); + + $requested_redirect_to = ''; + } + + /** + * Filters the log out redirect URL. + * + * @since 4.2.0 + * + * @param string $redirect_to The redirect destination URL. + * @param string $requested_redirect_to The requested redirect destination URL passed as a parameter. + * @param WP_User $user The WP_User object for the user that's logging out. + */ + $redirect_to = apply_filters('logout_redirect', $redirect_to, $requested_redirect_to, $user); + + wp_safe_redirect($redirect_to); + exit; + + case 'lostpassword': + case 'retrievepassword': + if ($http_post) { + $errors = retrieve_password(); + + if (! is_wp_error($errors)) { + $redirect_to = ! empty($_REQUEST['redirect_to']) ? sanitize_url(wp_unslash($_REQUEST['redirect_to'])) : 'wp-login.php?checkemail=confirm'; + wp_safe_redirect($redirect_to); + exit; + } + } + + if (isset($_GET['error'])) { + if ('invalidkey' === $_GET['error']) { + // translators: %s: 'ERROR' + $errors->add('invalidkey', sprintf(__('%s: Your password reset link appears to be invalid.') . ' ' . __('Please request a new link below.'), '' . __('ERROR') . '')); + } elseif ('expiredkey' === $_GET['error']) { + // translators: %s: 'ERROR' + $errors->add('expiredkey', sprintf(__('%s: Your password reset link has expired.') . ' ' . __('Please request a new link below.'), '' . __('ERROR') . '')); + } + } + + $lostpassword_redirect = ! empty($_REQUEST['redirect_to']) ? sanitize_url(wp_unslash($_REQUEST['redirect_to'])) : ''; + /** + * Filters the URL redirected to after submitting the lostpassword/retrievepassword form. + * + * @since 3.0.0 + * + * @param string $lostpassword_redirect The redirect destination URL. + */ + $redirect_to = apply_filters('lostpassword_redirect', $lostpassword_redirect); + + /** + * Fires before the lost password form. + * + * @since 1.5.1 + * @since 5.1.0 Added the `$errors` parameter. + * + * @param WP_Error $errors A `WP_Error` object containing any errors generated by using invalid + * credentials. Note that the error object may not contain any errors. + */ + do_action('lost_password', $errors); + + login_header(__('Lost Password'), '

            ' . __('Please enter your username or email address. You will receive an email message with instructions on how to reset your password.') . '

            ', $errors); // phpcs:ignore UpdraftPlus.Translation.MultipleSentence.MultipleSentenceInsideTranslationFunction -- ignore this to use WordPress translation + + $user_login = ''; + + if (isset($_POST['user_login']) && is_string($_POST['user_login'])) { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized below. + $user_login = wp_unslash($_POST['user_login']); // Remove slashes first + + if (is_email($user_login)) { + // Sanitize as an email address + $user_login = sanitize_email($user_login); + } else { + // Sanitize as a username + $user_login = sanitize_user($user_login, true); + } + } + + ?> + +
            +

            + + +

            + + +

            + +

            +
            + + + get_error_code() === 'expired_key') { + wp_redirect(site_url('wp-login.php?action=lostpassword&error=expiredkey')); + } else { + wp_redirect(site_url('wp-login.php?action=lostpassword&error=invalidkey')); + } + + exit; + } + + $errors = new WP_Error(); + + // Check if password is one or all empty spaces. + if (!empty($_POST['pass1'])) { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Not recommended to sanitize password. + $_POST['pass1'] = trim($_POST['pass1']); + if (empty($_POST['pass1'])) { + $errors->add('password_reset_empty_space', __('The password cannot be a space or all spaces.')); + } + } + + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Not recommended to sanitize password. + if (!empty($_POST['pass1']) && trim($_POST['pass2']) !== $_POST['pass1']) { + $errors->add('password_reset_mismatch', __('Error: The passwords do not match.')); + } + + /** + * Fires before the password reset procedure is validated. + * + * @since 3.5.0 + * + * @param WP_Error $errors WP Error object. + * @param WP_User|WP_Error $user WP_User object if the login and reset key match. WP_Error object otherwise. + */ + do_action('validate_password_reset', $errors, $user); + + if ((! $errors->has_errors()) && isset($_POST['pass1']) && ! empty($_POST['pass1'])) { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Not recommended to sanitize password. + reset_password($user, wp_unslash($_POST['pass1'])); + setcookie($rp_cookie, ' ', time() - YEAR_IN_SECONDS, $rp_path, COOKIE_DOMAIN, is_ssl(), true); + login_header(__('Password Reset'), '

            ' . __('Your password has been reset.') . ' ' . __('Log in') . '

            '); + login_footer(); + exit; + } + + wp_enqueue_script('utils'); + wp_enqueue_script('user-profile'); + + login_header(__('Reset Password'), '

            ' . __('Enter your new password below or generate one.') . '

            ', $errors); + ?> +
            + + +
            +

            + +

            + +
            + + + +
            +
            +
            + + +
            +
            + +

            + + +

            + +

            +
            + + + +

            + + +

            +
            + + + ' . __('Register For This Site') . '

            ', $errors); + ?> +
            +

            + + +

            +

            + + +

            + +

            + +

            +
            + +

            + +

            +
            + + + add( + 'confirm', + sprintf( + /* translators: %s: Link to the login page. */ + __('Check your email for the confirmation link, then visit the login page.'), + wp_login_url() + ), + 'message' + ); + } elseif ('registered' === $_GET['checkemail']) { + $errors->add( + 'registered', + sprintf( + /* translators: %s: Link to the login page. */ + __('Registration complete.') . ' ' . __('Please check your email, then visit the login page.'), + wp_login_url() + ), + 'message' + ); + } + + // This action is documented in wp-login.php + $errors = apply_filters('wp_login_errors', $errors, $redirect_to); + + login_header(__('Check your email'), '', $errors); + login_footer(); + break; + + case 'confirmaction': + if (! isset($_GET['request_id'])) { + wp_die(esc_html__('Missing request ID.')); + } + + if (! isset($_GET['confirm_key'])) { + wp_die(esc_html__('Missing confirm key.')); + } + + $request_id = (int) $_GET['request_id']; + $key = sanitize_text_field(wp_unslash($_GET['confirm_key'])); + $result = wp_validate_user_request_key($request_id, $key); + + if (is_wp_error($result)) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- WP_Error is an object and cannot be escaped. + wp_die($result); + } + + /** + * Fires an action hook when the account action has been confirmed by the user. + * + * Using this you can assume the user has agreed to perform the action by + * clicking on the link in the confirmation email. + * + * After firing this action hook the page will redirect to wp-login a callback + * redirects or exits first. + * + * @since 4.9.6 + * + * @param int $request_id Request ID. + */ + do_action('user_request_action_confirmed', $request_id); + + $message = _wp_privacy_account_request_confirmed_message($request_id); + + login_header(__('User action confirmed.'), $message); + login_footer(); + exit; + + case 'login': + default: + $secure_cookie = ''; + $customize_login = isset($_REQUEST['customize-login']); + + if ($customize_login) { + wp_enqueue_script('customize-base'); + } + + // If the user wants SSL but the session is not SSL, force a secure cookie. + if (! empty($_POST['log']) && ! force_ssl_admin()) { + $user_name = sanitize_user(wp_unslash($_POST['log'])); + $user = get_user_by('login', $user_name); + + if (! $user && strpos($user_name, '@')) { + $user = get_user_by('email', $user_name); + } + + if ($user) { + if (get_user_option('use_ssl', $user->ID)) { + $secure_cookie = true; + force_ssl_admin(true); + } + } + } + + if (isset($_REQUEST['redirect_to'])) { + $redirect_to = sanitize_url(wp_unslash($_REQUEST['redirect_to'])); + // Redirect to HTTPS if user wants SSL. + if ($secure_cookie && false !== strpos($redirect_to, 'wp-admin')) { + $redirect_to = preg_replace('|^http://|', 'https://', $redirect_to); + } + } else { + $redirect_to = admin_url(); + } + + $reauth = empty($_REQUEST['reauth']) ? false : true; + + $user = wp_signon(array(), $secure_cookie); + + if (empty($_COOKIE[LOGGED_IN_COOKIE])) { + if (headers_sent()) { + $user = new WP_Error( + 'test_cookie', + sprintf( + // translators: 1: 'ERROR', 2: 'this documentation'(Browser cookie documentation link), 3: 'support forums'(Support forums link) + __('%1$s: Cookies are blocked due to unexpected output.') . ' ' . __('For help, please see %2$s or try the %3$s.'), + '' . __('ERROR') . '', + '' . __('this documentation') . '', + '' . __('support forums') . '' + ) + ); + } elseif (isset($_POST['testcookie']) && empty($_COOKIE[TEST_COOKIE])) { + // If cookies are disabled, we can't log in even with a valid user and password. + $user = new WP_Error( + 'test_cookie', + sprintf( + // translators: 1: 'ERROR', 2: 'enable cookies'(Browser cookie documentation link) + __('%1$s: Cookies are blocked or not supported by your browser.') . ' ' . __('You must %2$s to use WordPress.'), + '' . __('ERROR') . '', + '' . __('enable cookies') . '' + ) + ); + } + } + + $requested_redirect_to = isset($_REQUEST['redirect_to']) ? sanitize_url(wp_unslash($_REQUEST['redirect_to'])) : ''; + /** + * Filters the login redirect URL. + * + * @since 3.0.0 + * + * @param string $redirect_to The redirect destination URL. + * @param string $requested_redirect_to The requested redirect destination URL passed as a parameter. + * @param WP_User|WP_Error $user WP_User object if login was successful, WP_Error object otherwise. + */ + $redirect_to = apply_filters('login_redirect', $redirect_to, $requested_redirect_to, $user); + + if (! is_wp_error($user) && ! $reauth) { + if ($interim_login) { + $message = '

            ' . __('You have logged in successfully.') . '

            '; + $interim_login = 'success'; + login_header('', $message); + ?> +
            +
            +
            + + <?php esc_html_e('notice image', 'all-in-one-wp-security-and-firewall');?> +
            +
            +

            + +
            + + + + + +
            +

            +

            + +
            + + ' . esc_html($discount_code) . '
            '; + + if (!empty($button_link) && !empty($button_meta) && 'inline' != $button_meta) { + ?> + + +

            +
            +
            +
            +
            + + + +
            +
            +
            +

            + +
            + + + + + +
            +

            +

            + +

            + +

            + + + + + + + + + +

            + + +
            +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/notices/thanks-for-using-main-dash.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/notices/thanks-for-using-main-dash.php new file mode 100755 index 00000000..38d135ec --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/notices/thanks-for-using-main-dash.php @@ -0,0 +1,84 @@ + + +
            + +
            +

            + +

            + + + + +
            +

            + ' . esc_html__('AIOS Premium', 'all-in-one-wp-security-and-firewall') . '' + ); + } + ?> +

            +

            :

            + +

            + ' . esc_html__('Browse more', 'all-in-one-wp-security-and-firewall') . ' ' . '' . esc_html__('Premium WooCommerce plugins', 'all-in-one-wp-security-and-firewall') . ''; ?> +

            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/partials/non-apache-feature-notice.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/partials/non-apache-feature-notice.php new file mode 100755 index 00000000..216995a5 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/partials/non-apache-feature-notice.php @@ -0,0 +1,16 @@ + +
            +

            + ' . esc_html__('Attention:', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('This feature works only on the Apache server.', 'all-in-one-wp-security-and-firewall') . ' '; + /* translators: %s: Server software */ + echo sprintf(esc_html__("You are using the non-apache server %s, so this feature won't work on your site.", 'all-in-one-wp-security-and-firewall'), esc_html(AIOWPSecurity_Utility::get_server_software())); + ?> +

            +
            + +

            +
            + '. esc_html__('A 404 or Not Found error occurs when somebody tries to access a non-existent page on your website.', 'all-in-one-wp-security-and-firewall') . ' +
            ' . esc_html__('Typically, most 404 errors happen quite innocently when people have mis-typed a URL or used an old link to page which doesn\'t exist anymore.', 'all-in-one-wp-security-and-firewall').' +
            ' . esc_html__('However, in some cases you may find many repeated 404 errors which occur in a relatively short space of time and from the same IP address which are all attempting to access a variety of non-existent page URLs.', 'all-in-one-wp-security-and-firewall').' +
            ' . esc_html__('Such behaviour can mean that a hacker might be trying to find a particular page or URL for sinister reasons.', 'all-in-one-wp-security-and-firewall'); + // translators: %1$s - Open strong tag, %2$s - Close strong tag. + echo '
            ' . wp_kses_post(apply_filters('aios_smart_404_notice', __('With this feature enabled, you can use the table below to manually temporarily block IP addresses.', 'all-in-one-wp-security-and-firewall') . '
            ' . sprintf(__('The %1$s Smart 404 %2$s feature in Premium automatically detects and blocks these IP addresses.', 'all-in-one-wp-security-and-firewall'), '', ''))); + ?> +
            + +
            + '.esc_html__('All-In-One Security Premium', 'all-in-one-wp-security-and-firewall').''; + /* translators: %s: Premium upgrade link */ + $info_msg = sprintf(esc_html__('You may also be interested in %s.', 'all-in-one-wp-security-and-firewall'), $premium_plugin_link); + /* translators: 1: open strong tag, 2: close strong tag. */ + $info_msg2 = sprintf(esc_html__('This plugin adds a number of extra features including %1$s and %2$s.', 'all-in-one-wp-security-and-firewall'), ''.esc_html__('smart 404 blocking', 'all-in-one-wp-security-and-firewall').'', ''.esc_html__('country IP blocking', 'all-in-one-wp-security-and-firewall').''); + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variables already escaped. + echo '

            '. $info_msg . '
            ' . $info_msg2 . '

            '; + ?> +
            + + +
            +

            +
            +
            + output_feature_details_badge("firewall-enable-404-blocking"); + ?> +
            +
            + + + + + + + + + + + + + + +
            : +
            + configs->get_value('aiowps_enable_404_IP_lockout')); ?> +
            +
            + +
            + +
            + +
            +
            +
            +
            +
            +

            +
            + ' . esc_html__('This list displays the 404 event logs when somebody tries to access a non-existent page on your website.', 'all-in-one-wp-security-and-firewall').'
            '.sprintf(esc_html__('404 event logs that are older than %1$d days are purged automatically.', 'all-in-one-wp-security-and-firewall'), esc_html(apply_filters('aios_purge_events_records_after_days', AIOS_PURGE_EVENTS_RECORDS_AFTER_DAYS))).'

            '; + + // Fetch, prepare, sort, and filter our data... + $event_list_404->prepare_items(); + // echo "put table of locked entries here"; + ?> +
            + + + search_box(__('Search', 'all-in-one-wp-security-and-firewall'), 'search_404_events'); ?> + '; + } + ?> + + display(); ?> +
            +
            +
            +
            +

            +
            +
            + + + + + +
            + +
            +
            +
            +
            +

            +
            +
            + + + + +
            + +
            +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/captcha-provider.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/captcha-provider.php new file mode 100755 index 00000000..50de4413 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/captcha-provider.php @@ -0,0 +1,93 @@ + +
            +

            +
            + is_login_lockdown_by_const()) { ?> +
            +

            + '.__('To enable it, define AIOS_DISABLE_LOGIN_LOCKOUT constant value as false, or remove it.', 'all-in-one-wp-security-and-firewall'); + ?> +

            +
            + + Cloudflare Turnstile'; + $recaptcha_link = 'Google reCAPTCHA v2'; + echo sprintf('

            ' . __('This feature allows you to add a CAPTCHA form on various WordPress login pages and forms.', 'all-in-one-wp-security-and-firewall') . ' ' . __('Adding a CAPTCHA form on a login page or form is another effective yet simple "Brute Force" prevention technique.', 'all-in-one-wp-security-and-firewall') . + '
            ' . __('You have the option of using either %s, %s or a plain maths CAPTCHA form.', 'all-in-one-wp-security-and-firewall') . '

            ', $turnstile_link, $recaptcha_link); + echo sprintf('

            ' . __('We recommend %s as a more privacy-respecting option than %s', 'all-in-one-wp-security-and-firewall') . '

            ', 'Cloudflare Turnstile', 'Google reCAPTCHA'); + ?> + + + + + +
            : + +
            +
            + + + + + + + + + + + + + +
            +
            + + + +
            + + + +
            +
            +
            + + + + + + + + + +
            +
            + + + +
            +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/captcha-settings.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/captcha-settings.php new file mode 100755 index 00000000..d9607607 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/captcha-settings.php @@ -0,0 +1,64 @@ + +
            + array( + 'title' => __('Wordpress forms', 'all-in-one-wp-security-and-firewall'), + ), + 'woo-captcha' => array( + 'title' => __('Woocommerce forms', 'all-in-one-wp-security-and-firewall'), + 'display_condition_callback' => array('AIOWPSecurity_Utility', 'is_woocommerce_plugin_active'), + ), + 'other-plugins' => array( + 'title' => __('Other forms', 'all-in-one-wp-security-and-firewall'), + 'display_condition_callback' => array('AIOWPSecurity_Utility', 'is_other_form_plugins_active'), + ), + ); + $aio_wp_security->include_template('wp-admin/brute-force/captcha-provider.php', false, array('default_captcha' => $default_captcha, 'supported_captchas' => $supported_captchas, 'captcha_themes' => $captcha_themes, 'captcha_theme' => $captcha_theme)); + + $templates = apply_filters('aiowps_modify_captcha_settings_template', $templates); + + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce check occurred outside of template. + $subtab = isset($_GET['subtab']) ? sanitize_text_field(wp_unslash($_GET['subtab'])) : ''; + ?> +
            > +
            +
            +

            + +
              + $template) { + // Check if the current title is the first title + $title = $template['title']; + $class = 'class="aiowps-template-list-item'; + $class .= ($key === $subtab || $title === $first_title) ? " aiowps-active" : ''; + $class .= '"'; + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- No user input for $class. + echo '
            • ' . esc_html($title) . '
            • '; + } + ?> +
            +
            +
            + $template) { + $aio_wp_security->include_template('wp-admin/brute-force/partials/' . esc_attr($key) . '.php'); + } + ?> +
            +
            +
            +
            + +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php new file mode 100755 index 00000000..e81b0045 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/cookie-based-brute-force-prevention.php @@ -0,0 +1,165 @@ + +

            +
            + ' . esc_html__('A Brute Force Attack is when a hacker tries many combinations of usernames and passwords until they succeed in guessing the right combination.', 'all-in-one-wp-security-and-firewall').'
            ' . esc_html__('Due to the fact that at any one time there may be many concurrent login attempts occurring on your site via malicious automated robots, this also has a negative impact on your server\'s memory and performance.', 'all-in-one-wp-security-and-firewall').'
            ' . esc_html__('The features in this tab will stop the majority of brute force login attacks thus providing even better protection for your WP login page.', 'all-in-one-wp-security-and-firewall') . '

            '; + ?> +
            +
            + ' . esc_html__('Read our tutorial on how to use the cookie-based brute force prevention feature', 'all-in-one-wp-security-and-firewall') . ''; + /* translators: %s: Tutorial link. */ + $info_msg = sprintf(esc_html__('%s.', 'all-in-one-wp-security-and-firewall'), $tutorial_link); + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Data already escaped. + echo '

            ' . $info_msg . '

            '; + ?> +
            +include_template('notices/cookie-based-brute-force-prevention-disabled.php'); + } +?> +
            +
            +

            +
            +
            + output_feature_details_badge("firewall-enable-brute-force-attack-prevention"); + ?> +
            + +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/honeypot.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/honeypot.php new file mode 100755 index 00000000..96e7c392 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/honeypot.php @@ -0,0 +1,51 @@ + +
            +' . esc_html__('This feature allows you to add a special hidden "honeypot" field on WordPress login and registration pages.', 'all-in-one-wp-security-and-firewall'). ' ' . esc_html__('This will only be visible to robots and not humans.', 'all-in-one-wp-security-and-firewall') . '
            ' . esc_html__('Since robots usually fill in every input field on a form, they will also submit a value for the special hidden honeypot field.', 'all-in-one-wp-security-and-firewall') . '
            ' . esc_html__('The way honeypots work is that a hidden field is placed somewhere inside a form which only robots will submit.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('If that field contains a value when the form is submitted then a robot has most likely submitted the form and it is consequently dealt with.', 'all-in-one-wp-security-and-firewall') . '
            ' . esc_html__('Therefore, if the plugin detects that this field has a value when the form is submitted, then the robot which is attempting to submit the form on your site will be redirected to its localhost address - http://127.0.0.1.', 'all-in-one-wp-security-and-firewall') . '

            '; +?> +
            +
            +
            +

            +
            +
            + output_feature_details_badge("login-honeypot"); + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_enable_login_honeypot')); ?> +
            +
            +
            +
            +
            +

            +
            +
            + output_feature_details_badge("registration-honeypot"); + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_enable_registration_honeypot')); ?> +
            +
            +
            +
            + +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/login-whitelist.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/login-whitelist.php new file mode 100755 index 00000000..a622069c --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/login-whitelist.php @@ -0,0 +1,66 @@ + +

            +
            + ' . esc_html__('The All-In-One Security whitelist feature gives you the option of only allowing certain IP addresses or ranges to have access to your WordPress login page.', 'all-in-one-wp-security-and-firewall') . '
            ' . esc_html__('This feature will deny login access for all IP addresses which are not in your whitelist as configured in the settings below.', 'all-in-one-wp-security-and-firewall') . '
            ' . esc_html__('By allowing/blocking IP addresses, you are using the most secure first line of defence because login access will only be granted to whitelisted IP addresses and other addresses will be blocked as soon as they try to access your login page.', 'all-in-one-wp-security-and-firewall') .'

            '; + ?> +
            +
            + ' . sprintf(esc_html__('If you are locked out by the login whitelist feature and you do not have a static IP address, define the following constant %s in wp-config.php to disable the feature.', 'all-in-one-wp-security-and-firewall'), 'define(\'AIOS_DISABLE_LOGIN_WHITELIST\', true);') . '

            '; + ?> +
            +
            + ' . esc_html__('Cookie-Based brute force login prevention', 'all-in-one-wp-security-and-firewall') . ''; + $rename_login_feature_link = '' . esc_html__('Rename login page', 'all-in-one-wp-security-and-firewall') . ''; + /* translators: 1: Brute force link, 2: Rename login link 3: Open strong tag, 4: Close strong tag. */ + echo '

            ' . sprintf(esc_html__('Attention: If in addition to enabling the white list feature, you also have one of the %1$s or %2$s features enabled, %3$s you will still need to use your secret word or special slug in the URL when trying to access your WordPress login page %4$s', 'all-in-one-wp-security-and-firewall'), $brute_force_login_feature_link, $rename_login_feature_link, '', '') . '

            ' . esc_html__('These features are NOT functionally related.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('Having both of them enabled on your site means you are creating 2 layers of security.', 'all-in-one-wp-security-and-firewall') . '

            '; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variables already escaped. + ?> +
            +include_template('notices/disable-login-whitelist.php'); + } +?> +
            +

            +
            +
            + output_feature_details_badge("whitelist-manager-ip-login-whitelisting"); + ?> +
            +
            + + + + + + + + + + + + +
            : +
            + configs->get_value('aiowps_enable_whitelisting')); ?> +
            +
            + +
            + + +
            + +
            + +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/partials/cookie-test-container.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/partials/cookie-test-container.php new file mode 100755 index 00000000..7dbde4a5 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/partials/cookie-test-container.php @@ -0,0 +1,11 @@ +
            +

            + +

            +
            + 'aios-perform-cookie-test')); diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/partials/other-plugins.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/partials/other-plugins.php new file mode 100755 index 00000000..9a4f109e --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/partials/other-plugins.php @@ -0,0 +1,74 @@ + +
            +

            + +
            +
            + output_feature_details_badge("bp-register-captcha"); + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_enable_bp_register_captcha')); ?> +
            +
            +
            + + +
            +
            + output_feature_details_badge("bbp-new-topic-captcha"); + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_enable_bbp_new_topic_captcha')); ?> +
            +
            +
            + + +
            +
            + output_feature_details_badge("contact-form-7-captcha"); + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_enable_contact_form_7_captcha')); ?> + + +
            + '. sprintf(__('%s will automatically try to insert a CAPTCHA field before the form\'s submit button', 'all-in-one-wp-security-and-firewall'), 'AIOS') .'

            '; + echo '

            '. sprintf(__('For the exact placement of the CAPTCHA you can use the following shortcode in your %s template', 'all-in-one-wp-security-and-firewall'), 'Contact Form 7') .'

            '; + echo '
            [' . AIOWPSEC_CAPTCHA_SHORTCODE .']
            '; + echo '

            '. sprintf(__('This feature requires %s version %s or greater', 'all-in-one-wp-security-and-firewall'), 'Contact Form 7', '5.0') .'

            '; + echo '

            '. sprintf(__('The validation message will be displayed only when using %s version %s or greater', 'all-in-one-wp-security-and-firewall'), 'Contact Form 7', '5.6') .'

            '; + ?> +
            +
            +
            +
            + +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/partials/rename-login-notice.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/partials/rename-login-notice.php new file mode 100755 index 00000000..6d1d4baa --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/partials/rename-login-notice.php @@ -0,0 +1,10 @@ +configs->get_value('aiowps_enable_rename_login_page')) { + ?> +
            +

            +

            +

            configs->get_value('aiowps_login_page_slug')); ?>

            +
            + +
            +

            +
            +
            + output_feature_details_badge("woo-login-captcha"); + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_enable_woo_login_captcha')); ?> +
            +
            +
            +
            + output_feature_details_badge("woo-lostpassword-captcha"); + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_enable_woo_lostpassword_captcha')); ?> +
            +
            +
            +
            + output_feature_details_badge("woo-register-captcha"); + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_enable_woo_register_captcha')); ?> +
            +
            +
            +
            + output_feature_details_badge("woo-checkout-captcha"); + ?> +
            + + +
            "> +

            + 'disabled'); + } else { + echo __('Guest checkout allows a customer to place an order without an account or being logged in.', 'all-in-one-wp-security-and-firewall'); + $checkout_checkbox_attributes = array(); + } + ?> +

            +
            + + + + +
            : +
            + configs->get_value('aiowps_enable_woo_checkout_captcha'), $checkout_checkbox_attributes); ?> +
            +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/partials/wordpress-forms.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/partials/wordpress-forms.php new file mode 100755 index 00000000..a7a14461 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/partials/wordpress-forms.php @@ -0,0 +1,114 @@ + +
            +

            +
            +
            + output_feature_details_badge("user-login-captcha"); + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_enable_login_captcha')); ?> +
            +
            +
            +
            +
            + output_feature_details_badge("user-registration-captcha"); + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_enable_registration_page_captcha')); ?> +
            +
            +
            +
            +
            + output_feature_details_badge("lost-password-captcha"); + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_enable_lost_password_captcha')); ?> +
            +
            +
            +
            +
            + output_feature_details_badge("custom-login-captcha"); + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_enable_custom_login_captcha')); ?> +
            +
            +
            +
            +
            + output_feature_details_badge("comment-form-captcha"); + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_enable_comment_captcha')); ?> +
            +
            +
            +
            +
            + output_feature_details_badge("password_protected-captcha"); + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_enable_password_protected_captcha')); ?> +
            +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/rename-login.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/rename-login.php new file mode 100755 index 00000000..367dcc10 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/brute-force/rename-login.php @@ -0,0 +1,55 @@ + +
            + ' . esc_html__('An effective Brute Force prevention technique is to change the default WordPress login page URL.', 'all-in-one-wp-security-and-firewall') . '

            ' . '

            ' . esc_html__('Normally if you wanted to login to WordPress you would type your site\'s home URL followed by wp-login.php.', 'all-in-one-wp-security-and-firewall') . '

            ' . '

            ' . esc_html__('This feature allows you to change the login URL by setting your own slug and renaming the last portion of the login URL which contains the wp-login.php to any string that you like.', 'all-in-one-wp-security-and-firewall') . '

            ' . '

            ' . esc_html__('By doing this, malicious bots and hackers will not be able to access your login page because they will not know the correct login page URL.', 'all-in-one-wp-security-and-firewall') . '

            '; + if (!is_multisite() || 1 == get_current_blog_id()) { + $cookie_based_feature_url = '' . esc_html__('Cookie based brute force prevention', 'all-in-one-wp-security-and-firewall').''; + $white_list_feature_url = '' . esc_html__('Login page white list', 'all-in-one-wp-security-and-firewall').''; + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- URLs escaped above. + echo '

            ' . esc_html__('You may also be interested in the following alternative brute force prevention features:', 'all-in-one-wp-security-and-firewall') . '

            ' . $cookie_based_feature_url . '

            ' . $white_list_feature_url . '

            '; + } + ?> +
            +
            +include_template('wp-admin/brute-force/partials/rename-login-notice.php', false, array('home_url' => $home_url)); +?> +
            +
            +

            +
            +
            + output_feature_details_badge("bf-rename-login-page"); + ?> +
            +
            +
            + ' . esc_html__('This feature can lock you out of admin if it doesn\'t work correctly on your site.', 'all-in-one-wp-security-and-firewall') . ' '. sprintf(esc_html__('Before activating this feature, you must read the following %s.', 'all-in-one-wp-security-and-firewall'), '' . esc_html__('message', 'all-in-one-wp-security-and-firewall').'') . '

            '; + echo '

            ' . esc_html__("NOTE: If you are hosting your site on WPEngine or a provider which performs server caching, you will need to ask the host support people to NOT cache your renamed login page.", 'all-in-one-wp-security-and-firewall') . '

            '; + ?> +
            + + + + + + + + + +
            : +
            + configs->get_value('aiowps_enable_rename_login_page')); ?> +
            +
            + +
            + +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/audit-logs.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/audit-logs.php new file mode 100755 index 00000000..d4e4bd5b --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/audit-logs.php @@ -0,0 +1,18 @@ + +
            +

            +
            + prepare_items(); ?> +
            + + + '; + } + $audit_log_list->search_box(__('Search', 'all-in-one-wp-security-and-firewall'), 'search_audit_events'); + $audit_log_list->display(); + ?> +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/debug-logs.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/debug-logs.php new file mode 100755 index 00000000..2cf1cac6 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/debug-logs.php @@ -0,0 +1,44 @@ + +
            +
            +

            +
            +
            + +
            +
            +
            +
            +
            +

            +
            + prepare_items(); + $debug_log_list->display(); + ?> +
            +
            + +
            + ' . __('This section displays information valuable for diagnosing conflicts, configuration discrepancies, or compatibility concerns with other plugins, themes, or the hosting environment.', 'all-in-one-wp-security-and-firewall') . '

            ' + .'

            ' . __('You can use this information to help troubleshoot issues you may be experiencing with your WordPress site or send a report to the AIOS team.', 'all-in-one-wp-security-and-firewall') . '

            '; + ?> +
            +debug_obj->generate_report(); + + do_action('aiowp_security_after_report_sections'); +?> +
            +

            +
            + debug_obj->generate_report_textarea(esc_html__('All-In-One Security diagnostics report', 'all-in-one-wp-security-and-firewall')); + echo '
            '; + do_action('aiowp_security_additional_report_actions'); + ?> +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/locked-ip.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/locked-ip.php new file mode 100755 index 00000000..94a91989 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/locked-ip.php @@ -0,0 +1,28 @@ + +
            + ' . esc_html__('Login lockout', 'all-in-one-wp-security-and-firewall').''; + echo '

            ' . esc_html__('This tab displays the list of all IP addresses which are currently temporarily locked out.', 'all-in-one-wp-security-and-firewall') . '

            '; + ?> +
            +
            +

            +
            + prepare_items(); + // echo "put table of locked entries here"; + ?> +
            + + + '; + } + ?> + + display(); ?> +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/may-also-like.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/may-also-like.php new file mode 100755 index 00000000..1a8571d5 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/may-also-like.php @@ -0,0 +1,398 @@ + + +
            +
            +

            +

            + + | + +

            +
            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + <?php esc_attr_e('All-In-One Security Free', 'all-in-one-wp-security-and-firewall'); ?> +

            +
            + + <?php esc_attr_e('All-In-One Security Premium', 'all-in-one-wp-security-and-firewall'); ?> +

            +
            +

            +
            + +
            +

            +

            +
            + +

            ' . esc_html__('See all login security features', 'all-in-one-wp-security-and-firewall') . '.'); ?>

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            + +
            +

            +

            +
            + +

            ' . esc_html__('See all firewall features', 'all-in-one-wp-security-and-firewall') . '.'); ?>

            +
            +

            +
            +

            +
            +

            +

            +
            + +

            ' . esc_html__('See all file and database security features', 'all-in-one-wp-security-and-firewall') . '.'); ?>

            +
            +

            +
            +

            +
            +

            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            +

            +
            + +
            +

            +

            +
            +

            +
            +

            +
            +

            +

            +
            +

            +
            +

            +
            +

            +

            +
            +

            +
            +

            +
            +

            +
            + +
            +
            +
            +
            +

            +

            + + | + + | + + | + + | + + | + + | + +

            +
            +
            +
            + UpdraftPlus +

            +

            + +
            +
            + WP-Optimize +

            +

            + +
            +
            + UpdraftCentral +

            +

            + +
            +
            + Easy Updates Manager +

            +

            + + +

            + +
            +
            + + Internal Link Juicer +

            + +

            + +

            +

            + +

            + +
            +
            + WP Overnight +

            +

            + +

            +

            + + +

            + +
            +
            + WP Get API +

            + +

            + +

            + +
            +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/permanent-block.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/permanent-block.php new file mode 100755 index 00000000..40c38212 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/permanent-block.php @@ -0,0 +1,27 @@ + +
            + ' . esc_html__('This tab displays the list of all permanently blocked IP addresses.', 'all-in-one-wp-security-and-firewall') . '

            ' . '

            ' . esc_html__('NOTE: This feature does NOT use the .htaccess file to permanently block the IP addresses so it should be compatible with all web servers running WordPress.', 'all-in-one-wp-security-and-firewall') . '

            '; + ?> +
            +
            +

            +
            + prepare_items(); + ?> +
            + + + search_box(__('Search', 'all-in-one-wp-security-and-firewall'), 'search_permanent_block'); + if (!empty($tab)) { + echo ''; + } + ?> + + display(); ?> +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/widget-bar-chart.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/widget-bar-chart.php new file mode 100755 index 00000000..2050e042 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/widget-bar-chart.php @@ -0,0 +1,47 @@ + +
            + $total) { + $chart_rows[] = array( + date("d-M", strtotime($date)), // Format the date + (int) $total, // Ensure the total is an integer + ); + } + // Combine columns and rows for chart data + $xdays_chart_data = array_merge(array($chart_columns), $chart_rows); + ?> + +
            _chart_div'>
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/widget-summary.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/widget-summary.php new file mode 100755 index 00000000..a40277a4 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/dashboard/widget-summary.php @@ -0,0 +1,29 @@ + +
            + +

            + + + + + + + + + + + + + + + + + + + + + + +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/database-security/database-backup.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/database-security/database-backup.php new file mode 100755 index 00000000..b2be7a8a --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/database-security/database-backup.php @@ -0,0 +1,41 @@ + +
            +

            +
            + +

            + + +

            + + +

            + array('title' => array(), 'href' => array()))); ?> +

            + +
            +
            +
            +

            +
            +

            + + + + UpdraftPlus + + array('title' => array(), 'href' => array()))); + } + ?> +

            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/database-security/database-prefix.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/database-security/database-prefix.php new file mode 100755 index 00000000..57685f2c --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/database-security/database-prefix.php @@ -0,0 +1,58 @@ + +

            +
            + '.esc_html__('Your WordPress database is the most important asset of your website because it contains a lot of your site\'s precious information.', 'all-in-one-wp-security-and-firewall').'
            '.esc_html__('The database is also a target for hackers via methods such as SQL injections and malicious and automated code which targets certain tables.', 'all-in-one-wp-security-and-firewall').'
            '.esc_html__('One way to add a layer of protection for your DB is to change the default WordPress table prefix from "wp_" to something else which will be difficult for hackers to guess.', 'all-in-one-wp-security-and-firewall').'
            '.esc_html__('This feature allows you to easily change the prefix to a value of your choice or to a random value set by this plugin.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            +

            +
            + output_feature_details_badge("db-security-db-prefix"); + ?> +
            +

            + + ' . esc_html__('database backup', 'all-in-one-wp-security-and-firewall') . ''; + /* translators: %s: Backup link. */ + printf(esc_html__('It is recommended that you perform a %s before using this feature', 'all-in-one-wp-security-and-firewall'), $backup_tab_link); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- URL already escaped. + ?> + +

            +
            +
            + + + + + + + + + + +
            : + prefix); ?> + '.esc_html__('Your site is currently using the default WordPress database prefix value of "wp_".', 'all-in-one-wp-security-and-firewall').' '.esc_html__('To increase your site\'s security you should consider changing the database prefix value to another value.', 'all-in-one-wp-security-and-firewall').''; + } + ?> +
            + + +
            + configs->get_value('aiowps_enable_random_prefix')); ?> +
            +
            + +
            +
            + +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/copy-protection.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/copy-protection.php new file mode 100755 index 00000000..db948d02 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/copy-protection.php @@ -0,0 +1,33 @@ + +
            +

            +
            +
            + output_feature_details_badge("enable-copy-protection"); + ?> +
            +
            +
            + '.esc_html__('This feature allows you to disable the ability to select and copy text from your front end.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('When admin user is logged in, the feature is automatically disabled for his session.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_copy_protection')); ?> +
            +
            +
            + +
            +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/file-permissions.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/file-permissions.php new file mode 100755 index 00000000..85843d3d --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/file-permissions.php @@ -0,0 +1,37 @@ + +

            +
            + '.esc_html__('Your WordPress file and folder permission settings govern the accessibility and read/write privileges of the files and folders which make up your WP installation.', 'all-in-one-wp-security-and-firewall').'
            '.esc_html__('Your WP installation already comes with reasonably secure file permission settings for the filesystem.', 'all-in-one-wp-security-and-firewall').'
            '.esc_html__('However, sometimes people or other plugins modify the various permission settings of certain core WP folders or files such that they end up making their site less secure because they chose the wrong permission values.', 'all-in-one-wp-security-and-firewall').'
            '.esc_html__('This feature will scan the critical WP core folders and files and will highlight any permission settings which are insecure.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +'; + echo '

            '.esc_html__('This plugin has detected that your site is running on a Windows server.', 'all-in-one-wp-security-and-firewall').' +
            '.esc_html__('This feature is not applicable for Windows server installations.', 'all-in-one-wp-security-and-firewall').' +

            '; + echo ''; + } else { +?> +
            +

            +
            +
            + output_feature_details_badge("filesystem-file-permissions"); + ?> +
            +
            + + +
            + include_template('wp-admin/filesystem-security/partials/file-permissions-table.php', false, array('files_dirs_to_check' => $files_dirs_to_check, 'file_utility' => $file_utility)); ?> +
            +
            +
            +
            + +

            +
            + '.esc_html($info_msg) . ' ' . esc_html__('By protecting your files and assets, you can help prevent nefarious users gain key information and protect your server\'s resources.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            +
            + array( + 'title' => __('Delete default WP files', 'all-in-one-wp-security-and-firewall') + ), + 'prevent-hotlinks' => array( + 'title' => __('Prevent hotlinking', 'all-in-one-wp-security-and-firewall') + ), + 'php-file-editing' => array( + 'title' => __('Disable PHP file editing', 'all-in-one-wp-security-and-firewall') + ), + ); + $templates = apply_filters('aiowps_modify_file_protection_template', $templates); + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce. + $subtab = isset($_GET['subtab']) ? sanitize_text_field(wp_unslash($_GET['subtab'])) : ''; + ?> +
            +
            +

            + +
              + $template) { + // Check if the current title is the first title + $is_active = ($key === $subtab || $template['title'] === $first_title) ? 'class="aiowps-active"' : ''; + $title = $template['title']; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. $is_active has no user input to escape. + echo '
            • ' . esc_html($title) . '
            • '; + } + ?> +
            +
            +
            + $template) { + $aio_wp_security->include_template('wp-admin/filesystem-security/partials/' . $key . '.php', false, array('show_disallow_file_edit_warning' => $show_disallow_file_edit_warning)); + } + ?> +
            +
            +
            + +
            +
            + diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/filesystem-log-result.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/filesystem-log-result.php new file mode 100755 index 00000000..0ecd6459 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/filesystem-log-result.php @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + +
            ' . esc_html($filepath) . ''); ?>
            +

            '.sprintf(esc_html__('The file %s could not be read', 'all-in-one-wp-security-and-firewall'), '' . esc_html($filepath) . '') . '

            '; +} \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/frames.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/frames.php new file mode 100755 index 00000000..5995ab87 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/frames.php @@ -0,0 +1,34 @@ + +
            +
            +

            +
            +
            + output_feature_details_badge("enable-frame-protection"); + ?> +
            +
            +
            + '.esc_html__('This feature allows you to prevent other sites from displaying any of your content via a frame or iframe.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('When enabled, this feature will set the "X-Frame-Options" parameter to "sameorigin" in the HTTP header.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_prevent_site_display_inside_frame')); ?> +
            +
            +
            + +
            +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/host-system-logs.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/host-system-logs.php new file mode 100755 index 00000000..70764659 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/host-system-logs.php @@ -0,0 +1,29 @@ + +

            +
            + '.esc_html__('Sometimes your hosting platform will produce error or warning logs in a file called "error_log".', 'all-in-one-wp-security-and-firewall').'
            '.esc_html__('Depending on the nature and cause of the error or warning, your hosting server can create multiple instances of this file in numerous directory locations of your WordPress installation.', 'all-in-one-wp-security-and-firewall').'
            '.esc_html__('By occasionally viewing the contents of these logs files you can keep informed of any underlying problems on your system which you might need to address.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            + +
            +

            +
            +

            :

            +
            + +
            + + + +
            +
            + +
            + +
            +
            +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/partials/file-permissions-table.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/partials/file-permissions-table.php new file mode 100755 index 00000000..f06f1622 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/partials/file-permissions-table.php @@ -0,0 +1,27 @@ + + + + + + + + + + + + + show_wp_filesystem_permission_status($file_or_dir['name'], $file_or_dir['path'], $file_or_dir['permissions']); + } + ?> + + + + + + + + + +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/partials/php-file-editing.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/partials/php-file-editing.php new file mode 100755 index 00000000..f363d43b --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/partials/php-file-editing.php @@ -0,0 +1,31 @@ + +
            +

            +
            +
            + '.esc_html__('The WordPress Dashboard by default allows administrators to edit PHP files, such as plugin and theme files.', 'all-in-one-wp-security-and-firewall').'
            '.esc_html__('This is often the first tool an attacker will use if able to login, since it allows code execution.', 'all-in-one-wp-security-and-firewall').'
            '.esc_html__('This feature will disable the ability for people to edit PHP files via the dashboard.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            + output_feature_details_badge("filesystem-file-editing"); + + if ($show_disallow_file_edit_warning) { + echo '

            ' . esc_html__('The DISALLOW_FILE_EDIT constant has already been defined, please remove it before enabling this feature.', 'all-in-one-wp-security-and-firewall') . '
            ' . esc_html__('The constant is likely already defined in your wp-config.php file.', 'all-in-one-wp-security-and-firewall') . '

            '; + } + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_disable_file_editing')); ?> +
            +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/partials/prevent-hotlinks.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/partials/prevent-hotlinks.php new file mode 100755 index 00000000..22b04139 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/partials/prevent-hotlinks.php @@ -0,0 +1,29 @@ + +
            +

            +
            +
            + '.esc_html__('A hotlink is where someone displays an image on their site which is actually located on your site by using a direct link to the source of the image on your server.', 'all-in-one-wp-security-and-firewall'); + echo '
            '.esc_html__('Due to the fact that the image being displayed on the other person\'s site is coming from your server, this can cause leaking of bandwidth and resources for you because your server has to present this image for the people viewing it on someone elses\'s site.', 'all-in-one-wp-security-and-firewall'); + echo '
            '.esc_html__('This feature will prevent people from directly hotlinking images from your site\'s pages by writing some directives in your .htaccess file.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            + output_feature_details_badge("prevent-hotlinking"); + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_prevent_hotlinking')); ?> +
            +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/partials/wp-file-access.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/partials/wp-file-access.php new file mode 100755 index 00000000..2c78af43 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/filesystem-security/partials/wp-file-access.php @@ -0,0 +1,34 @@ + +
            +

            +
            +
            + ' . $info_msg . '

            ' . '

            ' . esc_html__('By deleting these files you are hiding some key pieces of information (such as WordPress version info) from potential hackers.', 'all-in-one-wp-security-and-firewall') . '

            '; + ?> +
            +
            + output_feature_details_badge("auto-delete-wp-files"); + ?> +
            + + + + + +
            + + + +
            + + configs->get_value('aiowps_auto_delete_default_wp_files')); ?> +
            +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/5g.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/5g.php new file mode 100755 index 00000000..16ddde7b --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/5g.php @@ -0,0 +1,35 @@ + +

            +
            +
            +

            +
            + + +
            +
            + + + + + +
            : +
            + configs->get_value('aiowps_enable_5g_firewall')); ?> + + +
            + '.esc_html__('This setting will implement the 5G security firewall protection mechanisms on your site which include the following things:', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('1) Block forbidden characters commonly used in exploitative attacks.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('2) Block malicious encoded URL characters such as the ".css(" string.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('3) Guard against the common patterns and specific exploits in the root portion of targeted URLs.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('4) Stop attackers from manipulating query strings by disallowing illicit characters.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('....and much more.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            +
            +
            +
            + +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/advanced-settings.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/advanced-settings.php new file mode 100755 index 00000000..5f5bb88c --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/advanced-settings.php @@ -0,0 +1,5 @@ + +

            +include_template('wp-admin/firewall/partials/firewall-setup.php'); +$aio_wp_security->include_template('wp-admin/firewall/partials/upgrade-unsafe-http-calls.php', false, $advanced_settings_data); diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/block-and-allow-lists.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/block-and-allow-lists.php new file mode 100755 index 00000000..28fa30ef --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/block-and-allow-lists.php @@ -0,0 +1,87 @@ + +

            +
            + ' . __('The All-In-One Security blacklist feature gives you the option of banning certain host IP addresses or ranges and also user agents.', 'all-in-one-wp-security-and-firewall').' +
            ' . __('This feature will deny total site access for users which have IP addresses or user agents matching those which you have configured in the settings below.', 'all-in-one-wp-security-and-firewall').' +
            ' . __('Black-listed visitors will be blocked as soon as WordPress loads, preventing them from gaining any further access.', 'all-in-one-wp-security-and-firewall').' +

            '; + ?> +
            + +
            + ' . htmlspecialchars(__('All-In-One Security Premium', 'all-in-one-wp-security-and-firewall')) . ''; + $info_msg = sprintf(__('You may also be interested in %s.', 'all-in-one-wp-security-and-firewall'), $premium_plugin_link); + $info_msg2 = sprintf(__('This plugin adds a number of extra features including %s and %s.', 'all-in-one-wp-security-and-firewall'), '' . __('smart 404 blocking', 'all-in-one-wp-security-and-firewall') . '', '' . __('country IP blocking', 'all-in-one-wp-security-and-firewall') . ''); + echo '

            ' . $info_msg . '
            ' . $info_msg2 . '

            '; + ?> +
            + +
            +

            +
            +
            + output_feature_details_badge("blacklist-manager-ip-user-agent-blacklisting"); + ?> +
            +
            +
            +

            + ' . __('please read the following message', 'all-in-one-wp-security-and-firewall') . ''; + echo __('This feature can lock you out of admin if it doesn\'t work correctly on your site.', 'all-in-one-wp-security-and-firewall'). ' ' . sprintf(__('You %s before activating this feature.', 'all-in-one-wp-security-and-firewall'), $read_link); + ?> +

            +
            + + + + + + + + + + + + + +
            : +
            + +
            +
            + +
            + + include_template('info/ip-address-ip-range-info.php');?> +
            + +
            + + + + +
            + ' . __('The user agent string will be checked in a case-insensitive manner.', 'all-in-one-wp-security-and-firewall') . '

            '; + echo '

            ' . __('Each user agent string must be on a new line.', 'all-in-one-wp-security-and-firewall') . '

            '; + echo '

            ' . __('Example 1 - A single user agent string to block:', 'all-in-one-wp-security-and-firewall') . '

            '; + echo '

            SquigglebotBot

            '; + echo '

            ' . __('Example 2 - A list of more than 1 user agent strings to block', 'all-in-one-wp-security-and-firewall') . '

            '; + echo '

            baiduspider
            SquigglebotBot
            SurveyBot
            VoidEYE
            webcrawl.net
            YottaShopping_Bot

            '; + ?> +
            +
            + +
            +
            +
            +include_template('wp-admin/firewall/partials/allowlist.php', false, compact('allowlist')); diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/htaccess-firewall-rules.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/htaccess-firewall-rules.php new file mode 100755 index 00000000..40114012 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/htaccess-firewall-rules.php @@ -0,0 +1,58 @@ + +

            +
            + array( + 'title' => __('Basic firewall settings', 'all-in-one-wp-security-and-firewall') + ), + 'block-debug-log' => array( + 'title' => __('Block debug log', 'all-in-one-wp-security-and-firewall') + ), + 'listing-directory-contents' => array( + 'title' => __('Listing directory content', 'all-in-one-wp-security-and-firewall') + ), + ); + + $templates = apply_filters('aiowps_modify_htaccess_firewall_rules_template', $templates); + + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce. + $subtab = isset($_GET['subtab']) ? sanitize_text_field(wp_unslash($_GET['subtab'])) : ''; + ?> +
            +
            +

            + +
              + $template) { + // Check if the current title is the first title + $is_active = ($key === $subtab || $template['title'] === $first_title) ? 'class="aiowps-active"' : ''; + $title = $template['title']; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. No user input to escape. + echo '
            • ' . esc_attr($title) . '
            • '; + } + ?> +
            +
            +
            + $template) { + $aio_wp_security->include_template('wp-admin/firewall/partials/' . $key . '.php', false, $htaccess_rules_data); + } + ?> +
            +
            +
            + +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/advanced-character-filter.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/advanced-character-filter.php new file mode 100755 index 00000000..04d07f31 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/advanced-character-filter.php @@ -0,0 +1,31 @@ + +
            +

            +
            +
            + output_feature_details_badge("firewall-advanced-character-string-filter"); + ?> +
            + + + + + +
            : +
            + + + +
            +

            + ' . esc_html__('This setting matches for common malicious string patterns and exploits and will produce a 403 error for the hacker attempting the query.', 'all-in-one-wp-security-and-firewall'); + echo '
            ' . esc_html__('NOTE: Some strings for this setting might break some functionality.', 'all-in-one-wp-security-and-firewall'); + ?> +

            +
            +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/advanced-settings-6g.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/advanced-settings-6g.php new file mode 100755 index 00000000..093b23c9 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/advanced-settings-6g.php @@ -0,0 +1,70 @@ + +

            + + + +
            + + + + + + + + +
            : +
            + + + + + +
            + ' . esc_html__('Some WooCommerce extensions use the PUT request method in addition to GET and POST.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__("This means WooCommerce users shouldn't block the PUT request method.", 'all-in-one-wp-security-and-firewall') . '

            '; + echo '

            ' . esc_html__('A few REST requests use the PUT request method.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('If your site is communicated by the WP REST API, you should not block the PUT request method.', 'all-in-one-wp-security-and-firewall') . '

            '; + ?> +
            +
            + +
            +
            +

            + + + +
            + + + + + + + + + + + + + + + + + +
            : +
            + +
            +
            : +
            + +
            +
            : +
            + +
            +
            : +
            + +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/allowlist.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/allowlist.php new file mode 100755 index 00000000..32458129 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/allowlist.php @@ -0,0 +1,19 @@ +
            +

            +
            +
            +

            +
            +
            +

            +
            +
            + + + + +
            + +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/bad-query-strings.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/bad-query-strings.php new file mode 100755 index 00000000..01d3356a --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/bad-query-strings.php @@ -0,0 +1,30 @@ + +
            +

            +
            +
            + output_feature_details_badge("firewall-deny-bad-queries"); + ?> +
            + + + + + +
            : +
            + + + +
            +

            + '.esc_html__('NOTE: Some of these strings might be used for plugins or themes and hence this might break some functionality.', 'all-in-one-wp-security-and-firewall'); + ?> +

            +
            +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/basic-firewall-settings.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/basic-firewall-settings.php new file mode 100755 index 00000000..951aa9ef --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/basic-firewall-settings.php @@ -0,0 +1,42 @@ + +
            +

            +
            +
            + output_feature_details_badge("firewall-basic-rules"); + ?> +
            + + + + + + + + + + +
            : +
            + + + +
            + '.esc_html__('This setting will implement the following basic firewall protection mechanisms on your site:', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('1) Protect your htaccess file by denying access to it.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('2) Disable the server signature.', 'all-in-one-wp-security-and-firewall').'

            '; + /* translators: %s: Upload limit. */ + echo '

            '.sprintf(esc_html__('3) Limit file upload size (%sMB).', 'all-in-one-wp-security-and-firewall'), esc_html(AIOS_FIREWALL_MAX_FILE_UPLOAD_LIMIT_MB)).'

            '; + echo '

            '.esc_html__('4) Protect your wp-config.php file by denying access to it.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('The above firewall features will be applied via your .htaccess file and should not affect your site\'s overall functionality.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('You are still advised to take a backup of your active .htaccess file just in case.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            +
            + + +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/blank-ref-and-useragent.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/blank-ref-and-useragent.php new file mode 100755 index 00000000..5b449a45 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/blank-ref-and-useragent.php @@ -0,0 +1,27 @@ + + + + +
            + output_feature_details_badge("firewall-ban-post-blank-headers"); + ?> +
            + + + + + +
            : +
            + + + +
            + '.esc_html__('This feature will check whether the user-agent and referer HTTP headers are blank.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('If they are both blank, the IP address associated with the request will be added to your permanent block list.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/block-debug-log.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/block-debug-log.php new file mode 100755 index 00000000..4464bd9e --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/block-debug-log.php @@ -0,0 +1,30 @@ + +
            +

            +
            +
            + output_feature_details_badge("firewall-block-debug-file-access"); + ?> +
            + + + + + +
            : +
            + + + +
            + ' . esc_html__('WordPress has an option to turn on the debug logging to a file located in wp-content/debug.log.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('This file may contain sensitive information.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            ' . esc_html__('Using this option will block external access to this file.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('You can still access this file by logging into your site via FTP.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            +
            +
            + \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/disable-rss-atom.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/disable-rss-atom.php new file mode 100755 index 00000000..07b87b3e --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/disable-rss-atom.php @@ -0,0 +1,30 @@ + +
            +

            +
            +
            + output_feature_details_badge("firewall-disable-rss-and-atom"); + ?> +
            + + + + + +
            +
            + + + +
            + ' . esc_html__('Most users will want to share their site content widely, but some may prefer to prevent automated site scraping.', 'all-in-one-wp-security-and-firewall').'

            '; + /* translators: %s: FAQ URL. */ + echo '

            ' . sprintf(esc_html__('For more information, check the %s', 'all-in-one-wp-security-and-firewall'), '' . esc_html__('documentation', 'all-in-one-wp-security-and-firewall').'').'

            '; + ?> +
            +
            +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/disable-trace.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/disable-trace.php new file mode 100755 index 00000000..10d5289d --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/disable-trace.php @@ -0,0 +1,34 @@ + +
            +

            +
            +
            + output_feature_details_badge("firewall-disable-trace-track"); + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_disable_trace_and_track')); ?> + + +
            +

            + '; + esc_html_e('This hacking technique is usually used together with cross site scripting attacks (XSS).', 'all-in-one-wp-security-and-firewall'); + echo '
            '; + esc_html_e('Disabling trace and track on your site will help prevent HTTP Trace attacks.', 'all-in-one-wp-security-and-firewall'); + ?> +

            +
            +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/fake-googlebots.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/fake-googlebots.php new file mode 100755 index 00000000..fad89207 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/fake-googlebots.php @@ -0,0 +1,44 @@ + +
            + ' . esc_html__('This feature allows you to block bots which are impersonating as a Googlebot but actually aren\'t. (In other words they are fake Google bots)', 'all-in-one-wp-security-and-firewall') . '

            '; + $info_msg .= '

            '. esc_html__('Googlebots have a unique identity which cannot easily be forged and this feature will identify any fake Google bots and block them from reading your site\'s pages.', 'all-in-one-wp-security-and-firewall').'

            '; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variable already escaped. + echo $info_msg; + ?> +
            +
            + '. esc_html__('Attention', 'all-in-one-wp-security-and-firewall').': '.__('Sometimes non-malicious Internet organizations might have bots which impersonate as a "Googlebot".', 'all-in-one-wp-security-and-firewall').'

            '; + $info_msg_2 .= '

            '.esc_html__('Just be aware that if you activate this feature the plugin will block all bots which use the "Googlebot" string in their User Agent information but are NOT officially from Google (irrespective of whether they are malicious or not).', 'all-in-one-wp-security-and-firewall').'

            '; + $info_msg_2 .= '

            '.esc_html__('All other bots from other organizations such as "Yahoo", "Bing" etc will not be affected by this feature.', 'all-in-one-wp-security-and-firewall').'

            '; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variable already escaped. + echo $info_msg_2; + ?> +
            + + +
            + output_feature_details_badge("firewall-block-fake-googlebots"); + ?> +
            + + + + + +
            : +
            + + + +
            + '.esc_html__('This feature will check if the User Agent information of a bot contains the string "Googlebot".', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('It will then perform a few tests to verify if the bot is legitimately from Google and if so it will allow the bot to proceed.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('If the bot fails the checks then the plugin will mark it as being a fake Googlebot and it will block it', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/firewall-downgrade-button.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/firewall-downgrade-button.php new file mode 100755 index 00000000..08c957b9 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/firewall-downgrade-button.php @@ -0,0 +1,5 @@ + +
            + + +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/firewall-set-up-button.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/firewall-set-up-button.php new file mode 100755 index 00000000..73273e83 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/firewall-set-up-button.php @@ -0,0 +1,5 @@ + +
            + + +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/firewall-setup.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/firewall-setup.php new file mode 100755 index 00000000..fe7755a1 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/firewall-setup.php @@ -0,0 +1,30 @@ + +
            +

            +
            +
            +

            +
            +
            +

            +
            + + + + + +
            : +
            + include_template('wp-admin/firewall/partials/firewall-downgrade-button.php') : $aio_wp_security->include_template('wp-admin/firewall/partials/firewall-set-up-button.php'); ?> +
            + + +
            +

            :

            + +

            :

            + +

            +

            +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/internet-bots.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/internet-bots.php new file mode 100755 index 00000000..c09910c5 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/internet-bots.php @@ -0,0 +1,23 @@ + +
            +

            +
            +
            + '.esc_html__('What is an Internet Bot', 'all-in-one-wp-security-and-firewall').''; + /* translators: s%: Wiki URL. */ + $info_msg .= '

            '.sprintf(__('%s?', 'all-in-one-wp-security-and-firewall'), $wiki_link).'

            '; + + $info_msg .= '

            '. esc_html__('A bot is a piece of software which runs on the Internet and performs automatic tasks.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('For example when Google indexes your pages it uses bots to achieve this task.', 'all-in-one-wp-security-and-firewall').'

            '; + $info_msg .= '

            '. esc_html__('A lot of bots are legitimate and non-malicious but not all bots are good and often you will find some which try to impersonate legitimate bots such as "Googlebot" but in reality they have nohing to do with Google at all.', 'all-in-one-wp-security-and-firewall').'

            '; + $info_msg .= '

            '. esc_html__('Although most of the bots out there are relatively harmless sometimes website owners want to have more control over which bots they allow into their site.', 'all-in-one-wp-security-and-firewall').'

            '; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variable already escaped. + echo $info_msg; + ?> +
            + + include_template('wp-admin/firewall/partials/fake-googlebots.php', false, compact('aiowps_block_fake_googlebots')); ?> + include_template('wp-admin/firewall/partials/blank-ref-and-useragent.php', false, compact('aiowps_ban_post_blank_headers')); ?> +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/listing-directory-contents.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/listing-directory-contents.php new file mode 100755 index 00000000..fcc47616 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/listing-directory-contents.php @@ -0,0 +1,34 @@ + +
            +

            +
            +
            + output_feature_details_badge("firewall-disable-index-views"); + ?> +
            + + + + + +
            : +
            + + + +
            +

            + '; + esc_html_e('This feature will prevent the listing of contents for all directories.', 'all-in-one-wp-security-and-firewall'); + echo '
            '; + echo esc_html__('NOTE: In order for this feature to work "AllowOverride" of the Indexes directive must be enabled in your httpd.conf file.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('Ask your hosting provider to check this if you don\'t have access to httpd.conf', 'all-in-one-wp-security-and-firewall'); + ?> +

            +
            +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/ng.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/ng.php new file mode 100755 index 00000000..29d7c11e --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/ng.php @@ -0,0 +1,56 @@ + + +
            +

            +
            +
            + '.sprintf(esc_html__('This feature allows you to activate the %1$s (or legacy %2$s) firewall security protection rules designed and produced by %3$s.', 'all-in-one-wp-security-and-firewall'), '6G', '5G', 'Perishable Press').'

            '; + $info_msg .= '

            '.esc_html__('The 6G firewall is an updated and improved version of the 5G firewall that is PHP-based and doesn\'t use a .htaccess file.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('If you have the 5G firewall active, you might consider activating the 6G firewall instead.', 'all-in-one-wp-security-and-firewall').'

            '; + $info_msg .= '

            '.esc_html__('The 6G firewall is a simple, flexible blacklist that helps reduce the number of malicious URL requests that hit your website.', 'all-in-one-wp-security-and-firewall').'

            '; + $info_msg .= '

            '.esc_html__('The added advantage of applying the 6G firewall to your site is that it has been tested and confirmed by the people at PerishablePress.com to be an optimal and least disruptive set of security rules for general WP sites.', 'all-in-one-wp-security-and-firewall').'

            '; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variable already escaped. + echo $info_msg; + ?> +
            +
            + output_feature_details_badge("firewall-enable-6g"); + ?> +
            + + + + + +
            : +
            + + + +
            + '.esc_html__('This setting will implement the 6G security firewall protection mechanisms on your site which include the following things:', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('1) Block forbidden characters commonly used in exploitative attacks.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('2) Block malicious encoded URL characters such as the ".css(" string.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('3) Guard against the common patterns and specific exploits in the root portion of targeted URLs.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('4) Stop attackers from manipulating query strings by disallowing illicit characters.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('....and much more.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            +
            + + +
            + include_template('wp-admin/firewall/partials/advanced-settings-6g.php', false, array('methods' => $ng_settings['methods'], 'blocked_query' => $ng_settings['blocked_query'], 'blocked_request' => $ng_settings['blocked_request'], 'blocked_referrers' => $ng_settings['blocked_referrers'], 'blocked_agents' => $ng_settings['blocked_agents'], 'block_request_methods' => $ng_settings['block_request_methods'])); ?> +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/proxy-comment.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/proxy-comment.php new file mode 100755 index 00000000..f80849db --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/proxy-comment.php @@ -0,0 +1,30 @@ + +
            +

            +
            +
            + output_feature_details_badge("firewall-forbid-proxy-comments"); + ?> +
            + + + + + +
            : +
            + + + +
            +

            + '.esc_html__('By forbidding proxy comments you are in effect eliminating some spam and other proxy requests.', 'all-in-one-wp-security-and-firewall'); + ?> +

            +
            +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/rest-route-whitelist.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/rest-route-whitelist.php new file mode 100755 index 00000000..b4bca264 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/rest-route-whitelist.php @@ -0,0 +1,21 @@ + +
            +

            wp:') . ' ' . esc_html__('This route is essential for the WordPress block editor and API integrations.', 'all-in-one-wp-security-and-firewall') . ' ' .esc_html__('Disabling it may break plugins and themes.', 'all-in-one-wp-security-and-firewall');?>

            +

            oembed:') . ' ' . esc_html__('Disabling this may prevent your site\'s content from being embedded in social media and other platforms.', 'all-in-one-wp-security-and-firewall');?>

            +
            +
            + + + + + + + +
            : + +
            + +
            +
            + +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/upgrade-unsafe-http-calls.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/upgrade-unsafe-http-calls.php new file mode 100755 index 00000000..16b345b4 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/upgrade-unsafe-http-calls.php @@ -0,0 +1,48 @@ + +
            +

            +
            +
            + output_feature_details_badge('upgrade-unsafe-http-calls'); + ?> +
            +
            +
            + ' . sprintf(esc_html__('This feature allows you to upgrade all unsafe HTTP calls on your site using %1$s to %2$s.', 'all-in-one-wp-security-and-firewall'), 'wp_remote_*', 'wp_safe_remote_*') . '

            '; + /* translators: %s Bold unsafe function name. */ + echo '

            ' . sprintf(esc_html__('You can also specify a list of URLs that are allowed to be contacted with the unsafe %s calls.', 'all-in-one-wp-security-and-firewall'), 'wp_remote_*') . '

            '; + ?> +
            + + + + + + + + + +
            : +
            + +
            +
            + +
            + + + +
            + ' . esc_html__('Each URL must be on a new line.', 'all-in-one-wp-security-and-firewall') . '

            '; + echo '

            ' . esc_html__('All localhost URLs are already an exception.', 'all-in-one-wp-security-and-firewall') . '

            '; + ?> +
            +
            + +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/wp-rest-api.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/wp-rest-api.php new file mode 100755 index 00000000..d2467cb0 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/wp-rest-api.php @@ -0,0 +1,59 @@ + + +
            +

            +
            +
            +
            + output_feature_details_badge("disallow-unauthorised-requests"); + ?> +
            +
            + '.esc_html__('This feature allows you to block WordPress REST API access for unauthorized requests.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('When enabled this feature will only allow REST requests to be processed if the user is logged in.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('Only REST requests made by logged-in users with a role permitted below will succeed, unless the REST API endpoint has been white-listed for others to also use.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('You can whitelist REST routes by selecting from the list of all registered rest routes for all users, including those who are not logged in.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            + +
            +

            + +

            +
            + + + + + + + + + + +
            : +
            + +
            +
            : + $name) { ?> +
            + +
            +
            + +
            +
            "> + include_template('wp-admin/firewall/partials/rest-route-whitelist.php', false, compact('route_namespaces', 'aios_whitelisted_rest_routes')); ?> +
            +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php new file mode 100755 index 00000000..e84c3971 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/xmlrpc-pingback-protection.php @@ -0,0 +1,52 @@ + +
            +

            +
            +
            + output_feature_details_badge("firewall-pingback-rules"); + ?> +
            + include_template('wp-admin/firewall/partials/xmlrpc-warning-notice.php'); ?> + + + + + + + + + +
            : +
            + + + +
            + '.esc_html__('This setting will disable access to the WordPress xmlrpc.php file which is responsible for the XML-RPC functionality in WordPress.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('Hackers can exploit various vulnerabilities in the WordPress XML-RPC API in a number of ways such as:', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('1) Denial of Service (DoS) attacks', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('2) Hacking internal routers.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('3) Scanning ports in internal networks to get info from various hosts.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('Apart from the security protection benefit, this feature may also help reduce load on your server, particularly if your site currently has a lot of unwanted traffic hitting the XML-RPC API on your installation.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('NOTE: You should only enable this feature if you are not currently using the XML-RPC functionality on your WordPress installation.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('Leave this feature disabled and use the feature below if you want pingback protection but you still need XMLRPC.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            +
            : +
            + + + +
            + '.esc_html__('NOTE: If you use Jetpack or the Wordpress iOS or other apps then you should enable this feature but leave the "Completely Block Access To XMLRPC" checkbox unchecked.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('The feature will still allow XMLRPC functionality on your site but will disable the pingback methods.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('This feature will also remove the "X-Pingback" header if it is present.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/xmlrpc-warning-notice.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/xmlrpc-warning-notice.php new file mode 100755 index 00000000..266da3f3 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/partials/xmlrpc-warning-notice.php @@ -0,0 +1,11 @@ + + +
            +

            + '.esc_html__('Attention:', 'all-in-one-wp-security-and-firewall').' '.esc_html__('You have enabled the "Completely Block Access To XMLRPC" checkbox which means all XMLRPC functionality will be blocked.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('By leaving this feature enabled you will prevent Jetpack or Wordpress iOS or other apps which need XMLRPC from working correctly on your site.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('If you still need XMLRPC then uncheck the "Completely Block Access To XMLRPC" checkbox and enable only the "Disable Pingback Functionality From XMLRPC" checkbox.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +

            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/php-firewall-rules.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/php-firewall-rules.php new file mode 100755 index 00000000..6acf10d8 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/firewall/php-firewall-rules.php @@ -0,0 +1,81 @@ + + +

            +
            + array( + 'title' => __('Security enhancements', 'all-in-one-wp-security-and-firewall'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ), + 'disable-rss-atom' => array( + 'title' => __('Feed control', 'all-in-one-wp-security-and-firewall'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ), + 'proxy-comment' => array( + 'title' => __('Comment protection', 'all-in-one-wp-security-and-firewall'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ), + 'bad-query-strings' => array( + 'title' => __('URL security', 'all-in-one-wp-security-and-firewall'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ), + 'advanced-character-filter' => array( + 'title' => __('String filtering', 'all-in-one-wp-security-and-firewall'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ), + 'ng' => array( + 'title' => __('nG firewall rules', 'all-in-one-wp-security-and-firewall'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ), + 'wp-rest-api' => array( + 'title' => __('WP REST API', 'all-in-one-wp-security-and-firewall') + ), + 'internet-bots' => array( + 'title' => __('Internet bot settings', 'all-in-one-wp-security-and-firewall'), + 'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'), + ) + ); + + $templates = apply_filters('aiowps_modify_php_firewall_rules_template', $templates); + + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce. + $subtab = isset($_GET['subtab']) ? sanitize_text_field(wp_unslash($_GET['subtab'])) : ''; + ?> +
            +
            +

            + +
              + $template) { + // Check if the current title is the first title + $is_active = ($key === $subtab || $template['title'] === $first_title) ? 'class="aiowps-active"' : ''; + $title = $template['title']; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. No user input to escape. + echo '
            • ' . esc_html($title) . '
            • '; + } + ?> +
            +
            +
            + $template) { + $aio_wp_security->include_template('wp-admin/firewall/partials/' . esc_attr($key) . '.php', false, $php_firewall_data); + } + ?> +
            +
            +
            + +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/general/moved.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/general/moved.php new file mode 100755 index 00000000..e07a3ed9 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/general/moved.php @@ -0,0 +1,28 @@ + + array( + 'title' => __('6G firewall rules', 'all-in-one-wp-security-and-firewall'), + 'uri' => 'aiowpsec_firewall&tab=php-rules&subtab=ng' + ), + 'internet-bots' => array( + 'title' => __('Internet bots', 'all-in-one-wp-security-and-firewall'), + 'uri' => 'aiowpsec_firewall&tab=php-rules&subtab=internet-bots' + ), +); + +if (empty($info)) return; +?> +
            +

            +
            + ' . esc_html__('here', 'all-in-one-wp-security-and-firewall') . ''; + echo '

            '; + /* translators: 1: Old location 2: New location */ + echo sprintf(esc_html__('The %1$s feature is now located %2$s.', 'all-in-one-wp-security-and-firewall'), esc_html($info[$key]['title']), $new_location_link) . ' ' . esc_html__('This page will be removed in a future release.', 'all-in-one-wp-security-and-firewall'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Link already escaped. + echo '

            '; + ?> +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/scanner/file-change-detect.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/scanner/file-change-detect.php new file mode 100755 index 00000000..bf99a7b0 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/scanner/file-change-detect.php @@ -0,0 +1,148 @@ + +

            ' . esc_html__('The scan has detected that there was a change in your website\'s files.', 'all-in-one-wp-security-and-firewall') .' '.esc_html__('View the scan results and clear this message', 'all-in-one-wp-security-and-firewall').'

            '; + } +?> +
            + ' . esc_html__('If given an opportunity hackers can insert their code or files into your system which they can then use to carry out malicious acts on your site.', 'all-in-one-wp-security-and-firewall') .'
            ' . esc_html__('Being informed of any changes in your files can be a good way to quickly prevent a hacker from causing damage to your website.', 'all-in-one-wp-security-and-firewall') .'
            ' . esc_html__('In general, WordPress core and plugin files and file types such as ".php" or ".js" should not change often and when they do, it is important that you are made aware when a change occurs and which file was affected.', 'all-in-one-wp-security-and-firewall') .'
            ' . esc_html__('The "File Change Detection Feature" will notify you of any file change which occurs on your system, including the addition and deletion of files by performing a regular automated or manual scan of your system\'s files.', 'all-in-one-wp-security-and-firewall') .'
            ' . esc_html__('This feature also allows you to exclude certain files or folders from the scan in cases where you know that they change often as part of their normal operation. (For example log files and certain caching plugin files may change often and hence you may choose to exclude such files from the file change detection scan)', 'all-in-one-wp-security-and-firewall') . '

            '; + ?> +
            +
            +
            +
            +
            + +
            +
            + ' . esc_html__('Nothing is currently scheduled', 'all-in-one-wp-security-and-firewall') . ''; + } else { + echo '' . esc_html($next_fcd_scan_time) . ''; + } + ?> +
            +
            +
            +
            + +
            +
            + + ' . esc_html__('View the last file scan results', 'all-in-one-wp-security-and-firewall') . ''; + } else { + esc_html_e('No previous scan results', 'all-in-one-wp-security-and-firewall'); + } + ?> + +
            +
            +
            + + + +
            +
            +
            + +

            +
            +
            + +
            +
            +
            +
            +
            +

            +
            +
            + output_feature_details_badge('scan-file-change-detection'); + ?> +
            +
            +
            + + + + + + + + + + + + + + + + + + + + + +
            : +
            + +
            +
            + + +
            + +
            + + + +
            + ' . esc_html__('You can exclude file types from the scan which would not normally pose any security threat if they were changed.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('These can include things such as image files.', 'all-in-one-wp-security-and-firewall') . '

            '; + /* translators: 1. JPG, 2. PNG, 3. BMP. */ + echo '

            ' . sprintf(esc_html__('Example: If you want the scanner to ignore files of type %1$s, %2$s, and %3$s, then you would enter the following:', 'all-in-one-wp-security-and-firewall'), 'jpg', 'png', 'bmp'). '

            '; + echo '

            ' . 'jpg' . '

            '; + echo '

            ' . 'png' . '

            '; + echo '

            ' . 'bmp' . '

            '; + ?> +
            +
            + +
            + + + +
            + ' . esc_html__('You can exclude specific files/directories from the scan which would not normally pose any security threat if they were changed.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('These can include things such as log files.', 'all-in-one-wp-security-and-firewall') . '

            '; + echo '

            ' . esc_html__('Example: If you want the scanner to ignore certain files in different directories or whole directories, then you would enter the following:', 'all-in-one-wp-security-and-firewall') . '

            '; + echo '

            ' . 'cache/config/master.php' . '

            '; + echo '

            ' . esc_html__('somedirectory', 'all-in-one-wp-security-and-firewall') . '

            '; + ?> +
            +
            + + +
            + +
            +
            + +
            + +
            + +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/scanner/malware-scan.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/scanner/malware-scan.php new file mode 100755 index 00000000..fafe5198 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/scanner/malware-scan.php @@ -0,0 +1,25 @@ + +
            + ' . esc_html__('What is malware?', 'all-in-one-wp-security-and-firewall').''; + echo '

            ' . esc_html__('The word malware stands for malicious software.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('It can consist of things like trojan horses, adware, worms, spyware and any other undesirable code which a hacker will try to inject into your website.', 'all-in-one-wp-security-and-firewall') . '

            ' .'

            ' . esc_html__('Often when malware code has been inserted into your site you will normally not notice anything out of the ordinary based on appearances, but it can have a dramatic effect on your site\'s search ranking.', 'all-in-one-wp-security-and-firewall') . '

            ' .'

            ' . esc_html__('This is because the bots and spiders from search engines such as Google have the capability to detect malware when they are indexing the pages on your site, and consequently they can blacklist your website which will in turn affect your search rankings.', 'all-in-one-wp-security-and-firewall') . '

            '; + + $site_scanners_link = '' . esc_html__('here', 'all-in-one-wp-security-and-firewall'). ''; + + echo '

            ' . esc_html__('Scanning for malware', 'all-in-one-wp-security-and-firewall') . '

            '; + echo '

            ' . esc_html__('Due to the constantly changing and complex nature of Malware, scanning for such things using a standalone plugin will not work reliably.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('This is something best done via an external scan of your site regularly.', 'all-in-one-wp-security-and-firewall') . '

            '.'

            '.esc_html__('This is why we have created an easy-to-use scanning service which is hosted off our own server which will scan your site for malware weekly and notify you if it finds anything.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            ' . esc_html__('This service is included with the premium plugin and provides the following:', 'all-in-one-wp-security-and-firewall') . '

            '; + echo '
              +
            • ' . esc_html__('Automatic weekly scans', 'all-in-one-wp-security-and-firewall') . '
            • +
            • ' . esc_html__('Automatic malware and blacklist monitoring', 'all-in-one-wp-security-and-firewall') . '
            • +
            • ' . esc_html__('Automatic email alerting', 'all-in-one-wp-security-and-firewall') . '
            • +
            • ' . esc_html__('Site uptime monitoring', 'all-in-one-wp-security-and-firewall') . '
            • +
            • ' . esc_html__('Site response time monitoring', 'all-in-one-wp-security-and-firewall') . '
            • +
            • ' . esc_html__('We provide advice for malware cleanup', 'all-in-one-wp-security-and-firewall') . '
            • +
            • ' . esc_html__('Blacklist removal', 'all-in-one-wp-security-and-firewall') . '
            • +
            • ' . esc_html__('No contract (cancel anytime)', 'all-in-one-wp-security-and-firewall') . '
            • +
            '; + /* translators: %s: Scanner URL. */ + echo '

            ' . sprintf(esc_html__('Learn more %s.', 'all-in-one-wp-security-and-firewall'), $site_scanners_link) . '

            '; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- variable already escaped. + ?> +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/scanner/scan-result.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/scanner/scan-result.php new file mode 100755 index 00000000..5a5c0bfc --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/scanner/scan-result.php @@ -0,0 +1,42 @@ + +
            +

            +
            + esc_html__('The following files were added to your website.', 'all-in-one-wp-security-and-firewall'), + 'files_removed' => esc_html__('The following files were removed from your website.', 'all-in-one-wp-security-and-firewall'), + 'files_changed' => esc_html__('The following files were changed on your website.', 'all-in-one-wp-security-and-firewall') + ); + + foreach ($file_change_types as $type => $description) { + if (empty($last_scan_results[$type])) continue; + echo '
            ' . esc_html($description) . '
            '; + $output = '
            '; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + foreach ($last_scan_results[$type] as $key => $value) { + $output .= ''; + $output .= ''; + $file_size = AIOWPSecurity_Utility::convert_numeric_size_to_text($value['filesize']); + $output .= ''; + $last_modified = AIOWPSecurity_Utility::convert_timestamp($value['last_modified']); + $output .= ''; + $output .= ''; + } + $output .= '
            ' . esc_html__('File', 'all-in-one-wp-security-and-firewall') . '' . esc_html__('File size', 'all-in-one-wp-security-and-firewall') . '' . esc_html__('File modified', 'all-in-one-wp-security-and-firewall') . '
            ' . esc_html($key) . '' . esc_html($file_size) . '' . esc_html($last_modified) . '
            '; + $output .= '
            '; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variables escaped early inside HTML. + echo $output; + echo '
            '; + } + ?> +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/advanced-settings.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/advanced-settings.php new file mode 100755 index 00000000..22b2001e --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/advanced-settings.php @@ -0,0 +1,223 @@ + + +
            +

            +
            +
            + ' . esc_html__('The IP address detection settings allow you to specify how visitors\' IP addresses are made known to PHP (and hence to WordPress and its plugins).', 'all-in-one-wp-security-and-firewall'). + '
            ' . esc_html__('Usually, this is automatic and there is only one choice.', 'all-in-one-wp-security-and-firewall'). + ' ' . esc_html__('However in some setups, such as those using proxies (including load-balancers and security firewalls like Cloudflare), it may be necessary to set this manually.', 'all-in-one-wp-security-and-firewall'). + '

            ' . esc_html__('Attention', 'all-in-one-wp-security-and-firewall') . ': ' . esc_html__('It is important to set this correctly - otherwise you may make it possible for a hacker to ban all your visitors (e.g. via banning Cloudflare from connecting to you) instead of the hacker being banned.', 'all-in-one-wp-security-and-firewall') . '

            ' . esc_html__("The default is to use the REMOTE_ADDR PHP server variable.", 'all-in-one-wp-security-and-firewall') . " " . esc_html__("If this variable does not contain the visitor's IP address, then whilst you can make a different selection below, it is better to ask your web hosting company to have it correctly set.", 'all-in-one-wp-security-and-firewall') . ' ' . + esc_html__("This is the most secure setup, because when set correctly it is immune from being spoofed by an attacker.", 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            + + ' . esc_html__('You have no available IP address detection method(s); you must contact your web hosting company.', 'all-in-one-wp-security-and-firewall') . ''; + } + ?> + +

            + + +
            + + +
            + + + '; + echo esc_html__("If your site is setup on localhost, you won't see your external IP address using your server's IP detection setting; but on a localhost-served site (not available to the outside world), the setting is irrelevant and can be ignored.", 'all-in-one-wp-security-and-firewall'); + } + ?> + +
            + + + + +
            + + + + + + +
            +

            + +

            +
            +
            + + +
            + +
            + +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/delete-plugin-settings.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/delete-plugin-settings.php new file mode 100755 index 00000000..317273f2 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/delete-plugin-settings.php @@ -0,0 +1,41 @@ + +
            +

            +
            +
            +
            +

            + +

            +
            + + + + + + + + + +
            : +
            + configs->get_value('aiowps_on_uninstall_delete_db_tables')); ?> +
            +
            : + +
            + configs->get_value('aiowps_on_uninstall_delete_configs')); ?> +
            +
            +
            + +
            +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/general-settings.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/general-settings.php new file mode 100755 index 00000000..9d23f4d5 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/general-settings.php @@ -0,0 +1,116 @@ + +
            +

            .

            +
            + +
            +

            +
            +

            + +   + +

            +

            + +   + +

            +

            +

            +

              +
            • +
            • +
            • +
            +

            +
            +
            +
            +

            +
            +
            +
            + '.esc_html__('If you think that some plugin functionality on your site is broken due to a security feature you enabled in this plugin, then use the following option to turn off all the security features of this plugin.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            + +
            +
            +
            +
            +
            +

            +
            +
            +
            + ' . esc_html__('This feature will disable all firewall rules which are currently active in this plugin and it will also delete these rules from your .htaccess file.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('Use it if you think one of the firewall rules is causing an issue on your site.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            + +
            +
            +
            +
            +
            +

            +
            +
            +
            + ' . esc_html__('This feature will delete all of your settings related to the All-In-One Security plugin.', 'all-in-one-wp-security-and-firewall') . '

            '; + echo '

            ' . esc_html__('This feature will reset/empty all the database tables of the security plugin also.', 'all-in-one-wp-security-and-firewall') . '

            '; + echo '

            ' . esc_html__('Use this feature if you were locked out by the All-In-One Security plugin and/or you are having issues logging in when that plugin is activated.', 'all-in-one-wp-security-and-firewall') . '

            '; + echo '

            ' . esc_html__('In addition to the settings it will also delete any directives which were added to the .htaccess file by the All-In-One Security Plugin.', 'all-in-one-wp-security-and-firewall') . '

            '; + /* translators: 1: Open strong tag, 2: Close strong tag. */ + echo '

            ' . sprintf(esc_html__('%1$sNOTE: %2$sAfter deleting the settings you will need to re-configure the All-In-One Security plugin.', 'all-in-one-wp-security-and-firewall'), '', '') . '

            '; + ?> +
            +
            + +
            +
            +
            +
            + +
            +

            +
            +
            +
            + ' . esc_html__('This setting allows you to enable/disable debug for this plugin.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_enable_debug')); ?> +
            +
            +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/htaccess-file-operations.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/htaccess-file-operations.php new file mode 100755 index 00000000..059f689b --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/htaccess-file-operations.php @@ -0,0 +1,37 @@ + +

            +
            + '.esc_html__('Your ".htaccess" file is a key component of your website\'s security and it can be modified to implement various levels of protection mechanisms.', 'all-in-one-wp-security-and-firewall').' +
            '.esc_html__('This feature allows you to backup and save your currently active .htaccess file should you need to re-use the the backed up file in the future.', 'all-in-one-wp-security-and-firewall').' +
            '.esc_html__('You can also restore your site\'s .htaccess settings using a backed up .htaccess file.', 'all-in-one-wp-security-and-firewall').' +

            '; + ?> +
            +
            +

            +
            +
            +

            + +
            +
            +
            +
            +

            +
            +
            + + + + + +
            : + + + + +
            +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/settings-file-operations.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/settings-file-operations.php new file mode 100755 index 00000000..d371c892 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/settings-file-operations.php @@ -0,0 +1,45 @@ + +

            +
            + ' . esc_html__('This section allows you to export or import your All-In-One Security settings.', 'all-in-one-wp-security-and-firewall'); + echo '
            ' .esc_html__('This can be handy if you wanted to save time by applying the settings from one site to another site.', 'all-in-one-wp-security-and-firewall').' +
            '.esc_html__('NOTE: Before importing, it is your responsibility to know what settings you are trying to import.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('Importing settings blindly can cause you to be locked out of your site.', 'all-in-one-wp-security-and-firewall').' +
            '.esc_html__('For Example: If a settings item relies on the domain URL then it may not work correctly when imported into a site with a different domain.', 'all-in-one-wp-security-and-firewall').' +

            '; + ?> +
            +
            +

            +
            +
            + + + + +
            + +
            +
            +
            +
            +

            +
            +
            + + + + + + +
            + + + + + + +
            +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/wp-config-file-operations.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/wp-config-file-operations.php new file mode 100755 index 00000000..839811f9 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/wp-config-file-operations.php @@ -0,0 +1,47 @@ + +

            +
            + '.esc_html__('Your "wp-config.php" file is one of the most important files in your WordPress installation.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('It is a primary configuration file and contains crucial things such as details of your database and other critical components.', 'all-in-one-wp-security-and-firewall').' +
            '.esc_html__('This feature allows you to backup and save your currently active wp-config.php file should you need to re-use the the backed up file in the future.', 'all-in-one-wp-security-and-firewall').' +
            '.esc_html__('You can also restore your site\'s wp-config.php settings using a backed up wp-config.php file.', 'all-in-one-wp-security-and-firewall').' +

            '; + ?> +
            +
            +

            +
            +
            +

            + +
            +
            +
            +
            +

            +
            +
            + + + + + +
            : + + + + +
            +
            +
            +
            + +?> + + + --> \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/wp-version-info.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/wp-version-info.php new file mode 100755 index 00000000..6d24830d --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/settings/wp-version-info.php @@ -0,0 +1,38 @@ + +

            +
            + '.esc_html__('WordPress generator automatically adds some meta information inside the "head" tags of every page on your site\'s front end, below is an example of this:', 'all-in-one-wp-security-and-firewall'); + echo '
            <meta name="generator" content="WordPress 3.5.1" />'; + echo '
            '.esc_html__('The above meta information shows which version of WordPress your site is currently running and thus can help hackers or crawlers scan your site to see if you have an older version of WordPress or one with a known exploit.', 'all-in-one-wp-security-and-firewall').' +

            '.esc_html__('There are also other ways Wordpress reveals version info such as during style and script loading, an example of this is:', 'all-in-one-wp-security-and-firewall'); + // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet -- PCP error. Example code. Not an actual stylesheet. + echo '
            <link rel="stylesheet" id="jquery-ui-style-css" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.0/themes/smoothness/jquery-ui.css?ver=4.5.2" type="text/css" media="all" /> +

            '.esc_html__('This feature will allow you to remove the WP generator meta info and other version info from your site\'s pages.', 'all-in-one-wp-security-and-firewall').' +

            '; + ?> +
            +
            +

            +
            +
            + output_feature_details_badge("wp-generator-meta-tag"); + ?> +
            +
            + + + + + +
            : +
            + configs->get_value('aiowps_remove_wp_generator_meta_info')); ?> +
            +
            + +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php new file mode 100755 index 00000000..85880af9 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/spam-prevention/comment-spam-ip-monitoring.php @@ -0,0 +1,116 @@ + +
            +

            +
            + configs->get_value('aiowps_enable_autoblock_spam_ip') && '1' != $aio_wp_security->configs->get_value('aiowps_enable_spambot_detecting')) { + $comment_spam_detect_link = "" . esc_html__('spam comment detection', 'all-in-one-wp-security-and-firewall') . ""; + /* translators: %s: Feature URL. */ + $info_msg = sprintf(esc_html__('This feature has detected that %s is not active.', 'all-in-one-wp-security-and-firewall'), $comment_spam_detect_link) . ' ' . esc_html__('It is highly recommended that you activate to make the most of this feature.', 'all-in-one-wp-security-and-firewall'); + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variable already escaped. + echo '

            '.$info_msg.'

            '; + } + ?> +
            + output_feature_details_badge("auto-block-spam-ips"); + ?> +
            +
            +
            + '.esc_html__('This feature allows you to automatically and permanently block IP addresses which have exceeded a certain number of spam comments.', 'all-in-one-wp-security-and-firewall').'

            '.'

            '.esc_html__('Comments are considered spam if the "Spam comment detection" feature is enabled or an administrator manually marks a comment as "spam" from the WordPress Comments menu.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            + output_feature_details_badge("auto-block-spam-ip"); + ?> +
            + + + + + + + + + + + + + + + +
            : +
            + configs->get_value('aiowps_enable_autoblock_spam_ip')); ?> +
            +
            + + + +
            + '.esc_html__('Example 1: Setting this value to "1" will block ALL IP addresses which were used to submit at least one spam comment.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('Example 2: Setting this value to "5" will block only those IP addresses which were used to submit 5 spam comments or more on your site.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            + +
            +
            +
            +
            +

            +
            +
            + '.esc_html__('This section displays a list of the IP addresses of the people or bots who have left spam comments on your site.', 'all-in-one-wp-security-and-firewall').'
            '.esc_html__('This information can be handy for identifying the most persistent IP addresses or ranges used by spammers.', 'all-in-one-wp-security-and-firewall').'
            '.esc_html__('By inspecting the IP address data coming from spammers you will be in a better position to determine which addresses or address ranges you should block by adding them to the permanent block list.', 'all-in-one-wp-security-and-firewall').'
            '.esc_html__('To add one or more of the IP addresses displayed in the table below to your blacklist, simply press the "Block" link for the individual row or select more than one address using the checkboxes and then choose the "block" option from the Bulk Actions dropdown list and press the "Apply" button.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            + + + + + +
            + + + + +
            + '.esc_html__('Example 1: Setting this value to "1" will list ALL IP addresses which were used to submit at least 1 spam comment.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('Example 2: Setting this value to "5" will list only those IP addresses which were used to submit 5 spam comments or more on your site.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            + +
            +
            +
            +
            +

            +
            + '; + echo '

            '.esc_html__('The plugin has detected that you are using a Multi-Site WordPress installation.', 'all-in-one-wp-security-and-firewall').'

            '.esc_html__('Only the "superadmin" can block IP addresses from the main site.', 'all-in-one-wp-security-and-firewall').'

            '.esc_html__('Take note of the IP addresses you want blocked and ask the superadmin to add these to the blacklist using the "Blacklist Manager" on the main site.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '
            '; + } + // Fetch, prepare, sort, and filter our data... + $spammer_ip_list->prepare_items(); + // echo "put table of locked entries here"; + ?> +
            + + + + + display(); ?> +
            +
            + \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/spam-prevention/comment-spam.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/spam-prevention/comment-spam.php new file mode 100755 index 00000000..bd8015f6 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/spam-prevention/comment-spam.php @@ -0,0 +1,99 @@ + +

            +
            +
            +
            +

            +
            +
            + '.esc_html__('A large portion of WordPress blog comment spam is produced by automated bots rather than by humans.', 'all-in-one-wp-security-and-firewall').'
            '.esc_html__('This feature will reduce the useless and unnecessary traffic and load on your server resulting from spam comments.', 'all-in-one-wp-security-and-firewall').'
            '.esc_html__('In other words, if the comment was not submitted by a human, the request will be discarded or marked as spam.', 'all-in-one-wp-security-and-firewall').'
            '.esc_html__('This feature uses cookies and JavaScript.', 'all-in-one-wp-security-and-firewall').' '.esc_html__('If your visitors have either cookies or JavaScript disabled, their comments will automatically be discarded or marked as spam.', 'all-in-one-wp-security-and-firewall') . '

            '; + ?> +
            +
            + output_feature_details_badge("detect-spambots"); + ?> +
            + + + + + + + + + +
            : +
            + configs->get_value('aiowps_enable_spambot_detecting')); ?> + + +
            + '.esc_html__('This feature will detect comment attempts which originate from spambots.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('A legitimate comment is one which is submitted by a human who physically fills out the comment form and presses the submit button.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('A comment submitted by a spambot is done by directly calling the wp-comments-post.php file.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('This feature will detect these comments and either discard them completely or mark them as spam.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            +
            +
            + configs->get_value('aiowps_spambot_detect_usecookies')); ?> + + +
            + '.esc_html__('This feature uses cookies.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('Unless your cache (e.g. Cloudflare) is configured to ignore these cookies, it may decide to not cache any of these pages.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('Cloudflare detects that the set-cookie header is set and will not cache the page by default.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            +
            +
            +

            +
            + + + + + + + + + +
            + + + + +
            + + + configs->get_value('aiowps_enable_trash_spam_comments')); ?> + configs->get_value('aiowps_enable_trash_spam_comments')) $disabled = "disabled"; + echo ''; + ?> + + +
            + '.esc_html__('Enable this feature in order to move the spam comments to trash after given number of days.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            +
            +
            + +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/custom-htaccess.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/custom-htaccess.php new file mode 100755 index 00000000..109240b6 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/custom-htaccess.php @@ -0,0 +1,58 @@ + +

            +
            +
            + '. esc_html__('This feature can be used to apply your own custom .htaccess rules and directives.', 'all-in-one-wp-security-and-firewall').'

            '; + $info_msg .= '

            '. esc_html__('It is useful for when you want to tweak our existing firewall rules or when you want to add your own.', 'all-in-one-wp-security-and-firewall').'

            '; + $info_msg .= '

            '. esc_html__('NOTE: This feature can only be used if your site is hosted using the Apache webserver, or another that uses .htaccess files.', 'all-in-one-wp-security-and-firewall').'

            '; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped earlier. + echo $info_msg; + ?> +
            +
            + '. sprintf(esc_html__('%s: Only use this feature if you know what you are doing.', 'all-in-one-wp-security-and-firewall'), '' . esc_html__('Warning', 'all-in-one-wp-security-and-firewall') . '').'

            '; + $info_msg_2 .= '

            '.esc_html__('Incorrect .htaccess rules or directives can break or prevent access to your site.', 'all-in-one-wp-security-and-firewall').'

            '; + $info_msg_2 .= '

            '.esc_html__('It is your responsibility to ensure that you are entering the correct code!', 'all-in-one-wp-security-and-firewall').'

            '; + $info_msg_2 .= '

            '.esc_html__('If you break your site you will need to access your server via FTP or something similar and then edit your .htaccess file and delete the changes you made.', 'all-in-one-wp-security-and-firewall').'

            '; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped earlier. + echo $info_msg_2; + ?> +
            + +
            +

            +
            + + + + + + + + + + + + + +
            : +
            + configs->get_value('aiowps_enable_custom_rules')); ?> +
            +
            : +
            + configs->get_value('aiowps_place_custom_rules_at_top')); ?> +
            +
            + +
            + +
            +
            + +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/partials/who-is-lookup-result.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/partials/who-is-lookup-result.php new file mode 100755 index 00000000..2e97b2e7 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/partials/who-is-lookup-result.php @@ -0,0 +1,13 @@ +
            +

            + + + + + +
            WHOIS:
            +

            +
            +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/password-tool.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/password-tool.php new file mode 100755 index 00000000..8962aa1d --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/password-tool.php @@ -0,0 +1,30 @@ + +

            +
            + '.esc_html__('Poor password selection is one of the most common weak points of many sites and is usually the first thing a hacker will try to exploit when attempting to break into your site.', 'all-in-one-wp-security-and-firewall').'

            '. + '

            '.esc_html__('Many people fall into the trap of using a simple word or series of numbers as their password.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('Such a predictable and simple password would take a competent hacker merely minutes to guess your password by using a simple script which cycles through the easy and most common combinations.', 'all-in-one-wp-security-and-firewall').'

            '. + '

            '.esc_html__('The longer and more complex your password is the harder it is for hackers to "crack" because more complex passwords require much greater computing power and time.', 'all-in-one-wp-security-and-firewall').'

            '. + '

            '.esc_html__('This section contains a useful password strength tool which you can use to check whether your password is sufficiently strong enough.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            +

            +
            +

            +
            + +
            +
            +
            +
            +
            +
            + ' . __('HIBP', 'all-in-one-wp-security-and-firewall') . ''; ?> + ' . __('1 sec', 'all-in-one-wp-security-and-firewall') . ''); ?> + + +
            +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/visitor-lockout.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/visitor-lockout.php new file mode 100755 index 00000000..9973df25 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/visitor-lockout.php @@ -0,0 +1,43 @@ + +
            +

            +
            +
            +
            + '.esc_html__('This feature allows you to put your site into "maintenance mode" by locking down the front-end to all visitors except logged in users with super admin privileges.', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('Locking your site down to general visitors can be useful if you are investigating some issues on your site or perhaps you might be doing some maintenance and wish to keep out all traffic for security reasons.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            + + + + + + + + + +
            : +
            + configs->get_value('aiowps_site_lockout')); ?> +
            +
            + configs->get_value('aiowps_site_lockout_msg'); + if (empty($aiowps_site_lockout_msg_raw)) { + $aiowps_site_lockout_msg_raw = 'This site is currently not available. Please try again later.'; + } + $aiowps_site_lockout_msg = html_entity_decode($aiowps_site_lockout_msg_raw, ENT_COMPAT, "UTF-8"); + $aiowps_site_lockout_msg_settings = array('textarea_name' => 'aiowps_site_lockout_msg'); + wp_editor($aiowps_site_lockout_msg, "aiowps_site_lockout_msg_editor_content", $aiowps_site_lockout_msg_settings); + ?> +
            + +
            +
            + +
            +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/whois-lookup.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/whois-lookup.php new file mode 100755 index 00000000..359ab8c0 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/tools/whois-lookup.php @@ -0,0 +1,24 @@ + +
            +

            +
            +
            +

            +
            +
            + + + + + +
            + + + +
            + +
            +
            +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/additional.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/additional.php new file mode 100755 index 00000000..8e16fe2b --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/additional.php @@ -0,0 +1,32 @@ + +
            + '.esc_html__('WordPress 5.6 introduced a new feature called "Application passwords".', 'all-in-one-wp-security-and-firewall').' +
            '.esc_html__('This allows you to create a token from the WordPress dashboard which then can be used in the authorization header.', 'all-in-one-wp-security-and-firewall').'

            '.esc_html__('This feature allows you to disable application passwords as they can leave your site vulnerable to social engineering and phishing scams.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            +

            +
            +
            +
            + output_feature_details_badge("disable-application-password"); + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_disable_application_password')); ?> +
            +
            + +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/force-logout.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/force-logout.php new file mode 100755 index 00000000..05dd3f22 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/force-logout.php @@ -0,0 +1,40 @@ + +
            + '.esc_html__('Setting an expiry period for your administration session is a simple way to protect against unauthorized access to your site from your computer.', 'all-in-one-wp-security-and-firewall').' +
            '.esc_html__('This feature allows you to specify a time period in minutes after which the admin session will expire and the user will be forced to log back in.', 'all-in-one-wp-security-and-firewall').' +

            '; + ?> +
            +
            +

            +
            +
            + output_feature_details_badge("user-login-force-logout"); + ?> +
            +
            + + + + + + + + + +
            : +
            + configs->get_value('aiowps_enable_forced_logout')); ?> +
            +
            : + +
            + +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/hibp.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/hibp.php new file mode 100755 index 00000000..2f4d831d --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/hibp.php @@ -0,0 +1,35 @@ + +
            +

            + ' . __('HIBP', 'all-in-one-wp-security-and-firewall') . ''); ?> +

            +
            +
            +

            +
            +
            +
            + output_feature_details_badge('hibp'); ?> +
            + + + + + + + + + +
            : +
            + configs->get_value('aiowps_hibp_user_profile_update')); ?> +
            +
            : +
            + configs->get_value('aiowps_http_password_reset')); ?> +
            +
            + +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/http-authentication.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/http-authentication.php new file mode 100755 index 00000000..7ab0ce63 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/http-authentication.php @@ -0,0 +1,104 @@ + +
            +

            +

            + + + + + + +

            +
            + +
            +

            + +

            +
            + +
            + ' . sprintf(__('If you are locked out by the HTTP authentication feature, define the following constant %s in wp-config.php to disable the feature.', 'all-in-one-wp-security-and-firewall'), 'define(\'AIOS_DISABLE_HTTP_AUTHENTICATION\', true);') . '

            '; + ?> +
            + +configs->get_value('aiowps_http_authentication_admin') && !$aio_wp_security->configs->get_value('aiowps_http_authentication_frontend')) { ?> + configs->get_value('aiowps_http_authentication_username')) || (isset($_SERVER['PHP_AUTH_PW']) && $_SERVER['PHP_AUTH_PW'] != $aio_wp_security->configs->get_value('aiowps_http_authentication_password'))) { ?> +
            +

            +

            +
            + + +
            + +
            +

            +
            + output_feature_details_badge('http-authentication-admin-frontend'); + ?> + + + + + + + + + + + + + + + + + + + + + +
            + + +
            + configs->get_value('aiowps_http_authentication_admin')); ?> +
            +
            + + +
            + configs->get_value('aiowps_http_authentication_frontend')); ?> +
            +
            + + + +
            + + + +
            + ' . __('1 sec', 'all-in-one-wp-security-and-firewall') . ''; + $password_tool_link = '' . __('Password tool', 'all-in-one-wp-security-and-firewall') . ''; + $hibp_link = '' . __('HIBP', 'all-in-one-wp-security-and-firewall') . ''; + ?> + + +
            + + + configs->get_value('aiowps_http_authentication_failure_message'); + $aiowps_failure_message_raw = html_entity_decode($aiowps_failure_message, ENT_COMPAT, 'UTF-8'); + wp_editor($aiowps_failure_message_raw, 'aiowps_http_authentication_failure_message'); + ?> +
            +
            +
            + +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/logged-in-users.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/logged-in-users.php new file mode 100755 index 00000000..0aa4ba70 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/logged-in-users.php @@ -0,0 +1,31 @@ + +
            +

            +
            +
            + +
            +
            +
            +
            + '.esc_html__('This tab displays all users who are currently logged into your site.', 'all-in-one-wp-security-and-firewall').' +
            '.esc_html__('If you suspect there is a user or users who are logged in which should not be, you can block them by inspecting the IP addresses from the data below and adding them to your blacklist.', 'all-in-one-wp-security-and-firewall').' +
            '.esc_html__('You can also instantly log them out by pressing on the "Force logout" link when you hover over the row in the user id column.', 'all-in-one-wp-security-and-firewall').' +

            '; + ?> +
            +
            +

            +
            + prepare_items(); + // echo "put table of locked entries here"; + ?> +
            + + display(); ?> +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/login-lockout.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/login-lockout.php new file mode 100755 index 00000000..82bb48f2 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/login-lockout.php @@ -0,0 +1,188 @@ + +

            +
            + ' . esc_html__('Cookie-based brute force login prevention', 'all-in-one-wp-security-and-firewall').''; + echo '

            ' . esc_html__('One of the ways hackers try to compromise sites is via a', 'all-in-one-wp-security-and-firewall') . ' ' .'' . esc_html__('Brute force login attack', 'all-in-one-wp-security-and-firewall') . '. ' . esc_html__('This is where attackers use repeated login attempts until they guess the password.', 'all-in-one-wp-security-and-firewall').' +
            ' . esc_html__('Apart from choosing strong passwords, monitoring and blocking IP addresses which are involved in repeated login failures in a short period of time is a very effective way to stop these types of attacks.', 'all-in-one-wp-security-and-firewall'). + /* translators: %s: Brute force feature link. */ + '

            ' . sprintf(esc_html__('You may also want to checkout our %s feature for another secure way to protect against these types of attacks.', 'all-in-one-wp-security-and-firewall'), $brute_force_login_feature_link) . '

            '; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Link already escaped. + ?> +
            +
            +

            +
            +
            + output_feature_details_badge("user-login-login-lockdown"); + ?> +
            +
            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            : +
            + configs->get_value('aiowps_enable_login_lockdown')); ?> +
            +
            : +
            + configs->get_value('aiowps_allow_unlock_requests')); ?> +
            +
            + +
            + +
            + + + + + + +
            + + + + + +
            : +
            + configs->get_value('aiowps_set_generic_login_msg')); ?> +
            +
            : +
            + configs->get_value('aiowps_enable_invalid_username_lockdown')); ?> +
            +
            + + + configs->get_value('aiowps_instantly_lockout_specific_usernames'); + if (empty($instant_lockout_users_list)) { + $instant_lockout_users_list = array(); + } + ?> +
            + +
            + + +
            + configs->get_value('aiowps_enable_email_notify')); ?> +
            +
            +
            + + + +
            + ' . esc_html__('Each email address must be on a new line.', 'all-in-one-wp-security-and-firewall') . '

            '; + echo '

            ' . esc_html__('If a valid email address has not been filled in, it will not be saved.', 'all-in-one-wp-security-and-firewall') . '

            '; + echo '

            ' . esc_html__('The valid email address format is userid@example.com', 'all-in-one-wp-security-and-firewall') . '

            '; + /* translators: %s: Email example. */ + echo '

            ' . sprintf(esc_html__('Example: %s', 'all-in-one-wp-security-and-firewall'), 'rick@wordpress.org') . '

            '; + ?> +
            +
            + : + +
            + configs->get_value('aiowps_enable_php_backtrace_in_email')); ?> +
            +
            + +
            +
            +
            +
            +

            +
            +
            + Locked IP addresses'; + /* translators: %s: Locked IP link. */ + echo '

            ' . sprintf(esc_html__('To see a list of all locked IP addresses and ranges go to the %s tab in the dashboard menu.', 'all-in-one-wp-security-and-firewall'), $locked_ips_link) . '

            '; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Link already escaped. + ?> +
            +
            +
            +
            +

            +
            +
            + output_feature_details_badge("user-login-lockout-ip-whitelisting"); + ?> +
            +
            + + + + + + + + +
            : +
            + configs->get_value('aiowps_lockdown_enable_whitelisting')); ?> +
            +
            + +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/manual-approval.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/manual-approval.php new file mode 100755 index 00000000..f9eef302 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/manual-approval.php @@ -0,0 +1,57 @@ + +

            +
            +

            +
            +
            + '.esc_html__('If your site allows people to create their own accounts via the WordPress registration form, then you can minimize spam or bogus registrations by manually approving each registration.', 'all-in-one-wp-security-and-firewall'). + '
            '.esc_html__('This feature will automatically set a newly registered account to "pending" until the administrator activates it.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('Therefore undesirable registrants will be unable to log in without your express approval.', 'all-in-one-wp-security-and-firewall'). + '
            '.esc_html__('You can view all accounts which have been newly registered via the handy table below and you can also perform bulk activation/deactivation/deletion tasks on each account.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            + output_feature_details_badge("manually-approve-registrations"); + ?> +
            +
            + + + + + +
            : +
            + configs->get_value('aiowps_enable_manual_registration_approval')); ?> +
            +
            + +
            +
            +
            +
            +

            +
            +
            + +
            +
            +
            +
            +

            +
            + prepare_items(); + ?> +
            + search_box(esc_html__('Search', 'all-in-one-wp-security-and-firewall'), 'search_user_registration'); + ?> + + display(); ?> +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/display-name.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/display-name.php new file mode 100755 index 00000000..054c65f8 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/display-name.php @@ -0,0 +1,41 @@ + +

            +
            + '.esc_html__('When you submit a post or answer a comment, WordPress will usually display your "nickname".', 'all-in-one-wp-security-and-firewall'); + echo '
            '.esc_html__('By default the nickname is set to the login (or user) name of your account.', 'all-in-one-wp-security-and-firewall'); + echo '
            '.esc_html__('From a security perspective, leaving your nickname the same as your user name is bad practice because it gives a hacker at least half of your account\'s login credentials.', 'all-in-one-wp-security-and-firewall'); + /* translators: 1. Open strong tag, 2. Close strong tag. */ + echo '

            '.sprintf(esc_html__('Therefore to further tighten your site\'s security you are advised to change your %1$snickname%2$s and %1$sDisplay name%2$s to be different from your %1$sUsername%2$s.', 'all-in-one-wp-security-and-firewall'), '', ''); + echo '

            '; + ?> +
            +
            +

            +
            + output_feature_details_badge("user-accounts-display-name"); + + // now let's find any accounts which have login name same as display name + $login_nick_name_accounts = AIOWPSecurity_Utility::check_identical_login_and_nick_names(); + if ($login_nick_name_accounts) { + echo '

            '.esc_html__('Your site currently has the following accounts with identical login and display names.', 'all-in-one-wp-security-and-firewall').'('.esc_html__('Follow the link to edit the user profile of that particular user account, change Nickname, choose a different Display name compared to Username, and press the "Update Profile" button.', 'all-in-one-wp-security-and-firewall').')

            '; + ?> + + '; + // echo ''; + echo ''; + echo ''; + } + ?> +
            ' . esc_html($usr['user_login']) . '
            +

            '.esc_html__('No action required.', 'all-in-one-wp-security-and-firewall').'
            '.esc_html__('Your site does not have a user account where the display name is identical to the username.', 'all-in-one-wp-security-and-firewall').'

            '; + } + ?> +
            + \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/enforce-strong-password.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/enforce-strong-password.php new file mode 100755 index 00000000..33f3f7af --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/enforce-strong-password.php @@ -0,0 +1,28 @@ + +
            +

            +
            +
            + output_feature_details_badge("enforce-strong-password"); + ?> +
            +
            + '.esc_html__('This feature allows you to enforce the use of strong user passwords', 'all-in-one-wp-security-and-firewall').'

            '; + echo '

            '.esc_html__('When enabled, this feature will hide the "confirm weak password" checkbox on forms.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_enforce_strong_password')); ?> +
            +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/user-enumeration.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/user-enumeration.php new file mode 100755 index 00000000..9ff5bf94 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/user-enumeration.php @@ -0,0 +1,29 @@ + +
            +

            +
            +
            + output_feature_details_badge("disable-users-enumeration"); + ?> +
            +
            + '.sprintf(esc_html__('This feature allows you to prevent external users/bots from fetching the user info with URLs like "%1$s", "%2$s", oEmbed request.', 'all-in-one-wp-security-and-firewall'), '/?author=1', '/' . esc_html(rest_get_url_prefix()) . '/wp/v2/users').'

            '; + echo '

            ' . esc_html__('When enabled, this feature will print a "forbidden" error rather than the user information.', 'all-in-one-wp-security-and-firewall') . '

            '; + ?> +
            + + + + + +
            : +
            + configs->get_value('aiowps_prevent_users_enumeration')); ?> +
            +
            +
            +
            \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/wp-username-content.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/wp-username-content.php new file mode 100755 index 00000000..8a5e114e --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/wp-username-content.php @@ -0,0 +1,26 @@ +

            ' . esc_html__('Your site currently has an account which uses the "admin" username.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('It is highly recommended that you change this name to something else.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('Use the following field to change the admin username.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            + + + + + +
            +

            +
            + +
            +

            +
            +

            '; + esc_html_e('No action required.', 'all-in-one-wp-security-and-firewall'); + echo '
            '; + echo esc_html__('Your site does not have any account which uses the "admin" username.', 'all-in-one-wp-security-and-firewall'); + esc_html_e('This is good security practice.', 'all-in-one-wp-security-and-firewall'); + echo '

            '; +} \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/wp-username.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/wp-username.php new file mode 100755 index 00000000..41d5492e --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/partials/wp-username.php @@ -0,0 +1,38 @@ + +

            +
            + '.esc_html__('Depending on how you installed WordPress, you could have a default administrator with the username "admin".', 'all-in-one-wp-security-and-firewall').' +
            '.esc_html__('Hackers can try to take advantage of this information by attempting "Brute force login attacks" where they repeatedly try to guess the password by using "admin" for username.', 'all-in-one-wp-security-and-firewall').' +
            '.esc_html__('From a security perspective, changing the username "admin" is one of the first and smartest things you should do on your site.', 'all-in-one-wp-security-and-firewall').' +

            '.esc_html__('This feature will allow you to change your "admin" username to a more secure name of your choosing.', 'all-in-one-wp-security-and-firewall').' +

            '; + ?> +
            +postbox($postbox_title, $user_accounts); + +if (!is_super_admin()) { + // Hide config settings if multisite and not super admin. + AIOWPSecurity_Utility::display_multisite_super_admin_message(); +} else { +?> +
            +

            +
            +
            + output_feature_details_badge("user-accounts-change-admin-user"); + ?> +
            +
            + include_template('wp-admin/user-security/partials/wp-username-content.php', false); + ?> +
            +
            +
            + + +
            +

            +
            +
            + output_feature_details_badge("enable-salt-postfix"); + ?> +
            +
            +
            + '.esc_html__('WordPress "salts" are secret phrases which are combined with user passwords when those passwords are stored, with the end result that they become much harder for an attacker to crack even if he managed to steal the database of your website.', 'all-in-one-wp-security-and-firewall').' '.esc_html__('Learn more about WordPress Salts.', 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            +

            + +

            +
            + + + + + + + +
            + + +
            + configs->get_value('aiowps_enable_salt_postfix')); ?> + + +
            + '.esc_html__('This setting will suffix the salt with an additional 64 characters.', 'all-in-one-wp-security-and-firewall').' '.esc_html__("It improves your WordPress site's cryptographic mechanism.", 'all-in-one-wp-security-and-firewall').'

            '; + ?> +
            +
            +
            + +
            + +
            +
            +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/user-accounts.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/user-accounts.php new file mode 100755 index 00000000..5b044113 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/templates/wp-admin/user-security/user-accounts.php @@ -0,0 +1,16 @@ +include_template('wp-admin/user-security/partials/wp-username.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr, 'user_accounts' => $user_accounts, 'AIOWPSecurity_User_Security_Menu' => $AIOWPSecurity_User_Security_Menu)); + +$aio_wp_security->include_template('wp-admin/user-security/partials/display-name.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr)); +?> +
            + include_template('wp-admin/user-security/partials/user-enumeration.php'); + + $aio_wp_security->include_template('wp-admin/user-security/partials/enforce-strong-password.php'); + ?> +
            + +
            +
            diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/autoload.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/autoload.php new file mode 100755 index 00000000..a042bbb3 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/autoload.php @@ -0,0 +1,25 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ + private $vendorDir; + + // PSR-4 + /** + * @var array> + */ + private $prefixLengthsPsr4 = array(); + /** + * @var array> + */ + private $prefixDirsPsr4 = array(); + /** + * @var list + */ + private $fallbackDirsPsr4 = array(); + + // PSR-0 + /** + * List of PSR-0 prefixes + * + * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) + * + * @var array>> + */ + private $prefixesPsr0 = array(); + /** + * @var list + */ + private $fallbackDirsPsr0 = array(); + + /** @var bool */ + private $useIncludePath = false; + + /** + * @var array + */ + private $classMap = array(); + + /** @var bool */ + private $classMapAuthoritative = false; + + /** + * @var array + */ + private $missingClasses = array(); + + /** @var string|null */ + private $apcuPrefix; + + /** + * @var array + */ + private static $registeredLoaders = array(); + + /** + * @param string|null $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); + } + + /** + * @return array> + */ + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + } + + return array(); + } + + /** + * @return array> + */ + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + /** + * @return list + */ + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + /** + * @return list + */ + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + /** + * @return array Array of classname => path + */ + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + * + * @return void + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void + */ + public function add($prefix, $paths, $prepend = false) + { + $paths = (array) $paths; + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + $paths = (array) $paths; + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories + * + * @return void + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + * + * @return void + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + * + * @return void + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + * + * @return void + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } + } + + /** + * Unregisters this instance as an autoloader. + * + * @return void + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return true|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + $includeFile = self::$includeFile; + $includeFile($file); + + return true; + } + + return null; + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + /** + * Returns the currently registered loaders keyed by their corresponding vendor directories. + * + * @return array + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } + + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/InstalledVersions.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/InstalledVersions.php new file mode 100755 index 00000000..6d29bff6 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/InstalledVersions.php @@ -0,0 +1,378 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final + */ +class InstalledVersions +{ + /** + * @var mixed[]|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null + */ + private static $installed; + + /** + * @var bool + */ + private static $installedIsLocalDir; + + /** + * @var bool|null + */ + private static $canGetVendors; + + /** + * @var array[] + * @psalm-var array}> + */ + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints((string) $constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + + // when using reload, we disable the duplicate protection to ensure that self::$installed data is + // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not, + // so we have to assume it does not, and that may result in duplicate data being returned when listing + // all installed packages for example + self::$installedIsLocalDir = false; + } + + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + $copiedLocalDir = false; + + if (self::$canGetVendors) { + $selfDir = strtr(__DIR__, '\\', '/'); + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + $vendorDir = strtr($vendorDir, '\\', '/'); + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (is_file($vendorDir.'/composer/installed.php')) { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require $vendorDir.'/composer/installed.php'; + self::$installedByVendor[$vendorDir] = $required; + $installed[] = $required; + if (self::$installed === null && $vendorDir.'/composer' === $selfDir) { + self::$installed = $required; + self::$installedIsLocalDir = true; + } + } + if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) { + $copiedLocalDir = true; + } + } + } + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require __DIR__ . '/installed.php'; + self::$installed = $required; + } else { + self::$installed = array(); + } + } + + if (self::$installed !== array() && !$copiedLocalDir) { + $installed[] = self::$installed; + } + + return $installed; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/LICENSE b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/LICENSE new file mode 100755 index 00000000..f27399a0 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/autoload_classmap.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/autoload_classmap.php new file mode 100755 index 00000000..0fb0a2c1 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/autoload_classmap.php @@ -0,0 +1,10 @@ + $vendorDir . '/composer/InstalledVersions.php', +); diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/autoload_namespaces.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/autoload_namespaces.php new file mode 100755 index 00000000..15a2ff3a --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($vendorDir . '/mlocati/ip-lib/src'), +); diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/autoload_real.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/autoload_real.php new file mode 100755 index 00000000..9aa2c148 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/autoload_real.php @@ -0,0 +1,36 @@ +register(true); + + return $loader; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/autoload_static.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/autoload_static.php new file mode 100755 index 00000000..aaed0a00 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/autoload_static.php @@ -0,0 +1,36 @@ + + array ( + 'IPLib\\' => 6, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'IPLib\\' => + array ( + 0 => __DIR__ . '/..' . '/mlocati/ip-lib/src', + ), + ); + + public static $classMap = array ( + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit5a97a2a3e70dff38e164d50f66ea0390::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit5a97a2a3e70dff38e164d50f66ea0390::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit5a97a2a3e70dff38e164d50f66ea0390::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/installed.json b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/installed.json new file mode 100755 index 00000000..92beebe0 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/installed.json @@ -0,0 +1,135 @@ +{ + "packages": [ + { + "name": "mlocati/ip-lib", + "version": "1.22.0", + "version_normalized": "1.22.0.0", + "source": { + "type": "git", + "url": "https://github.com/mlocati/ip-lib.git", + "reference": "4e40ffd3bf9989db19403d89c4d8be44b87b8a91" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mlocati/ip-lib/zipball/4e40ffd3bf9989db19403d89c4d8be44b87b8a91", + "reference": "4e40ffd3bf9989db19403d89c4d8be44b87b8a91", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "ext-pdo_sqlite": "*", + "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5 || ^8.5 || ^9.5" + }, + "time": "2025-10-15T12:35:09+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "IPLib\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michele Locati", + "email": "mlocati@gmail.com", + "homepage": "https://github.com/mlocati", + "role": "Author" + } + ], + "description": "Handle IPv4, IPv6 addresses and ranges", + "homepage": "https://github.com/mlocati/ip-lib", + "keywords": [ + "IP", + "address", + "addresses", + "ipv4", + "ipv6", + "manage", + "managing", + "matching", + "network", + "networking", + "range", + "subnet" + ], + "support": { + "issues": "https://github.com/mlocati/ip-lib/issues", + "source": "https://github.com/mlocati/ip-lib/tree/1.22.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/mlocati", + "type": "github" + }, + { + "url": "https://paypal.me/mlocati", + "type": "other" + } + ], + "install-path": "../mlocati/ip-lib" + }, + { + "name": "team-updraft/common-libs", + "version": "3.0.7", + "version_normalized": "3.0.7.0", + "source": { + "type": "git", + "url": "ssh://git@source.updraftplus.com:20022/team-updraft/common-libs.git", + "reference": "30a5b39a3043cc12a6e1358183682d24376b3fdd" + }, + "dist": { + "type": "zip", + "url": "https://source.updraftplus.com/api/v4/projects/28/packages/composer/archives/team-updraft/common-libs.zip?sha=30a5b39a3043cc12a6e1358183682d24376b3fdd", + "reference": "30a5b39a3043cc12a6e1358183682d24376b3fdd", + "shasum": "" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "0.7.*", + "phpcompatibility/php-compatibility": "9.3.*", + "sirbrillig/phpcs-variable-analysis": "2.11.*", + "squizlabs/php_codesniffer": "3.6.*", + "wp-coding-standards/wpcs": "2.3.*" + }, + "type": "library", + "installation-source": "dist", + "license": [ + "GPL-3.0-only" + ], + "authors": [ + { + "name": "Team Updraft", + "email": "team.updraft@gmail.com" + } + ], + "description": "These are the common libs used across all of our projects", + "install-path": "../team-updraft/common-libs" + }, + { + "name": "team-updraft/lib-central", + "version": "1.25.6", + "version_normalized": "1.25.6.0", + "source": { + "type": "git", + "url": "ssh://git@source.updraftplus.com:20022/team-updraft/lib-central.git", + "reference": "888161bd56e469a660c1c3607d9b16d82aead64d" + }, + "dist": { + "type": "zip", + "url": "https://source.updraftplus.com/api/v4/projects/106/packages/composer/archives/team-updraft/lib-central.zip?sha=888161bd56e469a660c1c3607d9b16d82aead64d", + "reference": "888161bd56e469a660c1c3607d9b16d82aead64d", + "shasum": "" + }, + "type": "library", + "installation-source": "dist", + "install-path": "../team-updraft/lib-central" + } + ], + "dev": false, + "dev-package-names": [] +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/installed.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/installed.php new file mode 100755 index 00000000..2d9f83e4 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/composer/installed.php @@ -0,0 +1,50 @@ + array( + 'name' => 'updraftplus/all-in-one-wp-security-and-firewall', + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'reference' => '5b7f8094d3fc4ee8c05dc1251148f72445a12585', + 'type' => 'project', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev' => false, + ), + 'versions' => array( + 'mlocati/ip-lib' => array( + 'pretty_version' => '1.22.0', + 'version' => '1.22.0.0', + 'reference' => '4e40ffd3bf9989db19403d89c4d8be44b87b8a91', + 'type' => 'library', + 'install_path' => __DIR__ . '/../mlocati/ip-lib', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'team-updraft/common-libs' => array( + 'pretty_version' => '3.0.7', + 'version' => '3.0.7.0', + 'reference' => '30a5b39a3043cc12a6e1358183682d24376b3fdd', + 'type' => 'library', + 'install_path' => __DIR__ . '/../team-updraft/common-libs', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'team-updraft/lib-central' => array( + 'pretty_version' => '1.25.6', + 'version' => '1.25.6.0', + 'reference' => '888161bd56e469a660c1c3607d9b16d82aead64d', + 'type' => 'library', + 'install_path' => __DIR__ . '/../team-updraft/lib-central', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'updraftplus/all-in-one-wp-security-and-firewall' => array( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'reference' => '5b7f8094d3fc4ee8c05dc1251148f72445a12585', + 'type' => 'project', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev_requirement' => false, + ), + ), +); diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/LICENSE.txt b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/LICENSE.txt new file mode 100755 index 00000000..5c21e47c --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/LICENSE.txt @@ -0,0 +1,20 @@ +The MIT License (MIT) +Copyright (c) 2016 Michele Locati + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/README.md b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/README.md new file mode 100755 index 00000000..cf81753e --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/README.md @@ -0,0 +1,823 @@ +[![Tests](https://github.com/mlocati/ip-lib/actions/workflows/tests.yml/badge.svg)](https://github.com/mlocati/ip-lib/actions/workflows/tests.yml) +[![Code Coverage](https://img.shields.io/coverallsCoverage/github/mlocati/ip-lib?branch=main&label=Coverage)](https://coveralls.io/github/mlocati/ip-lib?branch=main) +[![Packagist Downloads](https://img.shields.io/packagist/dt/mlocati/ip-lib?label=Downloads)](https://packagist.org/packages/mlocati/ip-lib) +[![Open in Gitpod](https://img.shields.io/badge/Open%20in-Gitpod-%232cb64c?logo=gitpod)](https://gitpod.io/#https://github.com/mlocati/ip-lib) + +# IPLib - Handle IPv4, IPv6 and IP ranges + +## Introduction + +IPLib is a modern, PSR-compliant, test-driven IP addresses and subnets manipulation library. It implements primitives to handle IPv4 and IPv6 addresses, as well as IP ranges (subnets), in CIDR format (like `::1/128` or `127.0.0.1/32`) and in pattern format (like `::*:*` or `127.0.*.*`). + +## Requirements + +IPLib has very basic requirements as: + +- Works with any PHP version greater than 5.3.3 (PHP **5.3.x**, **5.4.x**, **5.5.x**, **5.6.x**, **7.x**, and **8.x** are fully supported). +- **No external dependencies** +- **No special PHP configuration needed** (yes, it will __always work__ even if PHP has not been built with IPv6 support!). + +## Installation + +### Manual installation + +[Download](https://github.com/mlocati/ip-lib/releases) the latest version, unzip it and add these lines in our PHP files: + +```php +require_once 'path/to/iplib/ip-lib.php'; +``` + +### Installation with Composer + +Simply run + +```sh +composer require mlocati/ip-lib +``` + +or add these lines to your `composer.json` file: + +```json +"require": { + "mlocati/ip-lib": "^1" +} +``` + +## Sample usage + +### Parse an address + +To parse an IPv4 address: + +```php +$address = \IPLib\Address\IPv4::parseString('127.0.0.1'); +``` + +To parse an IPv6 address: + +```php +$address = \IPLib\Address\IPv6::parseString('::1'); +``` + +To parse an address in any format (IPv4 or IPv6): + +```php +$address = \IPLib\Factory::parseAddressString('::1'); +$address = \IPLib\Factory::parseAddressString('127.0.0.1'); +``` + +### Get the next/previous addresses + +```php +$address = \IPLib\Factory::parseAddressString('::1'); + +// This will print :: +echo (string) $address->getPreviousAddress(); + +// This will print ::2 +echo (string) $address->getNextAddress(); +``` + +### Shifting the bits of an address + +You can use the `shift` method to shift the address bits to the right (with positive values) or to the left (negative values): + +```php +$address = \IPLib\Factory::parseAddressString('2.4.8.16'); +// This will print 1.2.4.8 +echo (string) $address->shift(1); +// This will print 4.8.16.32 +echo (string) $address->shift(-1); +// This will print 4.8.16.0 +echo (string) $address->shift(-8); + +$address = \IPLib\Factory::parseAddressString('::10'); +// This will print ::8 +echo (string) $address->shift(1); +// This will print ::20 +echo (string) $address->shift(-1); +// This will print ::10:0 +echo (string) $address->shift(-16); +``` + +### Adding two IP addresses + +You can calculate the sum of 2 IP addresses using the `add` method: + +```php +$a = \IPLib\Factory::parseAddressString('1.2.3.4'); +$b = \IPLib\Factory::parseAddressString('10.0.0.0'); +// This will print 11.2.3.4 +echo (string) $a->add($b); +``` + +### Get the addresses at a specified offset + +For addresses: + +```php +$address = \IPLib\Factory::parseAddressString('::1'); + +// This will print ::1 +echo (string) $address->getAddressAtOffset(0); + +// This will print ::2 +echo (string) $address->getAddressAtOffset(1); + +// This will print ::3 +echo (string) $address->getAddressAtOffset(2); + +// This will print ::3e9 +echo (string) $address->getAddressAtOffset(1000); + +// This will print :: +echo (string) $address->getAddressAtOffset(-1); + +// This will print NULL +echo var_dump($address->getAddressAtOffset(-2)); + +// This will print ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff +echo (string) $address->getAddressAtOffset('340282366920938463463374607431768211454'); + +``` + +For ranges: + +```php +$range = \IPLib\Factory::parseRangeString('::ff00/120'); + +// This will print ::ff00 +echo (string) $range->getAddressAtOffset(0); + +// This will print ::ff10 +echo (string) $range->getAddressAtOffset(16); + +// This will print ::ff64 +echo (string) $range->getAddressAtOffset(100); + +// This will print NULL because the address ::1:0 is out of the range +var_dump($range->getAddressAtOffset(256)); + +// This will print ::ffff +echo (string) $range->getAddressAtOffset(-1); + +// This will print ::fff0 +echo (string) $range->getAddressAtOffset(-16); + +// This will print ::ff00 +echo (string) $range->getAddressAtOffset(-256); + +// This will print NULL because the address ::feff is out of the range +var_dump($range->getAddressAtOffset(-257)); + + +$range2 = \IPLib\Factory::parseRangeString('::/0'); + +// This will print ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff +echo (string) $range2->getAddressAtOffset(-1); + +// This will print ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff +echo (string) $range2->getAddressAtOffset('340282366920938463463374607431768211455'); + +// This will print ::1 +echo (string) $range2->getAddressAtOffset('-340282366920938463463374607431768211455'); + +``` + +### Parse an IP address range + +To parse a subnet (CIDR) range: + +```php +$range = \IPLib\Range\Subnet::parseString('127.0.0.1/24'); +$range = \IPLib\Range\Subnet::parseString('::1/128'); +``` + +To parse a pattern (asterisk notation) range: + +```php +$range = \IPLib\Range\Pattern::parseString('127.0.0.*'); +$range = \IPLib\Range\Pattern::parseString('::*'); +``` + +To parse an address as a range: + +```php +$range = \IPLib\Range\Single::parseString('127.0.0.1'); +$range = \IPLib\Range\Single::parseString('::1'); +``` + +To parse a range in any format: + +```php +$range = \IPLib\Factory::parseRangeString('127.0.0.*'); +$range = \IPLib\Factory::parseRangeString('::1/128'); +$range = \IPLib\Factory::parseRangeString('::'); +``` + +### Retrieve a range from its boundaries + +You can calculate the smallest range that comprises two addresses: + +```php +$range = \IPLib\Factory::getRangeFromBoundaries('192.168.0.1', '192.168.255.255'); + +// This will print 192.168.0.0/16 +echo (string) $range; +``` + +You can also calculate a list of ranges that exactly describes all the addresses between two addresses: + +```php +$ranges = \IPLib\Factory::getRangesFromBoundaries('192.168.0.0', '192.168.0.5'); + +// This will print 192.168.0.0/30 192.168.0.4/31 +echo implode(' ', $ranges); +``` + +### Retrieve a range that contains a set of IP addresses + +You can use `IPLib\Factory::getRangeFromAddresses()` to retrieve the minimal IP range that contains all the provided IP addresses: + +```php +$range = \IPLib\Factory::getRangeFromAddresses(array( + '1.2.2.225', + '1.2.1.124', + '1.2.3.237', +)); + +// This will print 1.2.0.0/22 +echo (string) $range; +``` + +### Retrieve the boundaries of a range + +```php +$range = \IPLib\Factory::parseRangeString('127.0.0.*'); + +// This will print 127.0.0.0 +echo (string) $range->getStartAddress(); + +// This will print 127.0.0.255 +echo (string) $range->getEndAddress(); +``` + +### Format addresses and ranges + +Both IP addresses and ranges have a `toString` method that you can use to retrieve a textual representation: + +```php +// This will print 127.0.0.1 +echo \IPLib\Factory::parseAddressString('127.0.0.1')->toString(); + +// This will print 127.0.0.1 +echo \IPLib\Factory::parseAddressString('127.000.000.001')->toString(); + +// This will print ::1 +echo \IPLib\Factory::parseAddressString('::1')->toString(); + +// This will print ::1 +echo \IPLib\Factory::parseAddressString('0:0::1')->toString(); + +// This will print ::1/64 +echo \IPLib\Factory::parseRangeString('0:0::1/64')->toString(); +``` + +When working with IPv6, you may want the full (expanded) representation of the addresses. In this case, simply use a `true` parameter for the `toString` method: + +```php +// This will print 0000:0000:0000:0000:0000:0000:0000:0000 +echo \IPLib\Factory::parseAddressString('::')->toString(true); + +// This will print 0000:0000:0000:0000:0000:0000:0000:0001 +echo \IPLib\Factory::parseAddressString('::1')->toString(true); + +// This will print 0fff:0000:0000:0000:0000:0000:0000:0000 +echo \IPLib\Factory::parseAddressString('fff::')->toString(true); + +// This will print 0000:0000:0000:0000:0000:0000:0000:0000 +echo \IPLib\Factory::parseAddressString('::0:0')->toString(true); + +// This will print 0001:0002:0003:0004:0005:0006:0007:0008 +echo \IPLib\Factory::parseAddressString('1:2:3:4:5:6:7:8')->toString(true); + +// This will print 0000:0000:0000:0000:0000:0000:0000:0001/64 +echo \IPLib\Factory::parseRangeString('0:0::1/64')->toString(); +``` + +You may also want a *long* representation for IPv4 addresses: here again you can use `true`as the parameter for the `toString` method: + +```php +// This will print 1.2.3.4 +echo \IPLib\Factory::parseAddressString('1.2.3.4')->toString(); + +// This will print 001.002.003.004 +echo \IPLib\Factory::parseAddressString('1.2.3.4')->toString(true); +``` + +The address and range objects implements the `__toString()` method, which call the `toString()` method. +So, if you want the string (short) representation of an object, you can do any of the following: + +```php +$address = \IPLib\Address\IPv6::parseString('::1'); + +// All these will print ::1 +echo $address->toString(); +echo $address->toString(false); +echo (string) $address; +``` + +### Check if an address is contained in a range + +All the range types offer a `contains` method, and all the IP address types offer a `matches` method: you can call them to check if an address is contained in a range: + +```php +$address = \IPLib\Factory::parseAddressString('1:2:3:4:5:6:7:8'); +$range = \IPLib\Factory::parseRangeString('0:0::1/64'); + +$contained = $address->matches($range); +// that's equivalent to +$contained = $range->contains($address); +``` + +Please remark that if the address is IPv4 and the range is IPv6 (or vice-versa), the result will always be `false`. + +### Check if a range contains another range + +All the range types offer a `containsRange` method: you can call them to check if an address range fully contains another range: + +```php +$range1 = \IPLib\Factory::parseRangeString('0:0::1/64'); +$range2 = \IPLib\Factory::parseRangeString('0:0::1/65'); + +$contained = $range1->containsRange($range2); +``` + +### Getting the type of an IP address + +If you want to know if an address is within a private network, or if it's a public IP, or whatever you want, you can use the `getRangeType` method: + +```php +$address = \IPLib\Factory::parseAddressString('::'); + +$type = $address->getRangeType(); + +$typeName = \IPLib\Range\Type::getName($type); +``` + +The most notable values of the range type are: + +- `\IPLib\Range\Type::T_UNSPECIFIED` if the address is all zeros (`0.0.0.0` or `::`) +- `\IPLib\Range\Type::T_LOOPBACK` if the address is the localhost (usually `127.0.0.1` or `::1`) +- `\IPLib\Range\Type::T_PRIVATENETWORK` if the address is in the local network (for instance `192.168.0.1` or `fc00::1`) +- `\IPLib\Range\Type::T_PUBLIC` if the address is for public usage (for instance `104.25.25.33` or `2001:503:ba3e::2:30`) + +### Getting the type of an IP address range + +If you want to know the type of an address range, you can use the `getRangeType` method: + +```php +$range = \IPLib\Factory::parseRangeString('2000:0::1/64'); + +// $type will contain the value of \IPLib\Range\Type::T_PUBLIC +$type = $range->getRangeType(); + +// This will print Public address +echo \IPLib\Range\Type::getName($type); +``` + +Please note that if a range spans across multiple range types, you'll get NULL as the range type: + +```php +$range = \IPLib\Factory::parseRangeString('::/127'); + +// $type will contain null +$type = $range->getRangeType(); + +// This will print Unknown type +echo \IPLib\Range\Type::getName($type); +``` + +### Converting IP addresses + +This library supports converting IPv4 to/from IPv6 addresses using the [6to4 notation](https://tools.ietf.org/html/rfc3056) or the [IPv4-mapped notation](https://tools.ietf.org/html/rfc4291#section-2.5.5.2): + +```php +$ipv4 = \IPLib\Factory::parseAddressString('1.2.3.4'); + +// 6to4 notation +$ipv6 = $ipv4->toIPv6(); + +// This will print 2002:102:304:: +echo (string) $ipv6; + +// This will print 1.2.3.4 +echo $ipv6->toIPv4(); + +// IPv4-mapped notation +$ipv6_6to4 = $ipv4->toIPv6IPv4Mapped(); + +// This will print ::ffff:1.2.3.4 +echo (string) $ipv6_6to4; + +// This will print 1.2.3.4 +echo $ipv6_6to4->toIPv4(); +``` + +### Converting IP ranges + +This library supports IPv4/IPv6 ranges in pattern format (eg. `192.168.*.*`) and in CIDR/subnet format (eg. `192.168.0.0/16`), and it offers a way to convert between the two formats: + +```php +// This will print ::*:*:*:* +echo \IPLib\Factory::parseRangeString('::/64')->asPattern()->toString(); + +// This will print 1:2::/96 +echo \IPLib\Factory::parseRangeString('1:2::*:*')->asSubnet()->toString(); + +// This will print 192.168.0.0/24 +echo \IPLib\Factory::parseRangeString('192.168.0.*')->asSubnet()->toString(); + +// This will print 10.*.*.* +echo \IPLib\Factory::parseRangeString('10.0.0.0/8')->asPattern()->toString(); +``` + +Please remark that all the range types implement the `asPattern()` and `asSubnet()` methods. + +### Splitting IP ranges + +If you need to divide an IP address range into smaller ranges, you can use the `split` method. +You can specify the length of the network prefix, as well as indicate whether you want to force the Subnet notation (by default, it is not). + +For example: + +```php +$subnet = \IPLib\Factory::parseRangeString('192.168.112.203/24'); +$smallerSubnets = $subnet->split(25); +print_r(array_map('strval', $smallerSubnets)); +/* + * You'll have: + * Array + * ( + * [0] => 192.168.112.0/25 + * [1] => 192.168.112.128/25 + * ) + */ + +$subnet = \IPLib\Factory::parseRangeString('192.168.*.*'); +$smallerSubnets = $subnet->split(24); +print_r(array_map('strval', $smallerSubnets)); +/* + * You'll have: + * Array + * ( + * [0] => 192.168.0.* + * [1] => 192.168.1.* + * [...] + * [254] => 192.168.254.* + * [255] => 192.168.255.* + * ) + */ + +$subnet = \IPLib\Factory::parseRangeString('192.168.*.*'); +$smallerSubnets = $subnet->split(24, true); +print_r(array_map('strval', $smallerSubnets)); +/* + * You'll have: + * Array + * ( + * [0] => 192.168.0.0/24 + * [1] => 192.168.1.0/24 + * [...] + * [254] => 192.168.254.0/24 + * [255] => 192.168.255.0/24 + * ) + */ +``` + +### Getting the subnet mask for IPv4 ranges + +You can use the `getSubnetMask()` to get the subnet mask for IPv4 ranges: + +```php +// This will print 255.255.255.0 +echo \IPLib\Factory::parseRangeString('192.168.0.*')->getSubnetMask()->toString(); + +// This will print 255.255.255.252 +echo \IPLib\Factory::parseRangeString('192.168.0.12/30')->getSubnetMask()->toString(); +``` + +### Getting the range size + +You can use the `getSize()` to get the count of addresses this IP range contains: + +```php +// This will print 256 +echo \IPLib\Factory::parseRangeString('192.168.0.*')->getSize(); + +// This will print 4 +echo \IPLib\Factory::parseRangeString('192.168.0.12/30')->getSize(); + +// This will print 1 +echo \IPLib\Factory::parseRangeString('192.168.0.1')->getSize(); +``` + +Please note that if the number of IP addresses contained in the range is greater than the maximum integer supported by the operating system (2,147,483,647 for 32-bit systems, 9,223,372,036,854,775,807 for 64-bit systems), the `getSize()` method will return a `float` (which may be not precise). + +If instead you want the exact number of IP addresses, you can use the `getExactSize()` method, which will return a string containing the number of IP addresses in decimal format in case of such big numbers. + +```php +// This will print: +// int(1) +var_dump(\IPLib\Factory::parseRangeString('0.0.0.0/32')->getExactSize()); + +// On 32-bit systems, this will print +// string(10) "2147483648" +// On 64-bit systems, this will print +// int(2147483648) +var_dump(\IPLib\Factory::parseRangeString('0.0.0.0/1')->getExactSize()); + +// This will print: +// int(1073741824) +var_dump(\IPLib\Factory::parseRangeString('::/98')->getExactSize()); + +// On 32-bit systems, this will print +// string(10) "2147483648" +// On 64-bit systems, this will print +// int(2147483648) +var_dump(\IPLib\Factory::parseRangeString('::/97')->getExactSize()); + +// On 32-bit and 64-bit systems, this will print +// string(39) "170141183460469231731687303715884105728" +var_dump(\IPLib\Factory::parseRangeString('::/1')->getExactSize()); +``` + +### Getting the reverse DNS lookup address + +To perform reverse DNS queries, you need to use a special format of the IP addresses. + +You can use the `getReverseDNSLookupName()` method of the IP address instances to retrieve it easily: + +```php +$ipv4 = \IPLib\Factory::parseAddressString('1.2.3.255'); +$ipv6 = \IPLib\Factory::parseAddressString('1234:abcd::cafe:babe'); + +// This will print 255.3.2.1.in-addr.arpa +echo $ipv4->getReverseDNSLookupName(); + +// This will print e.b.a.b.e.f.a.c.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.c.b.a.4.3.2.1.ip6.arpa +echo $ipv6->getReverseDNSLookupName(); +``` + +To parse addresses in reverse DNS lookup format you can use the `IPLib\ParseStringFlag::ADDRESS_MAYBE_RDNS` flag when parsing a string: + +```php +$ipv4 = \IPLib\Factory::parseAddressString('255.3.2.1.in-addr.arpa', \IPLib\ParseStringFlag::ADDRESS_MAYBE_RDNS); +$ipv6 = \IPLib\Factory::parseAddressString('e.b.a.b.e.f.a.c.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.c.b.a.4.3.2.1.ip6.arpa', \IPLib\ParseStringFlag::ADDRESS_MAYBE_RDNS); + +// This will print 1.2.3.255 +echo $ipv4->toString(); + +// This will print 1234:abcd::cafe:babe +echo $ipv6->toString(); +``` + +You can also use `getReverseDNSLookupName()` for IP ranges. +In this case, the result is an array of strings: + +```php +$range = \IPLib\Factory::parseRangeString('10.155.16.0/22'); + +/* + * This will print: + * array ( + * 0 => '16.155.10.in-addr.arpa', + * 1 => '17.155.10.in-addr.arpa', + * 2 => '18.155.10.in-addr.arpa', + * 3 => '19.155.10.in-addr.arpa', + * ) +*/ +var_export($range->getReverseDNSLookupName()); +``` + +### Using a database + +This package offers a great feature: you can store address ranges in a database table, and check if an address is contained in one of the saved ranges with a simple query. + +To save a range, you need to store the address type (for IPv4 it's `4`, for IPv6 it's `6`), as well as two values representing the start and the end of the range. +These methods are: +```php +$range->getAddressType(); +$range->getComparableStartString(); +$range->getComparableEndString(); +``` + +Let's assume that you saved the type in a field called `addressType`, and the range boundaries in two fields called `rangeFrom` and `rangeTo`. + +When you want to check if an address is within a stored range, simply use the `getComparableString` method of the address and check if it's between the fields `rangeFrom` and `rangeTo`, and check if the stored `addressType` is the same as the one of the address instance you want to check. + +Here's a sample code: + +```php +/* + * Let's assume that: + * - $pdo is a PDO instance + * - $range is a range object + * - $address is an address object + */ + +// Save the $range object +$insertQuery = $pdo->prepare(' + insert into ranges (addressType, rangeFrom, rangeTo) + values (:addressType, :rangeFrom, :rangeTo) +'); + +$insertQuery->execute(array( + ':addressType' => $range->getAddressType(), + ':rangeFrom' => $range->getComparableStartString(), + ':rangeTo' => $range->getComparableEndString(), +)); + +// Retrieve the saved ranges where an address $address falls: +$searchQuery = $pdo->prepare(' + select * from ranges + where addressType = :addressType + and :address between rangeFrom and rangeTo +'); + +$searchQuery->execute(array( + ':addressType' => $address->getAddressType(), + ':address' => $address->getComparableString(), +)); + +$rows = $searchQuery->fetchAll(); +$searchQuery->closeCursor(); +``` + +## Handling non-standard address and range strings + +### Accepting ports + +If you want to accept addresses that may include ports, you can specify the `IPLib\ParseStringFlag::MAY_INCLUDE_PORT` flag: + +```php +use IPLib\Factory; +use IPLib\ParseStringFlag; + +require_once __DIR__ . '/../ip-lib.php'; + +// These will print NULL +var_export(Factory::parseAddressString('127.0.0.1:80')); +var_export(Factory::parseAddressString('[::]:80')); + +// This will print 127.0.0.1 +echo (string) Factory::parseAddressString('127.0.0.1:80', ParseStringFlag::MAY_INCLUDE_PORT); +// This will print :: +echo (string) Factory::parseAddressString('[::]:80', ParseStringFlag::MAY_INCLUDE_PORT); +``` + +### Accepting IPv6 zone IDs + +If you want to accept IPv6 addresses that may include a zone ID, you can specify the `IPLib\ParseStringFlag::MAY_INCLUDE_ZONEID` flag: + +```php +use IPLib\Factory; +use IPLib\ParseStringFlag; + +// This will print NULL +var_export(Factory::parseAddressString('::%11')); + +// This will print :: +echo (string) Factory::parseAddressString('::%11', ParseStringFlag::MAY_INCLUDE_ZONEID); +``` + +### Accepting non-decimal IPv4 addresses + +IPv4 addresses are usually expressed in decimal notation, for example as `192.168.0.1`. + +By the way, the GNU (used in many Linux distros), BSD (used in Mac) and Windows implementations of `inet_aton` and `inet_addr` accept IPv4 addresses with numbers in octal and/or hexadecimal format. +Please remark that this does not apply to the `inet_pton` and `ip2long` functions, as well as to the Musl implementation (used in Alpine Linux) of `inet_aton` and `inet_addr`. + +So, for example, these addresses are all equivalent to `192.168.0.1`: + +- `0xC0.0xA8.0x0.0x01` (only hexadecimal) +- `0300.0250.00.01` (only octal) +- `192.0250.0.0x01` (decimal, octal and hexadecimal numbers) + +(try it: if you browse to [`http://0177.0.0.0x1`](http://0177.0.0.0x1), your browser will try to browse `http://127.0.0.1`). + +If you want to accept this non-decimal syntax, you may use the `IPLib\ParseStringFlag::IPV4_MAYBE_NON_DECIMAL` flag: + +```php +use IPLib\Factory; +use IPLib\ParseStringFlag; + +// This will print NULL +var_export(Factory::parseAddressString('0177.0.0.0x1')); + +// This will print 127.0.0.1 +var_export((string) Factory::parseAddressString('0177.0.0.0x1', ParseStringFlag::IPV4_MAYBE_NON_DECIMAL)); + +// This will print NULL +var_export(Factory::parseRangeString('0177.0.0.0x1/32')); + +// This will print 127.0.0.1/32 +var_export((string) Factory::parseRangeString('0177.0.0.0x1/32', ParseStringFlag::IPV4_MAYBE_NON_DECIMAL)); +``` + +Please be aware that the `IPV4_MAYBE_NON_DECIMAL` flag may also affect parsing decimal numbers: + +```php +use IPLib\Factory; +use IPLib\ParseStringFlag; + +// This will print 127.0.0.10 since the last digit is assumed to be decimal +var_export((string) Factory::parseAddressString('127.0.0.010')); + +// This will print 127.0.0.8 since the last digit is assumed to be octal +var_export((string) Factory::parseAddressString('127.0.0.010', ParseStringFlag::IPV4_MAYBE_NON_DECIMAL)); +``` + +### Accepting IPv4 addresses in not-quad-dotted notation + +IPv4 addresses are usually expressed with 4 numbers, for example as `192.168.0.1`. + +By the way, the GNU (used in many Linux distros), BSD (used in Mac) and Windows implementations of `inet_aton` and `inet_addr` [accept IPv4 addresses with 1 to 4 numbers](https://man7.org/linux/man-pages/man3/inet_addr.3.html#DESCRIPTION). + +Please remark that this does not apply to the `inet_pton` and `ip2long` functions, as well as to the Musl implementation (used in Alpine Linux) of `inet_aton` and `inet_addr`. + +If you want to accept this non-decimal syntax, you may use the `IPLib\ParseStringFlag::IPV4ADDRESS_MAYBE_NON_QUAD_DOTTED` flag: + +```php +use IPLib\Factory; +use IPLib\ParseStringFlag; + +// This will print NULL +var_export(Factory::parseAddressString('1.2.500')); + +// This will print 0.0.0.0 +var_export((string) Factory::parseAddressString('0', ParseStringFlag::IPV4ADDRESS_MAYBE_NON_QUAD_DOTTED)); + +// This will print 0.0.0.1 +var_export((string) Factory::parseAddressString('1', ParseStringFlag::IPV4ADDRESS_MAYBE_NON_QUAD_DOTTED)); + +// This will print 0.0.1.244 +var_export((string) Factory::parseAddressString('0.0.500', ParseStringFlag::IPV4ADDRESS_MAYBE_NON_QUAD_DOTTED)); + +// This will print 255.255.255.255 +var_export((string) Factory::parseAddressString('4294967295', ParseStringFlag::IPV4ADDRESS_MAYBE_NON_QUAD_DOTTED)); +``` + +### Accepting compact IPv4 subnet notation + +Even if there isn't an RFC that describe it, IPv4 subnet notation may also be written in a compact form, omitting extra digits (for example, `127.0.0.0/24` may be written as `127/24`). +If you want to accept such format, you can specify the `IPLib\ParseStringFlag::IPV4SUBNET_MAYBE_COMPACT` flag: + +```php +use IPLib\Factory; +use IPLib\ParseStringFlag; + +// This will print NULL +var_export(Factory::parseRangeString('127/24')); + +// This will print 127.0.0.0/24 +echo (string) Factory::parseRangeString('127/24', ParseStringFlag::IPV4SUBNET_MAYBE_COMPACT); +``` + +### Combining multiple flags + +Of course, you may use more than one `IPLib\ParseStringFlag` flag at once: + +```php +use IPLib\Factory; +use IPLib\ParseStringFlag; + +// This will print 127.0.0.255 +var_export((string) Factory::parseAddressString('127.0.0.0xff:80', ParseStringFlag::MAY_INCLUDE_PORT | ParseStringFlag::IPV4_MAYBE_NON_DECIMAL)); + +// This will print :: +var_export((string) Factory::parseAddressString('[::%11]:80', ParseStringFlag::MAY_INCLUDE_PORT | ParseStringFlag::MAY_INCLUDE_ZONEID)); +``` + +## Gitpod Environment Variables + +The following features can be enabled through environment variables that have been set in your [Gitpod preferences](https://gitpod.io/variables).: + +\* _Please note that storing sensitive data in environment variables is not ultimately secure but should be OK for most development situations._ +- ### Sign Git commits with a GPG key + - `GPG_KEY_ID` (required) + - The ID of the GPG key you want to use to sign your git commits + - `GPG_KEY` (required) + - Base64 encoded private GPG key that corresponds to your `GPG_KEY_ID` + - `GPG_MATCH_GIT_TO_EMAIL` (optional) + - Sets your git user.email in `~/.gitconfig` to the value provided + - `GPG_AUTO_ULTIMATE_TRUST` (optional) + - If the value is set to `yes` or `YES` then your `GPG_KEY` will be automatically ultimately trusted +- ### Activate an Intelliphense License Key + - `INTELEPHENSE_LICENSEKEY` + - Creates `~/intelephense/licence.txt` and will contain the value provided + - This will activate [Intelliphense](https://intelephense.com/) for you each time the workspace is created or restarted + +## Do you really want to say thank you? + +You can offer me a [monthly coffee](https://github.com/sponsors/mlocati) or a [one-time coffee](https://paypal.me/mlocati) :wink: diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/composer.json b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/composer.json new file mode 100755 index 00000000..bb11be45 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/composer.json @@ -0,0 +1,60 @@ +{ + "name": "mlocati/ip-lib", + "description": "Handle IPv4, IPv6 addresses and ranges", + "type": "library", + "license": "MIT", + "homepage": "https://github.com/mlocati/ip-lib", + "authors": [ + { + "name": "Michele Locati", + "homepage": "https://github.com/mlocati", + "email": "mlocati@gmail.com", + "role": "Author" + } + ], + "keywords": [ + "ip", + "ipv4", + "ipv6", + "range", + "network", + "networking", + "address", + "addresses", + "subnet", + "matching", + "managing", + "manage" + ], + "require": { + "php": ">=5.3.3" + }, + "autoload": { + "psr-4": { + "IPLib\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "IPLib\\Test\\": "test/tests/", + "IPLib\\Test\\Helpers\\": "test/helpers/" + } + }, + "require-dev": { + "ext-pdo_sqlite": "*", + "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5 || ^8.5 || ^9.5" + }, + "scripts": { + "test": "phpunit" + }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mlocati" + }, + { + "type": "other", + "url": "https://paypal.me/mlocati" + } + ] +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/ip-lib.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/ip-lib.php new file mode 100755 index 00000000..c34d0b49 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/ip-lib.php @@ -0,0 +1,13 @@ +range = $range; + $this->type = $type; + $this->exceptions = $exceptions; + } + + /** + * Get the range definition. + * + * @return \IPLib\Range\RangeInterface + */ + public function getRange() + { + return $this->range; + } + + /** + * Get the range type. + * + * @return int one of the \IPLib\Range\Type::T_ constants + */ + public function getType() + { + return $this->type; + } + + /** + * Get the list of exceptions for this range type. + * + * @return \IPLib\Address\AssignedRange[] + */ + public function getExceptions() + { + return $this->exceptions; + } + + /** + * Get the assigned type for a specific address. + * + * @param \IPLib\Address\AddressInterface $address + * + * @return int|null return NULL of the address is outside this address; a \IPLib\Range\Type::T_ constant otherwise + */ + public function getAddressType(AddressInterface $address) + { + $result = null; + if ($this->range->contains($address)) { + foreach ($this->exceptions as $exception) { + $result = $exception->getAddressType($address); + if ($result !== null) { + break; + } + } + if ($result === null) { + $result = $this->type; + } + } + + return $result; + } + + /** + * Get the assigned type for a specific address range. + * + * @param \IPLib\Range\RangeInterface $range + * + * @return int|false|null return NULL of the range is fully outside this range; false if it's partly crosses this range (or it contains mixed types); a \IPLib\Range\Type::T_ constant otherwise + */ + public function getRangeType(RangeInterface $range) + { + $myStart = $this->range->getComparableStartString(); + $rangeEnd = $range->getComparableEndString(); + if ($myStart > $rangeEnd) { + $result = null; + } else { + $myEnd = $this->range->getComparableEndString(); + $rangeStart = $range->getComparableStartString(); + if ($myEnd < $rangeStart) { + $result = null; + } elseif ($rangeStart < $myStart || $rangeEnd > $myEnd) { + $result = false; + } else { + $result = null; + foreach ($this->exceptions as $exception) { + $result = $exception->getRangeType($range); + if ($result !== null) { + break; + } + } + if ($result === null) { + $result = $this->getType(); + } + } + } + + return $result; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Address/IPv4.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Address/IPv4.php new file mode 100755 index 00000000..c5f691e2 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Address/IPv4.php @@ -0,0 +1,582 @@ +address = $address; + $this->bytes = null; + $this->rangeType = null; + $this->comparableString = null; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::__toString() + */ + public function __toString() + { + return $this->address; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getNumberOfBits() + */ + public static function getNumberOfBits() + { + return 32; + } + + /** + * @deprecated since 1.17.0: use the parseString() method instead. + * For upgrading: + * - if $mayIncludePort is true, use the ParseStringFlag::MAY_INCLUDE_PORT flag + * - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag + * + * @param string|mixed $address the address to parse + * @param bool $mayIncludePort + * @param bool $supportNonDecimalIPv4 + * + * @return static|null + * + * @see \IPLib\Address\IPv4::parseString() + * @since 1.1.0 added the $mayIncludePort argument + * @since 1.10.0 added the $supportNonDecimalIPv4 argument + */ + public static function fromString($address, $mayIncludePort = true, $supportNonDecimalIPv4 = false) + { + return static::parseString($address, 0 | ($mayIncludePort ? ParseStringFlag::MAY_INCLUDE_PORT : 0) | ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0)); + } + + /** + * Parse a string and returns an IPv4 instance if the string is valid, or null otherwise. + * + * @param string|mixed $address the address to parse + * @param int $flags A combination or zero or more flags + * + * @return static|null + * + * @see \IPLib\ParseStringFlag + * @since 1.17.0 + */ + public static function parseString($address, $flags = 0) + { + if (!is_string($address)) { + return null; + } + $flags = (int) $flags; + $matches = null; + if ($flags & ParseStringFlag::ADDRESS_MAYBE_RDNS) { + if (preg_match('/^([12]?[0-9]{1,2}\.[12]?[0-9]{1,2}\.[12]?[0-9]{1,2}\.[12]?[0-9]{1,2})\.in-addr\.arpa\.?$/i', $address, $matches)) { + $address = implode('.', array_reverse(explode('.', $matches[1]))); + $flags = $flags & ~(ParseStringFlag::IPV4_MAYBE_NON_DECIMAL | ParseStringFlag::IPV4ADDRESS_MAYBE_NON_QUAD_DOTTED); + } + } + if ($flags & ParseStringFlag::IPV4ADDRESS_MAYBE_NON_QUAD_DOTTED) { + if (strpos($address, '.') === 0) { + return null; + } + $lengthNonHex = '{1,11}'; + $lengthHex = '{1,8}'; + $chunk234Optional = true; + } else { + if (!strpos($address, '.')) { + return null; + } + $lengthNonHex = '{1,3}'; + $lengthHex = '{1,2}'; + $chunk234Optional = false; + } + $rxChunk1 = "0?[0-9]{$lengthNonHex}"; + if ($flags & ParseStringFlag::IPV4_MAYBE_NON_DECIMAL) { + $rxChunk1 = "(?:0[Xx]0*[0-9A-Fa-f]{$lengthHex})|(?:{$rxChunk1})"; + $onlyDecimal = false; + } else { + $onlyDecimal = true; + } + $rxChunk1 = "0*?({$rxChunk1})"; + $rxChunk234 = "\.{$rxChunk1}"; + if ($chunk234Optional) { + $rxChunk234 = "(?:{$rxChunk234})?"; + } + $rx = "{$rxChunk1}{$rxChunk234}{$rxChunk234}{$rxChunk234}"; + if ($flags & ParseStringFlag::MAY_INCLUDE_PORT) { + $rx .= '(?::\d+)?'; + } + if (!preg_match('/^' . $rx . '$/', $address, $matches)) { + return null; + } + $math = new \IPLib\Service\UnsignedIntegerMath(); + $nums = array(); + $maxChunkIndex = count($matches) - 1; + for ($i = 1; $i <= $maxChunkIndex; $i++) { + $numBytes = $i === $maxChunkIndex ? 5 - $i : 1; + $chunkBytes = $math->getBytes($matches[$i], $numBytes, $onlyDecimal); + if ($chunkBytes === null) { + return null; + } + $nums = array_merge($nums, $chunkBytes); + } + + return new static(implode('.', $nums)); + } + + /** + * Parse an array of bytes and returns an IPv4 instance if the array is valid, or null otherwise. + * + * @param array $bytes + * + * @return static|null + */ + public static function fromBytes(array $bytes) + { + $result = null; + if (count($bytes) === 4) { + $chunks = array_map( + function ($byte) { + return (is_int($byte) && $byte >= 0 && $byte <= 255) ? (string) $byte : false; + }, + $bytes + ); + if (in_array(false, $chunks, true) === false) { + $result = new static(implode('.', $chunks)); + } + } + + return $result; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::toString() + */ + public function toString($long = false) + { + if ($long) { + return $this->getComparableString(); + } + + return $this->address; + } + + /** + * Get the octal representation of this IP address. + * + * @param bool $long + * + * @return string + * + * @since 1.10.0 + * + * @example if $long == false: if the decimal representation is '0.7.8.255': '0.7.010.0377' + * @example if $long == true: if the decimal representation is '0.7.8.255': '0000.0007.0010.0377' + */ + public function toOctal($long = false) + { + $chunks = array(); + foreach ($this->getBytes() as $byte) { + if ($long) { + $chunks[] = sprintf('%04o', $byte); + } else { + $chunks[] = '0' . decoct($byte); + } + } + + return implode('.', $chunks); + } + + /** + * Get the hexadecimal representation of this IP address. + * + * @param bool $long + * + * @return string + * + * @since 1.10.0 + * + * @example if $long == false: if the decimal representation is '0.9.10.255': '0.9.0xa.0xff' + * @example if $long == true: if the decimal representation is '0.9.10.255': '0x00.0x09.0x0a.0xff' + */ + public function toHexadecimal($long = false) + { + $chunks = array(); + foreach ($this->getBytes() as $byte) { + if ($long) { + $chunks[] = sprintf('0x%02x', $byte); + } else { + $chunks[] = '0x' . dechex($byte); + } + } + + return implode('.', $chunks); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getBytes() + */ + public function getBytes() + { + if ($this->bytes === null) { + $this->bytes = array_map( + function ($chunk) { + return (int) $chunk; + }, + explode('.', $this->address) + ); + } + + return $this->bytes; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getBits() + */ + public function getBits() + { + $parts = array(); + foreach ($this->getBytes() as $byte) { + $parts[] = sprintf('%08b', $byte); + } + + return implode('', $parts); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getAddressType() + */ + public function getAddressType() + { + return Type::T_IPv4; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getDefaultReservedRangeType() + */ + public static function getDefaultReservedRangeType() + { + return RangeType::T_PUBLIC; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getReservedRanges() + */ + public static function getReservedRanges() + { + if (self::$reservedRanges === null) { + $reservedRanges = array(); + foreach (array( + // RFC 5735 + '0.0.0.0/8' => array(RangeType::T_THISNETWORK, array('0.0.0.0/32' => RangeType::T_UNSPECIFIED)), + // RFC 5735 + '10.0.0.0/8' => array(RangeType::T_PRIVATENETWORK), + // RFC 6598 + '100.64.0.0/10' => array(RangeType::T_CGNAT), + // RFC 5735 + '127.0.0.0/8' => array(RangeType::T_LOOPBACK), + // RFC 5735 + '169.254.0.0/16' => array(RangeType::T_LINKLOCAL), + // RFC 5735 + '172.16.0.0/12' => array(RangeType::T_PRIVATENETWORK), + // RFC 5735 + '192.0.0.0/24' => array(RangeType::T_RESERVED), + // RFC 5735 + '192.0.2.0/24' => array(RangeType::T_RESERVED), + // RFC 5735 + '192.88.99.0/24' => array(RangeType::T_ANYCASTRELAY), + // RFC 5735 + '192.168.0.0/16' => array(RangeType::T_PRIVATENETWORK), + // RFC 5735 + '198.18.0.0/15' => array(RangeType::T_RESERVED), + // RFC 5735 + '198.51.100.0/24' => array(RangeType::T_RESERVED), + // RFC 5735 + '203.0.113.0/24' => array(RangeType::T_RESERVED), + // RFC 5735 + '224.0.0.0/4' => array(RangeType::T_MULTICAST), + // RFC 5735 + '240.0.0.0/4' => array(RangeType::T_RESERVED, array('255.255.255.255/32' => RangeType::T_LIMITEDBROADCAST)), + ) as $range => $data) { + $exceptions = array(); + if (isset($data[1])) { + foreach ($data[1] as $exceptionRange => $exceptionType) { + $subnet = Subnet::parseString($exceptionRange); + /** @var Subnet $subnet */ + $exceptions[] = new AssignedRange($subnet, $exceptionType); + } + } + $subnet = Subnet::parseString($range); + /** @var Subnet $subnet */ + $reservedRanges[] = new AssignedRange($subnet, $data[0], $exceptions); + } + self::$reservedRanges = $reservedRanges; + } + + return self::$reservedRanges; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getRangeType() + */ + public function getRangeType() + { + if ($this->rangeType === null) { + $rangeType = null; + foreach (static::getReservedRanges() as $reservedRange) { + $rangeType = $reservedRange->getAddressType($this); + if ($rangeType !== null) { + break; + } + } + $this->rangeType = $rangeType === null ? static::getDefaultReservedRangeType() : $rangeType; + } + + return $this->rangeType; + } + + /** + * Create an IPv6 representation of this address (in 6to4 notation). + * + * @return \IPLib\Address\IPv6 + */ + public function toIPv6() + { + $myBytes = $this->getBytes(); + $ipv6 = IPv6::parseString('2002:' . sprintf('%02x', $myBytes[0]) . sprintf('%02x', $myBytes[1]) . ':' . sprintf('%02x', $myBytes[2]) . sprintf('%02x', $myBytes[3]) . '::'); + /** @var IPv6 $ipv6 */ + + return $ipv6; + } + + /** + * Create an IPv6 representation of this address (in IPv6 IPv4-mapped notation). + * + * @return \IPLib\Address\IPv6 + * + * @since 1.11.0 + */ + public function toIPv6IPv4Mapped() + { + $ipv6 = IPv6::fromBytes(array_merge(array(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff), $this->getBytes())); + /** @var IPv6 $ipv6 */ + + return $ipv6; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getComparableString() + */ + public function getComparableString() + { + if ($this->comparableString === null) { + $chunks = array(); + foreach ($this->getBytes() as $byte) { + $chunks[] = sprintf('%03d', $byte); + } + $this->comparableString = implode('.', $chunks); + } + + return $this->comparableString; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::matches() + */ + public function matches(RangeInterface $range) + { + return $range->contains($this); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getAddressAtOffset() + */ + public function getAddressAtOffset($n) + { + if (is_int($n)) { + $thatChunks = NumberInChunks::fromInteger($n, NumberInChunks::CHUNKSIZE_BYTES); + } elseif (($s = BinaryMath::getInstance()->normalizeIntegerString($n)) !== '') { + $thatChunks = NumberInChunks::fromNumericString($s, NumberInChunks::CHUNKSIZE_BYTES); + } else { + return null; + } + $myBytes = $this->getBytes(); + while (isset($myBytes[1]) && $myBytes[0] === 0) { + array_shift($myBytes); + } + $myChunks = new NumberInChunks(false, $myBytes, NumberInChunks::CHUNKSIZE_BYTES); + $result = $myChunks->add($thatChunks); + if ($result->negative || count($result->chunks) > 4) { + return null; + } + + return static::fromBytes(array_pad($result->chunks, -4, 0)); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getNextAddress() + */ + public function getNextAddress() + { + return $this->getAddressAtOffset(1); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getPreviousAddress() + */ + public function getPreviousAddress() + { + return $this->getAddressAtOffset(-1); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getReverseDNSLookupName() + */ + public function getReverseDNSLookupName() + { + return implode( + '.', + array_reverse($this->getBytes()) + ) . '.in-addr.arpa'; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::shift() + */ + public function shift($bits) + { + $bits = (int) $bits; + if ($bits === 0) { + return $this; + } + $absBits = abs($bits); + if ($absBits >= 32) { + return new self('0.0.0.0'); + } + $pad = str_repeat('0', $absBits); + $paddedBits = $this->getBits(); + if ($bits > 0) { + $paddedBits = $pad . substr($paddedBits, 0, -$bits); + } else { + $paddedBits = substr($paddedBits, $absBits) . $pad; + } + $bytes = array_map('bindec', str_split($paddedBits, 8)); + + return new static(implode('.', $bytes)); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::add() + */ + public function add(AddressInterface $other) + { + if (!$other instanceof self) { + return null; + } + $myBytes = $this->getBytes(); + $otherBytes = $other->getBytes(); + $sum = array_fill(0, 4, 0); + $carry = 0; + for ($index = 3; $index >= 0; $index--) { + $byte = $myBytes[$index] + $otherBytes[$index] + $carry; + if ($byte > 0xFF) { + $carry = $byte >> 8; + $byte &= 0xFF; + } else { + $carry = 0; + } + $sum[$index] = $byte; + } + if ($carry !== 0) { + return null; + } + + return new static(implode('.', $sum)); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Address/IPv6.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Address/IPv6.php new file mode 100755 index 00000000..149becdf --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Address/IPv6.php @@ -0,0 +1,679 @@ +longAddress = $longAddress; + $this->shortAddress = null; + $this->bytes = null; + $this->words = null; + $this->rangeType = null; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::__toString() + */ + public function __toString() + { + return $this->toString(); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getNumberOfBits() + */ + public static function getNumberOfBits() + { + return 128; + } + + /** + * @deprecated since 1.17.0: use the parseString() method instead. + * For upgrading: + * - if $mayIncludePort is true, use the ParseStringFlag::MAY_INCLUDE_PORT flag + * - if $mayIncludeZoneID is true, use the ParseStringFlag::MAY_INCLUDE_ZONEID flag + * + * @param string|mixed $address + * @param bool $mayIncludePort + * @param bool $mayIncludeZoneID + * + * @return static|null + * + * @see \IPLib\Address\IPv6::parseString() + * @since 1.1.0 added the $mayIncludePort argument + * @since 1.3.0 added the $mayIncludeZoneID argument + */ + public static function fromString($address, $mayIncludePort = true, $mayIncludeZoneID = true) + { + return static::parseString($address, 0 | ($mayIncludePort ? ParseStringFlag::MAY_INCLUDE_PORT : 0) | ($mayIncludeZoneID ? ParseStringFlag::MAY_INCLUDE_ZONEID : 0)); + } + + /** + * Parse a string and returns an IPv6 instance if the string is valid, or null otherwise. + * + * @param string|mixed $address the address to parse + * @param int $flags A combination or zero or more flags + * + * @return static|null + * + * @see \IPLib\ParseStringFlag + * @since 1.17.0 + */ + public static function parseString($address, $flags = 0) + { + if (!is_string($address)) { + return null; + } + $matches = null; + $flags = (int) $flags; + if ($flags & ParseStringFlag::ADDRESS_MAYBE_RDNS) { + if (preg_match('/^([0-9a-f](?:\.[0-9a-f]){31})\.ip6\.arpa\.?/i', $address, $matches)) { + $nibbles = array_reverse(explode('.', $matches[1])); + $quibbles = array(); + foreach (array_chunk($nibbles, 4) as $n) { + $quibbles[] = implode('', $n); + } + $address = implode(':', $quibbles); + } + } + $result = null; + if (strpos($address, ':') !== false && strpos($address, ':::') === false) { + if ($flags & ParseStringFlag::MAY_INCLUDE_PORT && $address[0] === '[' && preg_match('/^\[(.+)]:\d+$/', $address, $matches)) { + $address = $matches[1]; + } + if ($flags & ParseStringFlag::MAY_INCLUDE_ZONEID) { + $percentagePos = strpos($address, '%'); + if ($percentagePos > 0) { + $address = substr($address, 0, $percentagePos); + } + } + if (preg_match('/^((?:[0-9a-f]*:+)+)(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/i', $address, $matches)) { + $address6 = static::parseString($matches[1] . '0:0'); + if ($address6 !== null) { + $address4 = IPv4::parseString($matches[2]); + if ($address4 !== null) { + $bytes4 = $address4->getBytes(); + $address6->longAddress = substr($address6->longAddress, 0, -9) . sprintf('%02x%02x:%02x%02x', $bytes4[0], $bytes4[1], $bytes4[2], $bytes4[3]); + $result = $address6; + } + } + } else { + if (strpos($address, '::') === false) { + $chunks = explode(':', $address); + } else { + $chunks = array(); + $parts = explode('::', $address); + if (count($parts) === 2) { + $before = ($parts[0] === '') ? array() : explode(':', $parts[0]); + $after = ($parts[1] === '') ? array() : explode(':', $parts[1]); + $missing = 8 - count($before) - count($after); + if ($missing >= 0) { + $chunks = $before; + if ($missing !== 0) { + $chunks = array_merge($chunks, array_fill(0, $missing, '0')); + } + $chunks = array_merge($chunks, $after); + } + } + } + if (count($chunks) === 8) { + $nums = array_map( + function ($chunk) { + return preg_match('/^[0-9A-Fa-f]{1,4}$/', $chunk) ? hexdec($chunk) : false; + }, + $chunks + ); + if (!in_array(false, $nums, true)) { + $longAddress = implode( + ':', + array_map( + function ($num) { + return sprintf('%04x', $num); + }, + $nums + ) + ); + $result = new static($longAddress); + } + } + } + } + + return $result; + } + + /** + * Parse an array of bytes and returns an IPv6 instance if the array is valid, or null otherwise. + * + * @param array $bytes + * + * @return static|null + */ + public static function fromBytes(array $bytes) + { + $result = null; + if (count($bytes) === 16) { + $address = ''; + for ($i = 0; $i < 16; $i++) { + if ($i !== 0 && $i % 2 === 0) { + $address .= ':'; + } + $byte = $bytes[$i]; + if (is_int($byte) && $byte >= 0 && $byte <= 255) { + $address .= sprintf('%02x', $byte); + } else { + $address = null; + break; + } + } + if ($address !== null) { + $result = new static($address); + } + } + + return $result; + } + + /** + * Parse an array of words and returns an IPv6 instance if the array is valid, or null otherwise. + * + * @param array $words + * + * @return static|null + */ + public static function fromWords(array $words) + { + $result = null; + if (count($words) === 8) { + $chunks = array(); + for ($i = 0; $i < 8; $i++) { + $word = $words[$i]; + if (is_int($word) && $word >= 0 && $word <= 0xffff) { + $chunks[] = sprintf('%04x', $word); + } else { + $chunks = null; + break; + } + } + if ($chunks !== null) { + $result = new static(implode(':', $chunks)); + } + } + + return $result; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::toString() + */ + public function toString($long = false) + { + if ($long) { + $result = $this->longAddress; + } else { + if ($this->shortAddress === null) { + if (strpos($this->longAddress, '0000:0000:0000:0000:0000:ffff:') === 0) { + $lastBytes = array_slice($this->getBytes(), -4); + $this->shortAddress = '::ffff:' . implode('.', $lastBytes); + } else { + $chunks = array_map( + function ($word) { + return dechex($word); + }, + $this->getWords() + ); + $shortAddress = implode(':', $chunks); + $matches = null; + for ($i = 8; $i > 1; $i--) { + $search = '(?:^|:)' . rtrim(str_repeat('0:', $i), ':') . '(?:$|:)'; + if (preg_match('/^(.*?)' . $search . '(.*)$/', $shortAddress, $matches)) { + $shortAddress = $matches[1] . '::' . $matches[2]; + break; + } + } + $this->shortAddress = $shortAddress; + } + } + $result = $this->shortAddress; + } + + return $result; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getBytes() + */ + public function getBytes() + { + if ($this->bytes === null) { + $bytes = array(); + foreach ($this->getWords() as $word) { + $bytes[] = $word >> 8; + $bytes[] = $word & 0xff; + } + $this->bytes = $bytes; + } + + return $this->bytes; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getBits() + */ + public function getBits() + { + $parts = array(); + foreach ($this->getBytes() as $byte) { + $parts[] = sprintf('%08b', $byte); + } + + return implode('', $parts); + } + + /** + * Get the word list of the IP address. + * + * @return int[] + */ + public function getWords() + { + if ($this->words === null) { + $this->words = array_map( + function ($chunk) { + return (int) hexdec($chunk); + }, + explode(':', $this->longAddress) + ); + } + + return $this->words; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getAddressType() + */ + public function getAddressType() + { + return Type::T_IPv6; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getDefaultReservedRangeType() + */ + public static function getDefaultReservedRangeType() + { + return RangeType::T_RESERVED; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getReservedRanges() + */ + public static function getReservedRanges() + { + if (self::$reservedRanges === null) { + $reservedRanges = array(); + foreach (array( + // RFC 4291 + '::/128' => array(RangeType::T_UNSPECIFIED), + // RFC 4291 + '::1/128' => array(RangeType::T_LOOPBACK), + // RFC 4291 + '100::/8' => array(RangeType::T_DISCARD, array('100::/64' => RangeType::T_DISCARDONLY)), + //'2002::/16' => array(RangeType::), + // RFC 4291 + '2000::/3' => array(RangeType::T_PUBLIC), + // RFC 4193 + 'fc00::/7' => array(RangeType::T_PRIVATENETWORK), + // RFC 4291 + 'fe80::/10' => array(RangeType::T_LINKLOCAL_UNICAST), + // RFC 4291 + 'ff00::/8' => array(RangeType::T_MULTICAST), + // RFC 4291 + //'::/8' => array(RangeType::T_RESERVED), + // RFC 4048 + //'200::/7' => array(RangeType::T_RESERVED), + // RFC 4291 + //'400::/6' => array(RangeType::T_RESERVED), + // RFC 4291 + //'800::/5' => array(RangeType::T_RESERVED), + // RFC 4291 + //'1000::/4' => array(RangeType::T_RESERVED), + // RFC 4291 + //'4000::/3' => array(RangeType::T_RESERVED), + // RFC 4291 + //'6000::/3' => array(RangeType::T_RESERVED), + // RFC 4291 + //'8000::/3' => array(RangeType::T_RESERVED), + // RFC 4291 + //'a000::/3' => array(RangeType::T_RESERVED), + // RFC 4291 + //'c000::/3' => array(RangeType::T_RESERVED), + // RFC 4291 + //'e000::/4' => array(RangeType::T_RESERVED), + // RFC 4291 + //'f000::/5' => array(RangeType::T_RESERVED), + // RFC 4291 + //'f800::/6' => array(RangeType::T_RESERVED), + // RFC 4291 + //'fe00::/9' => array(RangeType::T_RESERVED), + // RFC 3879 + //'fec0::/10' => array(RangeType::T_RESERVED), + ) as $range => $data) { + $exceptions = array(); + if (isset($data[1])) { + foreach ($data[1] as $exceptionRange => $exceptionType) { + $subnet = Subnet::parseString($exceptionRange); + /** @var Subnet $subnet */ + $exceptions[] = new AssignedRange($subnet, $exceptionType); + } + } + $subnet = Subnet::parseString($range); + /** @var Subnet $subnet */ + $reservedRanges[] = new AssignedRange($subnet, $data[0], $exceptions); + } + self::$reservedRanges = $reservedRanges; + } + + return self::$reservedRanges; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getRangeType() + */ + public function getRangeType() + { + if ($this->rangeType === null) { + $ipv4 = $this->toIPv4(); + if ($ipv4 !== null) { + $this->rangeType = $ipv4->getRangeType(); + } else { + $rangeType = null; + foreach (static::getReservedRanges() as $reservedRange) { + $rangeType = $reservedRange->getAddressType($this); + if ($rangeType !== null) { + break; + } + } + $this->rangeType = $rangeType === null ? static::getDefaultReservedRangeType() : $rangeType; + } + } + + return $this->rangeType; + } + + /** + * Create an IPv4 representation of this address (if possible, otherwise returns null). + * + * @return \IPLib\Address\IPv4|null + */ + public function toIPv4() + { + if (strpos($this->longAddress, '2002:') === 0) { + // 6to4 + return IPv4::fromBytes(array_slice($this->getBytes(), 2, 4)); + } + if (strpos($this->longAddress, '0000:0000:0000:0000:0000:ffff:') === 0) { + // IPv4-mapped IPv6 addresses + return IPv4::fromBytes(array_slice($this->getBytes(), -4)); + } + + return null; + } + + /** + * Render this IPv6 address in the "mixed" IPv6 (first 12 bytes) + IPv4 (last 4 bytes) mixed syntax. + * + * @param bool $ipV6Long render the IPv6 part in "long" format? + * @param bool $ipV4Long render the IPv4 part in "long" format? + * + * @return string + * + * @example '::13.1.68.3' + * @example '0000:0000:0000:0000:0000:0000:13.1.68.3' when $ipV6Long is true + * @example '::013.001.068.003' when $ipV4Long is true + * @example '0000:0000:0000:0000:0000:0000:013.001.068.003' when $ipV6Long and $ipV4Long are true + * + * @see https://tools.ietf.org/html/rfc4291#section-2.2 point 3. + * @since 1.9.0 + */ + public function toMixedIPv6IPv4String($ipV6Long = false, $ipV4Long = false) + { + $myBytes = $this->getBytes(); + $ipv6Bytes = array_merge(array_slice($myBytes, 0, 12), array(0xff, 0xff, 0xff, 0xff)); + $ipv6 = static::fromBytes($ipv6Bytes); + /** @var IPv6 $ipv6 */ + $ipv6String = $ipv6->toString($ipV6Long); + $ipv4Bytes = array_slice($myBytes, 12, 4); + $ipv4 = IPv4::fromBytes($ipv4Bytes); + /** @var IPv4 $ipv4 */ + $ipv4String = $ipv4->toString($ipV4Long); + $result = preg_replace('/((ffff:ffff)|(\d+(\.\d+){3}))$/i', $ipv4String, $ipv6String); + /** @var string $result */ + + return $result; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getComparableString() + */ + public function getComparableString() + { + return $this->longAddress; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::matches() + */ + public function matches(RangeInterface $range) + { + return $range->contains($this); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getAddressAtOffset() + */ + public function getAddressAtOffset($n) + { + if (is_int($n)) { + $thatChunks = NumberInChunks::fromInteger($n, NumberInChunks::CHUNKSIZE_WORDS); + } elseif (($s = BinaryMath::getInstance()->normalizeIntegerString($n)) !== '') { + $thatChunks = NumberInChunks::fromNumericString($s, NumberInChunks::CHUNKSIZE_WORDS); + } else { + return null; + } + $myWords = $this->getWords(); + while (isset($myWords[1]) && $myWords[0] === 0) { + array_shift($myWords); + } + $myChunks = new NumberInChunks(false, $myWords, NumberInChunks::CHUNKSIZE_WORDS); + $result = $myChunks->add($thatChunks); + if ($result->negative || count($result->chunks) > 8) { + return null; + } + + return static::fromWords(array_pad($result->chunks, -8, 0)); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getNextAddress() + */ + public function getNextAddress() + { + return $this->getAddressAtOffset(1); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getPreviousAddress() + */ + public function getPreviousAddress() + { + return $this->getAddressAtOffset(-1); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::getReverseDNSLookupName() + */ + public function getReverseDNSLookupName() + { + return implode( + '.', + array_reverse(str_split(str_replace(':', '', $this->toString(true)), 1)) + ) . '.ip6.arpa'; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::shift() + */ + public function shift($bits) + { + $bits = (int) $bits; + if ($bits === 0) { + return $this; + } + $absBits = abs($bits); + if ($absBits >= 128) { + return new self('0000:0000:0000:0000:0000:0000:0000:0000'); + } + $pad = str_repeat('0', $absBits); + $paddedBits = $this->getBits(); + if ($bits > 0) { + $paddedBits = $pad . substr($paddedBits, 0, -$bits); + } else { + $paddedBits = substr($paddedBits, $absBits) . $pad; + } + $bytes = array_map('bindec', str_split($paddedBits, 16)); + /** @var int[] $bytes */ + $result = static::fromWords($bytes); + /** @var IPv6 $result */ + + return $result; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Address\AddressInterface::add() + */ + public function add(AddressInterface $other) + { + if (!$other instanceof self) { + return null; + } + $myWords = $this->getWords(); + $otherWords = $other->getWords(); + $sum = array_fill(0, 8, 0); + $carry = 0; + for ($index = 7; $index >= 0; $index--) { + $word = $myWords[$index] + $otherWords[$index] + $carry; + if ($word > 0xFFFF) { + $carry = $word >> 16; + $word &= 0xFFFF; + } else { + $carry = 0; + } + $sum[$index] = $word; + } + if ($carry !== 0) { + return null; + } + + return static::fromWords($sum); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Address/Type.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Address/Type.php new file mode 100755 index 00000000..da5d2b3a --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Address/Type.php @@ -0,0 +1,44 @@ + $bytes + * + * @return \IPLib\Address\AddressInterface|null + */ + public static function addressFromBytes(array $bytes) + { + if (($result = Address\IPv4::fromBytes($bytes)) !== null) { + return $result; + } + if (($result = Address\IPv6::fromBytes($bytes)) !== null) { + return $result; + } + + return null; + } + + /** + * @deprecated since 1.17.0: use the parseRangeString() method instead. + * For upgrading: + * - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag + * + * @param string|mixed $range + * @param bool $supportNonDecimalIPv4 + * + * @return \IPLib\Range\RangeInterface|null + * + * @see \IPLib\Factory::parseRangeString() + * @since 1.10.0 added the $supportNonDecimalIPv4 argument + */ + public static function rangeFromString($range, $supportNonDecimalIPv4 = false) + { + return static::parseRangeString($range, $supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0); + } + + /** + * Parse an IP range string. + * + * @param string|mixed $range + * @param int $flags A combination or zero or more flags + * + * @return \IPLib\Range\RangeInterface|null + * + * @see \IPLib\ParseStringFlag + * @since 1.17.0 + */ + public static function parseRangeString($range, $flags = 0) + { + $result = Range\Subnet::parseString($range, $flags); + if ($result === null) { + $result = Range\Pattern::parseString($range, $flags); + } + if ($result === null) { + $result = Range\Single::parseString($range, $flags); + } + + return $result; + } + + /** + * @deprecated since 1.17.0: use the getRangeFromBoundaries() method instead. + * For upgrading: + * - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag + * + * @param string|\IPLib\Address\AddressInterface|mixed $from + * @param string|\IPLib\Address\AddressInterface|mixed $to + * @param bool $supportNonDecimalIPv4 + * + * @return \IPLib\Range\RangeInterface|null + * + * @see \IPLib\Factory::getRangeFromBoundaries() + * @since 1.2.0 + * @since 1.10.0 added the $supportNonDecimalIPv4 argument + */ + public static function rangeFromBoundaries($from, $to, $supportNonDecimalIPv4 = false) + { + return static::getRangeFromBoundaries($from, $to, ParseStringFlag::MAY_INCLUDE_PORT | ParseStringFlag::MAY_INCLUDE_ZONEID | ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0)); + } + + /** + * Create the smallest address range that comprises two addresses. + * + * @param string|\IPLib\Address\AddressInterface|mixed $from + * @param string|\IPLib\Address\AddressInterface|mixed $to + * @param int $flags A combination or zero or more flags + * + * @return \IPLib\Range\RangeInterface|null return NULL if $from and/or $to are invalid addresses, or if both are NULL or empty strings, or if they are addresses of different types + * + * @see \IPLib\ParseStringFlag + * @since 1.17.0 + */ + public static function getRangeFromBoundaries($from, $to, $flags = 0) + { + list($from, $to) = self::parseBoundaries($from, $to, $flags); + + return $from === false || $to === false ? null : static::rangeFromBoundaryAddresses($from, $to); + } + + /** + * Calculate the minimal range that contains all the specified addresses. + * + * @param array $addresses + * @param int $flags + * + * @return \IPLib\Range\RangeInterface|null Returns NULL if $addresses is empty, if it contains invalid addresses, or if the addresses aren't compatible (for example, both IPv4 and IPv6 addresses) + * + * @since 1.22.0 + */ + public static function getRangeFromAddresses(array $addresses, $flags = 0) + { + $min = null; + $max = null; + $numberOfBits = null; + foreach ($addresses as $address) { + if (!$address instanceof AddressInterface) { + $address = Factory::parseAddressString($address, $flags); + if ($address === null) { + return null; + } + } + if ($numberOfBits === null) { + $min = $address; + $max = $address; + $numberOfBits = $address->getNumberOfBits(); + } elseif ($numberOfBits !== $address->getNumberOfBits()) { + return null; + } else { + /** @var AddressInterface $min */ + /** @var AddressInterface $max */ + $comparable = $address->getComparableString(); + if ($min->getComparableString() > $comparable) { + $min = $address; + } + if ($max->getComparableString() < $comparable) { + $max = $address; + } + } + } + if ($numberOfBits === null) { + return null; + } + + return static::rangeFromBoundaryAddresses($min, $max); + } + + /** + * @deprecated since 1.17.0: use the getRangesFromBoundaries() method instead. + * For upgrading: + * - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag + * + * @param string|\IPLib\Address\AddressInterface|mixed $from + * @param string|\IPLib\Address\AddressInterface|mixed $to + * @param bool $supportNonDecimalIPv4 + * + * @return \IPLib\Range\Subnet[]|null + * + * @see \IPLib\Factory::getRangesFromBoundaries() + * @since 1.14.0 + */ + public static function rangesFromBoundaries($from, $to, $supportNonDecimalIPv4 = false) + { + return static::getRangesFromBoundaries($from, $to, ParseStringFlag::MAY_INCLUDE_PORT | ParseStringFlag::MAY_INCLUDE_ZONEID | ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0)); + } + + /** + * Create a list of Range instances that exactly describes all the addresses between the two provided addresses. + * + * @param string|\IPLib\Address\AddressInterface|mixed $from + * @param string|\IPLib\Address\AddressInterface|mixed $to + * @param int $flags A combination or zero or more flags + * + * @return \IPLib\Range\Subnet[]|null return NULL if $from and/or $to are invalid addresses, or if both are NULL or empty strings, or if they are addresses of different types + * + * @see \IPLib\ParseStringFlag + * @since 1.17.0 + */ + public static function getRangesFromBoundaries($from, $to, $flags = 0) + { + list($from, $to) = self::parseBoundaries($from, $to, $flags); + if ($from === false || $to === false || ($from === null && $to === null)) { + return null; + } + if ($from === null || $to === null) { + $address = $from ? $from : $to; + /** @var AddressInterface $address */ + + return array(new Subnet($address, $address, $address->getNumberOfBits())); + } + $numberOfBits = $from->getNumberOfBits(); + if ($to->getNumberOfBits() !== $numberOfBits) { + return null; + } + $calculator = new RangesFromBoundaryCalculator($numberOfBits); + + return $calculator->getRanges($from, $to); + } + + /** + * @param \IPLib\Address\AddressInterface|null $from + * @param \IPLib\Address\AddressInterface|null $to + * + * @return \IPLib\Range\RangeInterface|null + * + * @since 1.2.0 + */ + protected static function rangeFromBoundaryAddresses($from = null, $to = null) + { + if (!$from instanceof AddressInterface && !$to instanceof AddressInterface) { + $result = null; + } elseif (!$to instanceof AddressInterface) { + $result = Range\Single::fromAddress($from); + } elseif (!$from instanceof AddressInterface) { + $result = Range\Single::fromAddress($to); + } else { + $result = null; + $addressType = $from->getAddressType(); + if ($addressType === $to->getAddressType()) { + $cmp = strcmp($from->getComparableString(), $to->getComparableString()); + if ($cmp === 0) { + $result = Range\Single::fromAddress($from); + } else { + if ($cmp > 0) { + list($from, $to) = array($to, $from); + } + $fromBytes = $from->getBytes(); + $toBytes = $to->getBytes(); + $numBytes = count($fromBytes); + $sameBits = 0; + for ($byteIndex = 0; $byteIndex < $numBytes; $byteIndex++) { + $fromByte = $fromBytes[$byteIndex]; + $toByte = $toBytes[$byteIndex]; + if ($fromByte === $toByte) { + $sameBits += 8; + } else { + $differentBitsInByte = decbin($fromByte ^ $toByte); + $sameBits += 8 - strlen($differentBitsInByte); + break; + } + } + $result = static::parseRangeString($from->toString() . '/' . (string) $sameBits); + } + } + } + + return $result; + } + + /** + * @param string|\IPLib\Address\AddressInterface|mixed $from + * @param string|\IPLib\Address\AddressInterface|mixed $to + * @param int $flags + * + * @return array{\IPLib\Address\AddressInterface|false|null, \IPLib\Address\AddressInterface|false|null} + */ + private static function parseBoundaries($from, $to, $flags = 0) + { + $result = array(); + foreach (array('from', 'to') as $param) { + $value = $$param; + if (!($value instanceof AddressInterface)) { + $value = is_object($value) && method_exists($value, '__toString') || is_scalar($value) ? (string) $value : ''; + if ($value === '') { + $value = null; + } else { + $value = static::parseAddressString($value, $flags); + if ($value === null) { + $value = false; + } + } + } + $result[] = $value; + } + /** @var array{\IPLib\Address\AddressInterface|false|null, \IPLib\Address\AddressInterface|false|null} $result */ + if ($result[0] && $result[1] && strcmp($result[0]->getComparableString(), $result[1]->getComparableString()) > 0) { + $result = array($result[1], $result[0]); + } + + return $result; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/ParseStringFlag.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/ParseStringFlag.php new file mode 100755 index 00000000..860256e7 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/ParseStringFlag.php @@ -0,0 +1,79 @@ + 5.0.0.1 + * @example 5.256 => 5.0.1.0 + * @example 5.0.256 => 5.0.1.0 + * @example 123456789 => 7.91.205.21 + */ + const IPV4_MAYBE_NON_DECIMAL = 4; + + /** + * Use this flag if IPv4 subnet ranges may be in compact form. + * + * @example 127/24 => 127.0.0.0/24 + * @example 10/8 => 10.0.0.0/8 + * @example 10/24 => 10.0.0.0/24 + * @example 10.10.10/24 => 10.10.10.0/24 + * + * @var int + */ + const IPV4SUBNET_MAYBE_COMPACT = 8; + + /** + * Use this flag if IPv4 addresses may be in non quad-dotted notation. + * This notation is accepted by the implementation of inet_aton and inet_addr of the libc implementation of GNU, Windows and Mac (but not Musl), but not by inet_pton and ip2long. + * + * @var int + * + * @example 5.1 => 5.0.0.1 + * @example 5.256 => 5.0.1.0 + * @example 5.0.256 => 5.0.1.0 + * @example 123456789 => 7.91.205.21 + * + * @see https://man7.org/linux/man-pages/man3/inet_addr.3.html#DESCRIPTION + * @see https://www.freebsd.org/cgi/man.cgi?query=inet_net&sektion=3&apropos=0&manpath=FreeBSD+12.2-RELEASE+and+Ports#end + * @see http://git.musl-libc.org/cgit/musl/tree/src/network/inet_aton.c?h=v1.2.2 + */ + const IPV4ADDRESS_MAYBE_NON_QUAD_DOTTED = 16; + + /** + * Use this flag if you want to accept parsing IPv4/IPv6 addresses in Reverse DNS Lookup Address format. + * + * @var int + * + * @since 1.18.0 + * + * @example 140.13.12.10.in-addr.arpa => 10.12.13.140 + * @example b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.0.0.0.1.2.3.4.ip6.arpa => 4321:0:1:2:3:4:567:89ab + */ + const ADDRESS_MAYBE_RDNS = 32; +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/AbstractRange.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/AbstractRange.php new file mode 100755 index 00000000..019349cf --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/AbstractRange.php @@ -0,0 +1,188 @@ +rangeType === null) { + $addressType = $this->getAddressType(); + if ($addressType === AddressType::T_IPv6 && Subnet::get6to4()->containsRange($this)) { + $fromAddress = $this->fromAddress; + /** @var IPv6 $fromAddress */ + $toAddress = $this->toAddress; + /** @var IPv6 $toAddress */ + $range = Factory::getRangeFromBoundaries($fromAddress->toIPv4(), $toAddress->toIPv4()); + /** @var RangeInterface $range */ + $this->rangeType = $range->getRangeType(); + } else { + switch ($addressType) { + case AddressType::T_IPv4: + $defaultType = IPv4::getDefaultReservedRangeType(); + $reservedRanges = IPv4::getReservedRanges(); + break; + case AddressType::T_IPv6: + $defaultType = IPv6::getDefaultReservedRangeType(); + $reservedRanges = IPv6::getReservedRanges(); + break; + } + $rangeType = null; + foreach ($reservedRanges as $reservedRange) { + $rangeType = $reservedRange->getRangeType($this); + if ($rangeType !== null) { + break; + } + } + $this->rangeType = $rangeType === null ? $defaultType : $rangeType; + } + } + + return $this->rangeType === false ? null : $this->rangeType; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getAddressAtOffset() + */ + public function getAddressAtOffset($n) + { + if (is_int($n)) { + $positive = $n >= 0; + } elseif (($s = BinaryMath::getInstance()->normalizeIntegerString($n)) !== '') { + $n = $s; + $positive = $n[0] !== '-'; + } else { + return null; + } + if ($positive) { + $start = Factory::parseAddressString($this->getComparableStartString()); + /** @var \IPLib\Address\AddressInterface $start */ + $address = $start->getAddressAtOffset($n); + } else { + $end = Factory::parseAddressString($this->getComparableEndString()); + /** @var \IPLib\Address\AddressInterface $end */ + $nPlus1 = is_int($n) ? $n + 1 : BinaryMath::getInstance()->add1ToIntegerString($n); + $address = $end->getAddressAtOffset($nPlus1); + } + + if ($address === null) { + return null; + } + + return $this->contains($address) ? $address : null; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::contains() + */ + public function contains(AddressInterface $address) + { + $result = false; + if ($address->getAddressType() === $this->getAddressType()) { + $cmp = $address->getComparableString(); + $from = $this->getComparableStartString(); + if ($cmp >= $from) { + $to = $this->getComparableEndString(); + if ($cmp <= $to) { + $result = true; + } + } + } + + return $result; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::containsRange() + */ + public function containsRange(RangeInterface $range) + { + $result = false; + if ($range->getAddressType() === $this->getAddressType()) { + $myStart = $this->getComparableStartString(); + $itsStart = $range->getComparableStartString(); + if ($itsStart >= $myStart) { + $myEnd = $this->getComparableEndString(); + $itsEnd = $range->getComparableEndString(); + if ($itsEnd <= $myEnd) { + $result = true; + } + } + } + + return $result; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::split() + */ + public function split($networkPrefix, $forceSubnet = false) + { + $networkPrefix = (int) $networkPrefix; + $myNetworkPrefix = $this->getNetworkPrefix(); + if ($networkPrefix === $myNetworkPrefix) { + return array( + $forceSubnet ? $this->asSubnet() : $this, + ); + } + if ($networkPrefix < $myNetworkPrefix) { + throw new OutOfBoundsException("The value of the \$networkPrefix parameter can't be smaller than the network prefix of the range ({$myNetworkPrefix})"); + } + $startIp = $this->getStartAddress(); + $maxPrefix = $startIp::getNumberOfBits(); + if ($networkPrefix > $maxPrefix) { + throw new OutOfBoundsException("The value of the \$networkPrefix parameter can't be larger than the maximum network prefix of the range ({$maxPrefix})"); + } + switch ($startIp->getAddressType()) { + case AddressType::T_IPv4: + $one = IPv4::fromBytes(array(0, 0, 0, 1)); + break; + case AddressType::T_IPv6: + $one = IPv6::fromBytes(array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)); + break; + } + /** @var \IPLib\Address\AddressInterface $one */ + $delta = $one->shift($networkPrefix - $maxPrefix); + $result = array(); + while (true) { + $range = Subnet::parseString("{$startIp}/{$networkPrefix}"); + /** @var Subnet $range */ + if (!$forceSubnet && $this instanceof Pattern) { + $range = $range->asPattern() ?: $range; + } + $result[] = $range; + $startIp = $startIp->add($delta); + if ($startIp === null || !$this->contains($startIp)) { + break; + } + } + + return $result; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/Pattern.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/Pattern.php new file mode 100755 index 00000000..9b6b2eee --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/Pattern.php @@ -0,0 +1,354 @@ +fromAddress = $fromAddress; + $this->toAddress = $toAddress; + $this->asterisksCount = $asterisksCount; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::__toString() + */ + public function __toString() + { + return $this->toString(); + } + + /** + * @deprecated since 1.17.0: use the parseString() method instead. + * For upgrading: + * - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag + * + * @param string|mixed $range + * @param bool $supportNonDecimalIPv4 + * + * @return static|null + * + * @see \IPLib\Range\Pattern::parseString() + * @since 1.10.0 added the $supportNonDecimalIPv4 argument + */ + public static function fromString($range, $supportNonDecimalIPv4 = false) + { + return static::parseString($range, ParseStringFlag::MAY_INCLUDE_PORT | ParseStringFlag::MAY_INCLUDE_ZONEID | ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0)); + } + + /** + * Try get the range instance starting from its string representation. + * + * @param string|mixed $range + * @param int $flags A combination or zero or more flags + * + * @return static|null + * + * @since 1.17.0 + * @see \IPLib\ParseStringFlag + */ + public static function parseString($range, $flags = 0) + { + if (!is_string($range) || strpos($range, '*') === false) { + return null; + } + if ($range === '*.*.*.*') { + $fromAddress = IPv4::parseString('0.0.0.0'); + /** @var \IPLib\Address\IPv4 $fromAddress */ + $toAddress = IPv4::parseString('255.255.255.255'); + /** @var \IPLib\Address\IPv4 $toAddress */ + + return new static($fromAddress, $toAddress, 4); + } + if ($range === '*:*:*:*:*:*:*:*') { + $fromAddress = IPv6::parseString('::'); + /** @var \IPLib\Address\IPv6 $fromAddress */ + $toAddress = IPv6::parseString('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'); + /** @var \IPLib\Address\IPv6 $toAddress */ + + return new static($fromAddress, $toAddress, 8); + } + $matches = null; + if (strpos($range, '.') !== false && preg_match('/^[^*]+((?:\.\*)+)$/', $range, $matches)) { + $asterisksCount = strlen($matches[1]) >> 1; + if ($asterisksCount > 0) { + $missingDots = 3 - substr_count($range, '.'); + if ($missingDots > 0) { + $range .= str_repeat('.*', $missingDots); + $asterisksCount += $missingDots; + } + } + $fromAddress = IPv4::parseString(str_replace('*', '0', $range), $flags); + if ($fromAddress === null) { + return null; + } + $fixedBytes = array_slice($fromAddress->getBytes(), 0, -$asterisksCount); + $otherBytes = array_fill(0, $asterisksCount, 255); + $toAddress = IPv4::fromBytes(array_merge($fixedBytes, $otherBytes)); + /** @var \IPLib\Address\IPv4 $toAddress */ + + return new static($fromAddress, $toAddress, $asterisksCount); + } + if (strpos($range, ':') !== false && preg_match('/^[^*]+((?::\*)+)$/', $range, $matches)) { + $asterisksCount = strlen($matches[1]) >> 1; + $fromAddress = IPv6::parseString(str_replace('*', '0', $range)); + if ($fromAddress === null) { + return null; + } + $fixedWords = array_slice($fromAddress->getWords(), 0, -$asterisksCount); + $otherWords = array_fill(0, $asterisksCount, 0xffff); + $toAddress = IPv6::fromWords(array_merge($fixedWords, $otherWords)); + /** @var \IPLib\Address\IPv6 $toAddress */ + + return new static($fromAddress, $toAddress, $asterisksCount); + } + + return null; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::toString() + */ + public function toString($long = false) + { + if ($this->asterisksCount === 0) { + return $this->fromAddress->toString($long); + } + switch (true) { + case $this->fromAddress instanceof \IPLib\Address\IPv4: + $chunks = explode('.', $this->fromAddress->toString()); + $chunks = array_slice($chunks, 0, -$this->asterisksCount); + $chunks = array_pad($chunks, 4, '*'); + $result = implode('.', $chunks); + break; + case $this->fromAddress instanceof \IPLib\Address\IPv6: + if ($long) { + $chunks = explode(':', $this->fromAddress->toString(true)); + $chunks = array_slice($chunks, 0, -$this->asterisksCount); + $chunks = array_pad($chunks, 8, '*'); + $result = implode(':', $chunks); + } elseif ($this->asterisksCount === 8) { + $result = '*:*:*:*:*:*:*:*'; + } else { + $bytes = $this->toAddress->getBytes(); + $bytes = array_slice($bytes, 0, -$this->asterisksCount * 2); + $bytes = array_pad($bytes, 16, 1); + $address = IPv6::fromBytes($bytes); + /** @var IPv6 $address */ + $before = substr($address->toString(false), 0, -strlen(':101') * $this->asterisksCount); + $result = $before . str_repeat(':*', $this->asterisksCount); + } + break; + default: + throw new \Exception('@todo'); // @codeCoverageIgnore + } + + return $result; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getAddressType() + */ + public function getAddressType() + { + return $this->fromAddress->getAddressType(); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getStartAddress() + */ + public function getStartAddress() + { + return $this->fromAddress; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getEndAddress() + */ + public function getEndAddress() + { + return $this->toAddress; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getComparableStartString() + */ + public function getComparableStartString() + { + return $this->fromAddress->getComparableString(); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getComparableEndString() + */ + public function getComparableEndString() + { + return $this->toAddress->getComparableString(); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::asSubnet() + * @since 1.8.0 + */ + public function asSubnet() + { + return new Subnet($this->getStartAddress(), $this->getEndAddress(), $this->getNetworkPrefix()); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::asPattern() + */ + public function asPattern() + { + return $this; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getSubnetMask() + */ + public function getSubnetMask() + { + if ($this->getAddressType() !== AddressType::T_IPv4) { + return null; + } + switch ($this->asterisksCount) { + case 0: + $bytes = array(255, 255, 255, 255); + break; + case 4: + $bytes = array(0, 0, 0, 0); + break; + default: + $bytes = array_pad(array_fill(0, 4 - $this->asterisksCount, 255), 4, 0); + break; + } + + return IPv4::fromBytes($bytes); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getReverseDNSLookupName() + */ + public function getReverseDNSLookupName() + { + return $this->asterisksCount === 0 ? array($this->getStartAddress()->getReverseDNSLookupName()) : $this->asSubnet()->getReverseDNSLookupName(); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getSize() + */ + public function getSize() + { + $fromAddress = $this->fromAddress; + $maxPrefix = $fromAddress::getNumberOfBits(); + $prefix = $this->getNetworkPrefix(); + + return pow(2, $maxPrefix - $prefix); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getExactSize() + */ + public function getExactSize() + { + $fromAddress = $this->fromAddress; + $maxPrefix = $fromAddress::getNumberOfBits(); + $prefix = $this->getNetworkPrefix(); + + return BinaryMath::getInstance()->pow2string($maxPrefix - $prefix); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getNetworkPrefix() + */ + public function getNetworkPrefix() + { + switch ($this->getAddressType()) { + case AddressType::T_IPv4: + return 8 * (4 - $this->asterisksCount); + case AddressType::T_IPv6: + return 16 * (8 - $this->asterisksCount); + } + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/RangeInterface.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/RangeInterface.php new file mode 100755 index 00000000..78468218 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/RangeInterface.php @@ -0,0 +1,198 @@ +address = $address; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::__toString() + */ + public function __toString() + { + return $this->address->__toString(); + } + + /** + * @deprecated since 1.17.0: use the parseString() method instead. + * For upgrading: + * - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag + * + * @param string|mixed $range + * @param bool $supportNonDecimalIPv4 + * + * @return static|null + * + * @see \IPLib\Range\Single::parseString() + * @since 1.10.0 added the $supportNonDecimalIPv4 argument + */ + public static function fromString($range, $supportNonDecimalIPv4 = false) + { + return static::parseString($range, ParseStringFlag::MAY_INCLUDE_PORT | ParseStringFlag::MAY_INCLUDE_ZONEID | ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0)); + } + + /** + * Try get the range instance starting from its string representation. + * + * @param string|mixed $range + * @param int $flags A combination or zero or more flags + * + * @return static|null + * + * @see \IPLib\ParseStringFlag + * @since 1.17.0 + */ + public static function parseString($range, $flags = 0) + { + $result = null; + $flags = (int) $flags; + $address = Factory::parseAddressString($range, $flags); + if ($address !== null) { + $result = new static($address); + } + + return $result; + } + + /** + * Create the range instance starting from an address instance. + * + * @param \IPLib\Address\AddressInterface $address + * + * @return static + * + * @since 1.2.0 + */ + public static function fromAddress(AddressInterface $address) + { + return new static($address); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::toString() + */ + public function toString($long = false) + { + return $this->address->toString($long); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getAddressType() + */ + public function getAddressType() + { + return $this->address->getAddressType(); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getRangeType() + */ + public function getRangeType() + { + return $this->address->getRangeType(); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::contains() + */ + public function contains(AddressInterface $address) + { + $result = false; + if ($address->getAddressType() === $this->getAddressType()) { + if ($address->toString(false) === $this->address->toString(false)) { + $result = true; + } + } + + return $result; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getStartAddress() + */ + public function getStartAddress() + { + return $this->address; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getEndAddress() + */ + public function getEndAddress() + { + return $this->address; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getComparableStartString() + */ + public function getComparableStartString() + { + return $this->address->getComparableString(); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getComparableEndString() + */ + public function getComparableEndString() + { + return $this->address->getComparableString(); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::asSubnet() + */ + public function asSubnet() + { + return new Subnet($this->address, $this->address, $this->getNetworkPrefix()); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::asPattern() + */ + public function asPattern() + { + return new Pattern($this->address, $this->address, 0); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getSubnetMask() + */ + public function getSubnetMask() + { + if ($this->getAddressType() !== AddressType::T_IPv4) { + return null; + } + + return IPv4::fromBytes(array(255, 255, 255, 255)); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getReverseDNSLookupName() + */ + public function getReverseDNSLookupName() + { + return array($this->getStartAddress()->getReverseDNSLookupName()); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getSize() + */ + public function getSize() + { + return 1; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getExactSize() + */ + public function getExactSize() + { + return 1; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getNetworkPrefix() + */ + public function getNetworkPrefix() + { + switch ($this->getAddressType()) { + case AddressType::T_IPv4: + return 32; + case AddressType::T_IPv6: + return 128; + } + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/Subnet.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/Subnet.php new file mode 100755 index 00000000..e6e7f3d7 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/Subnet.php @@ -0,0 +1,373 @@ +fromAddress = $fromAddress; + $this->toAddress = $toAddress; + $this->networkPrefix = $networkPrefix; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::__toString() + */ + public function __toString() + { + return $this->toString(); + } + + /** + * @deprecated since 1.17.0: use the parseString() method instead. + * For upgrading: + * - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag + * + * @param string|mixed $range + * @param bool $supportNonDecimalIPv4 + * + * @return static|null + * + * @see \IPLib\Range\Subnet::parseString() + * @since 1.10.0 added the $supportNonDecimalIPv4 argument + */ + public static function fromString($range, $supportNonDecimalIPv4 = false) + { + return static::parseString($range, ParseStringFlag::MAY_INCLUDE_PORT | ParseStringFlag::MAY_INCLUDE_ZONEID | ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0)); + } + + /** + * Try get the range instance starting from its string representation. + * + * @param string|mixed $range + * @param int $flags A combination or zero or more flags + * + * @return static|null + * + * @see \IPLib\ParseStringFlag + * @since 1.17.0 + */ + public static function parseString($range, $flags = 0) + { + if (!is_string($range)) { + return null; + } + $parts = explode('/', $range); + if (count($parts) !== 2) { + return null; + } + $flags = (int) $flags; + if (strpos($parts[0], ':') === false && $flags & ParseStringFlag::IPV4SUBNET_MAYBE_COMPACT) { + $missingDots = 3 - substr_count($parts[0], '.'); + if ($missingDots > 0) { + $parts[0] .= str_repeat('.0', $missingDots); + } + } + $address = Factory::parseAddressString($parts[0], $flags); + if ($address === null) { + return null; + } + if (!preg_match('/^[0-9]{1,9}$/', $parts[1])) { + return null; + } + $networkPrefix = (int) $parts[1]; + $addressBytes = $address->getBytes(); + $totalBytes = count($addressBytes); + $numDifferentBits = $totalBytes * 8 - $networkPrefix; + if ($numDifferentBits < 0) { + return null; + } + $numSameBytes = $networkPrefix >> 3; + $sameBytes = array_slice($addressBytes, 0, $numSameBytes); + $differentBytesStart = ($totalBytes === $numSameBytes) ? array() : array_fill(0, $totalBytes - $numSameBytes, 0); + $differentBytesEnd = ($totalBytes === $numSameBytes) ? array() : array_fill(0, $totalBytes - $numSameBytes, 255); + $startSameBits = $networkPrefix % 8; + if ($startSameBits !== 0) { + $varyingByte = $addressBytes[$numSameBytes]; + $differentBytesStart[0] = $varyingByte & (int) bindec(str_pad(str_repeat('1', $startSameBits), 8, '0', STR_PAD_RIGHT)); + $differentBytesEnd[0] = $differentBytesStart[0] + (int) bindec(str_repeat('1', 8 - $startSameBits)); + } + $fromAddress = Factory::addressFromBytes(array_merge($sameBytes, $differentBytesStart)); + /** @var \IPLib\Address\AddressInterface $fromAddress */ + $toAddress = Factory::addressFromBytes(array_merge($sameBytes, $differentBytesEnd)); + /** @var \IPLib\Address\AddressInterface $toAddress */ + + return new static($fromAddress, $toAddress, $networkPrefix); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::toString() + */ + public function toString($long = false) + { + return $this->fromAddress->toString($long) . '/' . $this->networkPrefix; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getAddressType() + */ + public function getAddressType() + { + return $this->fromAddress->getAddressType(); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getStartAddress() + */ + public function getStartAddress() + { + return $this->fromAddress; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getEndAddress() + */ + public function getEndAddress() + { + return $this->toAddress; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getComparableStartString() + */ + public function getComparableStartString() + { + return $this->fromAddress->getComparableString(); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getComparableEndString() + */ + public function getComparableEndString() + { + return $this->toAddress->getComparableString(); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::asSubnet() + */ + public function asSubnet() + { + return $this; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::asPattern() + * @since 1.8.0 + */ + public function asPattern() + { + $address = $this->getStartAddress(); + $networkPrefix = $this->getNetworkPrefix(); + switch ($address->getAddressType()) { + case AddressType::T_IPv4: + return $networkPrefix % 8 === 0 ? new Pattern($address, $address, 4 - $networkPrefix / 8) : null; + case AddressType::T_IPv6: + return $networkPrefix % 16 === 0 ? new Pattern($address, $address, 8 - $networkPrefix / 16) : null; + } + } + + /** + * Get the 6to4 address IPv6 address range. + * + * @return self + * + * @since 1.5.0 + */ + public static function get6to4() + { + if (self::$sixToFour === null) { + $subnet = self::parseString('2002::/16'); + /** @var Subnet $subnet */ + self::$sixToFour = $subnet; + } + + return self::$sixToFour; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getNetworkPrefix() + * @since 1.7.0 + */ + public function getNetworkPrefix() + { + return $this->networkPrefix; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getSubnetMask() + */ + public function getSubnetMask() + { + if ($this->getAddressType() !== AddressType::T_IPv4) { + return null; + } + $bytes = array(); + $prefix = $this->getNetworkPrefix(); + while ($prefix >= 8) { + $bytes[] = 255; + $prefix -= 8; + } + if ($prefix !== 0) { + $bytes[] = bindec(str_pad(str_repeat('1', $prefix), 8, '0')); + } + $bytes = array_pad($bytes, 4, 0); + + return IPv4::fromBytes($bytes); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getReverseDNSLookupName() + */ + public function getReverseDNSLookupName() + { + switch ($this->getAddressType()) { + case AddressType::T_IPv4: + $unitSize = 8; // bytes + $maxUnits = 4; + $isHex = false; + $rxUnit = '\d+'; + break; + case AddressType::T_IPv6: + $unitSize = 4; // nibbles + $maxUnits = 32; + $isHex = true; + $rxUnit = '[0-9A-Fa-f]'; + break; + } + $totBits = $unitSize * $maxUnits; + $prefixUnits = (int) ($this->networkPrefix / $unitSize); + $extraBits = ($totBits - $this->networkPrefix) % $unitSize; + if ($extraBits !== 0) { + $prefixUnits += 1; + } + $numVariants = 1 << $extraBits; + $result = array(); + $unitsToRemove = $maxUnits - $prefixUnits; + $initialPointer = preg_replace("/^(({$rxUnit})\.){{$unitsToRemove}}/", '', $this->getStartAddress()->getReverseDNSLookupName()); + /** @var string $initialPointer */ + $chunks = explode('.', $initialPointer, 2); + for ($index = 0; $index < $numVariants; $index++) { + if ($index !== 0) { + $chunks[0] = $isHex ? dechex(1 + (int) hexdec($chunks[0])) : (string) (1 + (int) $chunks[0]); + } + $result[] = implode('.', $chunks); + } + + return $result; + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getSize() + */ + public function getSize() + { + $fromAddress = $this->fromAddress; + $maxPrefix = $fromAddress::getNumberOfBits(); + $prefix = $this->getNetworkPrefix(); + + return pow(2, $maxPrefix - $prefix); + } + + /** + * {@inheritdoc} + * + * @see \IPLib\Range\RangeInterface::getExactSize() + */ + public function getExactSize() + { + $fromAddress = $this->fromAddress; + $maxPrefix = $fromAddress::getNumberOfBits(); + $prefix = $this->getNetworkPrefix(); + + return BinaryMath::getInstance()->pow2string($maxPrefix - $prefix); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/Type.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/Type.php new file mode 100755 index 00000000..20d96753 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Range/Type.php @@ -0,0 +1,152 @@ +toSameLength($a, $b); + + return $a < $b ? -1 : ($a > $b ? 1 : 0); + } + + /** + * Add 1 to a non-negative integer represented in binary form. + * + * @param string $value + * + * @return string + */ + public function increment($value) + { + $lastZeroIndex = strrpos($value, '0'); + if ($lastZeroIndex === false) { + return '1' . str_repeat('0', strlen($value)); + } + + return ltrim(substr($value, 0, $lastZeroIndex), '0') . '1' . str_repeat('0', strlen($value) - $lastZeroIndex - 1); + } + + /** + * Calculate the bitwise AND of two non-negative integers represented in binary form. + * + * @param string $operand1 + * @param string $operand2 + * + * @return string + */ + public function andX($operand1, $operand2) + { + $operand1 = $this->reduce($operand1); + $operand2 = $this->reduce($operand2); + $numBits = min(strlen($operand1), strlen($operand2)); + $operand1 = substr(str_pad($operand1, $numBits, '0', STR_PAD_LEFT), -$numBits); + $operand2 = substr(str_pad($operand2, $numBits, '0', STR_PAD_LEFT), -$numBits); + $result = ''; + for ($index = 0; $index < $numBits; $index++) { + $result .= $operand1[$index] === '1' && $operand2[$index] === '1' ? '1' : '0'; + } + + return $this->reduce($result); + } + + /** + * Calculate the bitwise OR of two non-negative integers represented in binary form. + * + * @param string $operand1 + * @param string $operand2 + * + * @return string + */ + public function orX($operand1, $operand2) + { + list($operand1, $operand2, $numBits) = $this->toSameLength($operand1, $operand2); + $result = ''; + for ($index = 0; $index < $numBits; $index++) { + $result .= $operand1[$index] === '1' || $operand2[$index] === '1' ? '1' : '0'; + } + + return $result; + } + + /** + * Compute 2 raised to the given exponent. + * + * If the result fits into a native PHP integer, an int is returned. + * If the result exceeds PHP_INT_MAX, a string containing the exact decimal representation is returned. + * + * @param int $exponent The non-negative exponent + * + * @return int|numeric-string + */ + public function pow2string($exponent) + { + if ($exponent < PHP_INT_SIZE * 8 - 1) { + return 1 << $exponent; + } + $digits = array(1); + for ($i = 0; $i < $exponent; $i++) { + $carry = 0; + foreach ($digits as $index => $digit) { + $product = $digit * 2 + $carry; + $digits[$index] = $product % 10; + $carry = (int) ($product / 10); + } + if ($carry !== 0) { + $digits[] = $carry; + } + } + $result = implode('', array_reverse($digits)); + /** @var numeric-string $result */ + + return $result; + } + + /** + * @param numeric-string|mixed $value + * + * @return numeric-string|'' empty string if $value is not a valid numeric string + */ + public function normalizeIntegerString($value) + { + if (!is_string($value) || $value === '') { + return ''; + } + $sign = $value[0]; + if ($sign === '-' || $sign === '+') { + $value = substr($value, 1); + } + $matches = null; + if (!preg_match('/^0*([0-9]+)$/', $value, $matches)) { + return ''; + } + $numericString = $matches[1]; + if ($sign === '-' && $numericString !== '0') { + $numericString = '-' . $numericString; + } + /** @var numeric-string $numericString */ + + return $numericString; + } + + /** + * @param numeric-string $value a string that has been normalized with normalizeIntegerString() + * + * @return numeric-string + */ + public function add1ToIntegerString($value) + { + if ($value[0] === '-') { + if ($value === '-1') { + return '0'; + } + $digits = str_split(substr($value, 1)); + $i = count($digits) - 1; + while ($i >= 0) { + if ($digits[$i] !== '0') { + $digits[$i] = (string) ((int) $digits[$i] - 1); + break; + } + $digits[$i] = '9'; + $i--; + } + $imploded = implode('', $digits); + if ($imploded[0] === '0') { + $imploded = substr($imploded, 1); + } + $result = '-' . $imploded; + /** @var numeric-string $result */ + + return $result; // @phpstan-ignore varTag.nativeType + } + $digits = str_split($value); + $carry = 1; + for ($i = count($digits) - 1; $i >= 0; $i--) { + $sum = (int) $digits[$i] + $carry; + $digits[$i] = (string) ($sum % 10); + $carry = (int) ($sum / 10); + if ($carry === 0) { + break; + } + if ($i === 0) { + array_unshift($digits, (string) $carry); + } + } + $result = implode('', $digits); + /** @var numeric-string $result */ + + return $result; + } + + /** + * Zero-padding of two non-negative integers represented in binary form, so that they have the same length. + * + * @param string $num1 + * @param string $num2 + * + * @return array{string, string, int} The first array element is $num1 (padded), the first array element is $num2 (padded), the third array element is the number of bits + */ + private function toSameLength($num1, $num2) + { + $num1 = $this->reduce($num1); + $num2 = $this->reduce($num2); + $numBits = max(strlen($num1), strlen($num2)); + + return array( + str_pad($num1, $numBits, '0', STR_PAD_LEFT), + str_pad($num2, $numBits, '0', STR_PAD_LEFT), + $numBits, + ); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Service/NumberInChunks.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Service/NumberInChunks.php new file mode 100755 index 00000000..21762086 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Service/NumberInChunks.php @@ -0,0 +1,254 @@ +negative = $negative; + $this->chunks = $chunks; + $this->chunkSize = $chunkSize; + } + + /** + * @throws \InvalidArgumentException if $other has a $chunkSize that's not the same as the $chunkSize of this + * + * @return \IPLib\Service\NumberInChunks + */ + public function negate() + { + return new self($this->chunks === array(0) ? false : !$this->negative, $this->chunks, $this->chunkSize); + } + + /** + * @throws \InvalidArgumentException if $other has a $chunkSize that's not the same as the $chunkSize of this + * + * @return \IPLib\Service\NumberInChunks + */ + public function add(NumberInChunks $that) + { + if ($this->chunkSize !== $that->chunkSize) { + throw new InvalidArgumentException('Incompatible chunk size'); + } + if ($this->negative === $that->negative) { + return new self($this->negative, self::addChunks($this->chunks, $that->chunks, $this->chunkSize), $this->chunkSize); + } + if ($that->negative) { + list($negative, $chunks) = self::substractChunks($this->chunks, $that->chunks, $this->chunkSize); + } else { + list($negative, $chunks) = self::substractChunks($that->chunks, $this->chunks, $this->chunkSize); + } + + return new self($negative, $chunks, $this->chunkSize); + } + + /** + * @param int $int + * @param int $chunkSize + * + * @return \IPLib\Service\NumberInChunks + */ + public static function fromInteger($int, $chunkSize) + { + if ($int === 0) { + return new self(false, array(0), $chunkSize); + } + $negative = $int < 0; + if ($negative) { + $positiveInt = -$int; + /** @var int|float $positiveInt may be float because -PHP_INT_MIN is bigger than PHP_INT_MAX */ + if (is_float($positiveInt)) { + return self::fromNumericString((string) $int, $chunkSize); + } + $int = $positiveInt; + } + $bitMask = (1 << $chunkSize) - 1; + $chunks = array(); + while ($int !== 0) { + $chunks[] = $int & $bitMask; + $int >>= $chunkSize; + } + + return new self($negative, array_reverse($chunks), $chunkSize); + } + + /** + * @param string $numericString a string normalized with BinaryMath::normalizeIntegerString() + * @param int $chunkSize + * + * @return \IPLib\Service\NumberInChunks + */ + public static function fromNumericString($numericString, $chunkSize) + { + if ($numericString === '0') { + return new self(false, array(0), $chunkSize); + } + $negative = $numericString[0] === '-'; + if ($negative) { + $numericString = substr($numericString, 1); + } + $chunks = array(); + while ($numericString !== '0') { + $chunks[] = self::modulo($numericString, $chunkSize); + $numericString = self::divide($numericString, $chunkSize); + } + + return new self($negative, array_reverse($chunks), $chunkSize); + } + + /** + * @param string $numericString + * @param int $chunkSize + * + * @return int + */ + private static function modulo($numericString, $chunkSize) + { + $divisor = 1 << $chunkSize; + $carry = 0; + $len = strlen($numericString); + for ($i = 0; $i < $len; $i++) { + $digit = (int) $numericString[$i]; + $carry = ($carry * 10 + $digit) % $divisor; + } + + return $carry; + } + + /** + * @param string $numericString + * @param int $chunkSize + * + * @return string + */ + private static function divide($numericString, $chunkSize) + { + $divisor = 1 << $chunkSize; + $quotient = ''; + $carry = 0; + $len = strlen($numericString); + for ($i = 0; $i < $len; $i++) { + $digit = (int) $numericString[$i]; + $value = $carry * 10 + $digit; + $quotient .= (string) ($value >> $chunkSize); + $carry = $value % $divisor; + } + + return ltrim($quotient, '0') ?: '0'; + } + + /** + * @param int[] $addend1 + * @param int[] $addend2 + * @param int $chunkSize + * + * @return int[] + */ + private static function addChunks(array $addend1, array $addend2, $chunkSize) + { + $divisor = 1 << $chunkSize; + $result = array(); + $carry = 0; + while ($addend1 !== array() || $addend2 !== array()) { + $sum = $carry + (array_pop($addend1) ?: 0) + (array_pop($addend2) ?: 0); + $result[] = $sum % $divisor; + $carry = $sum >> $chunkSize; + } + if ($carry !== 0) { + $result[] = $carry; + } + + return array_reverse($result); + } + + /** + * @param int[] $minuend + * @param int[] $subtrahend + * @param int $chunkSize + * + * @return array{bool, int[]} + */ + private static function substractChunks(array $minuend, array $subtrahend, $chunkSize) + { + $minuendCount = count($minuend); + $subtrahendCount = count($subtrahend); + if ($minuendCount > $subtrahendCount) { + $count = $minuendCount; + $negative = false; + } elseif ($minuendCount < $subtrahendCount) { + $count = $subtrahendCount; + $negative = true; + } else { + $count = $minuendCount; + $negative = false; + for ($i = 0; $i < $count; $i++) { + $delta = $minuend[$i] - $subtrahend[$i]; + if ($delta === 0) { + continue; + } + if ($delta < 0) { + $negative = true; + } + break; + } + } + if ($negative) { + list($minuend, $subtrahend) = array($subtrahend, $minuend); + } + $subtrahend = array_pad($subtrahend, -$count, 0); + $borrowValue = 1 << $chunkSize; + $result = array(); + $borrow = 0; + for ($i = $count - 1; $i >= 0; $i--) { + $value = $minuend[$i] - $subtrahend[$i] - $borrow; + if ($value < 0) { + $value += $borrowValue; + $borrow = 1; + } else { + $borrow = 0; + } + $result[] = $value; + } + while (isset($result[1])) { + $value = array_pop($result); + if ($value !== 0) { + $result[] = $value; + break; + } + } + + return array($negative, array_reverse($result)); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Service/RangesFromBoundaryCalculator.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Service/RangesFromBoundaryCalculator.php new file mode 100755 index 00000000..4eaeb4e4 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Service/RangesFromBoundaryCalculator.php @@ -0,0 +1,175 @@ +math = BinaryMath::getInstance(); + $this->setNumBits($numBits); + } + + /** + * Calculate the subnets describing all (and only all) the addresses between two boundaries. + * + * @param \IPLib\Address\AddressInterface $from + * @param \IPLib\Address\AddressInterface $to + * + * @return \IPLib\Range\Subnet[]|null return NULL if the two addresses have an invalid number of bits (that is, different from the one passed to the constructor of this class) + */ + public function getRanges(AddressInterface $from, AddressInterface $to) + { + if ($from->getNumberOfBits() !== $this->numBits || $to->getNumberOfBits() !== $this->numBits) { + return null; + } + if ($from->getComparableString() > $to->getComparableString()) { + list($from, $to) = array($to, $from); + } + $result = array(); + $this->calculate($this->math->reduce($from->getBits()), $this->math->reduce($to->getBits()), $this->numBits, $result); + + return $result; + } + + /** + * Set the number of bits used to represent addresses (32 for IPv4, 128 for IPv6). + * + * @param int $numBits + * + * @return void + */ + private function setNumBits($numBits) + { + $numBits = (int) $numBits; + $masks = array(); + $unmasks = array(); + for ($bit = 0; $bit < $numBits; $bit++) { + $masks[$bit] = str_repeat('1', $numBits - $bit) . str_repeat('0', $bit); + $unmasks[$bit] = $bit === 0 ? '0' : str_repeat('1', $bit); + } + $this->numBits = $numBits; + $this->masks = $masks; + $this->unmasks = $unmasks; + } + + /** + * Calculate the subnets. + * + * @param string $start the start address (represented in reduced bit form) + * @param string $end the end address (represented in reduced bit form) + * @param int $position the number of bits in the mask we are comparing at this cycle + * @param \IPLib\Range\Subnet[] $result found ranges will be added to this variable + * + * @return void + */ + private function calculate($start, $end, $position, array &$result) + { + if ($start === $end) { + $result[] = $this->subnetFromBits($start, $this->numBits); + + return; + } + $startMasked = ''; + for ($index = $position - 1; $index >= 0; $index--) { + $startMasked = $this->math->andX($start, $this->masks[$index]); + $endMasked = $this->math->andX($end, $this->masks[$index]); + if ($startMasked !== $endMasked) { + $position = $index; + break; + } + } + if ($startMasked === $start && $this->math->andX($this->math->increment($end), $this->unmasks[$position]) === '0') { + $result[] = $this->subnetFromBits($start, $this->numBits - 1 - $position); + + return; + } + $middleAddress = $this->math->orX($start, $this->unmasks[$position]); + $this->calculate($start, $middleAddress, $position, $result); + $this->calculate($this->math->increment($middleAddress), $end, $position, $result); + } + + /** + * Create an address instance starting from its bits. + * + * @param string $bits the bits of the address (represented in reduced bit form) + * + * @return \IPLib\Address\AddressInterface + */ + private function addressFromBits($bits) + { + $bits = str_pad($bits, $this->numBits, '0', STR_PAD_LEFT); + $bytes = array(); + foreach (explode("\n", trim(chunk_split($bits, 8, "\n"))) as $byteBits) { + $bytes[] = (int) bindec($byteBits); + } + $result = Factory::addressFromBytes($bytes); + /** @var AddressInterface $result */ + + return $result; + } + + /** + * Create an range instance starting from the bits if the address and the length of the network prefix. + * + * @param string $bits the bits of the address (represented in reduced bit form) + * @param int $networkPrefix the length of the network prefix + * + * @return \IPLib\Range\Subnet + */ + private function subnetFromBits($bits, $networkPrefix) + { + $startAddress = $this->addressFromBits($bits); + $numOnes = $this->numBits - $networkPrefix; + if ($numOnes === 0) { + return new Subnet($startAddress, $startAddress, $networkPrefix); + } + $endAddress = $this->addressFromBits(substr($bits, 0, -$numOnes) . str_repeat('1', $numOnes)); + + return new Subnet($startAddress, $endAddress, $networkPrefix); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Service/UnsignedIntegerMath.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Service/UnsignedIntegerMath.php new file mode 100755 index 00000000..03dd5ea2 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/mlocati/ip-lib/src/Service/UnsignedIntegerMath.php @@ -0,0 +1,173 @@ +getBytesFromDecimal($m[1], $numBytes); + } + } else { + if (preg_match('/^0[Xx]0*([0-9A-Fa-f]+)$/', $value, $m)) { + return $this->getBytesFromHexadecimal($m[1], $numBytes); + } + if (preg_match('/^0+([0-7]*)$/', $value, $m)) { + return $this->getBytesFromOctal($m[1], $numBytes); + } + if (preg_match('/^[1-9][0-9]*$/', $value)) { + return $this->getBytesFromDecimal($value, $numBytes); + } + } + + // Not a valid number + return null; + } + + /** + * @return int + */ + protected function getMaxSignedInt() + { + return PHP_INT_MAX; + } + + /** + * @param string $value never zero-length, never extra leading zeroes + * @param int $numBytes + * + * @return int[]|null + */ + private function getBytesFromBits($value, $numBytes) + { + $valueLength = strlen($value); + if ($valueLength > $numBytes << 3) { + // overflow + return null; + } + $remainderBits = $valueLength % 8; + if ($remainderBits !== 0) { + $value = str_pad($value, $valueLength + 8 - $remainderBits, '0', STR_PAD_LEFT); + } + $bytes = array_map('bindec', str_split($value, 8)); + /** @var int[] $bytes */ + + return array_pad($bytes, -$numBytes, 0); + } + + /** + * @param string $value may be zero-length, never extra leading zeroes + * @param int $numBytes + * + * @return int[]|null + */ + private function getBytesFromOctal($value, $numBytes) + { + if ($value === '') { + return array_fill(0, $numBytes, 0); + } + $bits = implode( + '', + array_map( + function ($octalDigit) { + return str_pad(decbin((int) octdec($octalDigit)), 3, '0', STR_PAD_LEFT); + }, + str_split($value, 1) + ) + ); + $bits = ltrim($bits, '0'); + + return $bits === '' ? array_fill(0, $numBytes, 0) : self::getBytesFromBits($bits, $numBytes); + } + + /** + * @param string $value never zero-length, never extra leading zeroes + * @param int $numBytes + * + * @return int[]|null + */ + private function getBytesFromDecimal($value, $numBytes) + { + $valueLength = strlen($value); + $maxSignedIntLength = strlen((string) $this->getMaxSignedInt()); + if ($valueLength < $maxSignedIntLength) { + return $this->getBytesFromBits(decbin((int) $value), $numBytes); + } + // Divide by two, so that we have 1 less bit + $carry = 0; + $halfValue = ltrim( + implode( + '', + array_map( + function ($digit) use (&$carry) { + $number = $carry + (int) $digit; + $carry = ($number % 2) * 10; + + return (string) $number >> 1; + }, + str_split($value, 1) + ) + ), + '0' + ); + $halfValueBytes = $this->getBytesFromDecimal($halfValue, $numBytes); + if ($halfValueBytes === null) { + return null; + } + $carry = $carry === 0 ? 0 : 1; + $result = array_fill(0, $numBytes, 0); + for ($index = $numBytes - 1; $index >= 0; $index--) { + $byte = $carry + ($halfValueBytes[$index] << 1); + if ($byte <= 0xFF) { + $carry = 0; + } else { + $carry = ($byte & ~0xFF) >> 8; + $byte -= 0x100; + } + $result[$index] = $byte; + } + if ($carry !== 0) { + // Overflow + return null; + } + + return $result; + } + + /** + * @param string $value never zero-length, never extra leading zeroes + * @param int $numBytes + * + * @return int[]|null + */ + private function getBytesFromHexadecimal($value, $numBytes) + { + $valueLength = strlen($value); + if ($valueLength > $numBytes << 1) { + // overflow + return null; + } + $value = str_pad($value, $valueLength + $valueLength % 2, '0', STR_PAD_LEFT); + $bytes = array_map('hexdec', str_split($value, 2)); + /** @var int[] $bytes */ + + return array_pad($bytes, -$numBytes, 0); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/CI/php-compatibility.xml b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/CI/php-compatibility.xml new file mode 100755 index 00000000..f9c32de9 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/CI/php-compatibility.xml @@ -0,0 +1,17 @@ + + + + UpdraftPlus PHP Compatibility Check + + + + + + + + + + + + + diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/CI/php-syntax-check.xml b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/CI/php-syntax-check.xml new file mode 100755 index 00000000..69457411 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/CI/php-syntax-check.xml @@ -0,0 +1,12 @@ + + + UpdraftPlus PHP Syntax Check + + + + + + + + + \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/README.md b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/README.md new file mode 100755 index 00000000..090ba127 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/README.md @@ -0,0 +1,10 @@ +# Common Libraries + +This project contains many useful libraries that are currently used and can be reused across our projects. They are kept here for easy maintenance and also so that consumers get a uniform interface and things dont break across versions or on updates. + +CHANGELOG +* TWEAK: Port from previous semaphore classes to Updraft_Semaphore_3_0 in updraft-tasks +* FIX: Wrong query value in `delete_task_meta` method +* TWEAK: Make the logging format uniform +* FIX: Wrong DB Schema reference +* TWEAK: Logging on the semaphore \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/composer.json b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/composer.json new file mode 100755 index 00000000..e00ff4f1 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/composer.json @@ -0,0 +1,21 @@ +{ + "name": "team-updraft/common-libs", + "description": "These are the common libs used across all of our projects", + "type": "library", + "license": "GPL-3.0-only", + "authors": [{ + "name": "Team Updraft", + "email": "team.updraft@gmail.com" + }], + "config": { + "platform-check": false + }, + "require-dev": { + "squizlabs/php_codesniffer": "3.6.*", + "phpcompatibility/php-compatibility": "9.3.*", + "wp-coding-standards/wpcs": "2.3.*", + "sirbrillig/phpcs-variable-analysis": "2.11.*", + "dealerdirect/phpcodesniffer-composer-installer": "0.7.*" + }, + "prefer-stable" : true +} \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-notices/updraft-notices.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-notices/updraft-notices.php new file mode 100755 index 00000000..00265a5a --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-notices/updraft-notices.php @@ -0,0 +1,220 @@ +' : ''; + } else { + return $html_allowed ? '' : ''; + } + } + + /** + * Generate the end of a HTML URL + * + * @param boolean $html_allowed - indicates if HTML is allowed or not + * @param string $url - the URL + * @param boolean $https - the protocol to use + * + * @return string returns a partial HTML URL + */ + protected function url_end($html_allowed, $url, $https = false) { + $proto = $https ? 'https' : 'http'; + return $html_allowed ? '' : ' ('.$proto.'://'.$url.')'; + } + + /** + * Renders notice + * + * @param mixed $notice - a specific notice to render or false + * @param string $position - position of the notice + * @param boolean $return_instead_of_echo - indicates if we should echo notice or return as string + * + * @return mixed Returns string or echos notice + */ + public function do_notice($notice = false, $position = 'top', $return_instead_of_echo = false) { + + $this->notices_init(); + + if (false === $notice) $notice = apply_filters('updraft_notices_force_id', false, $this); + + $notice_content = $this->get_notice_data($notice, $position); + + if (false != $notice_content) { + return $this->render_specified_notice($notice_content, $return_instead_of_echo, $position); + } + } + + /** + * This method will return a notice ready for display. + * + * @param boolean $notice - a specific notice to render or false + * @param string $position - position of the notice + * + * @return array returns notice data + */ + protected function get_notice_data($notice = false, $position = 'top') { + + // If a specific notice has been passed to this method then return that notice. + if ($notice) { + if (!isset($this->notices_content[$notice])) return false; + + // Does the notice support the position specified? + if (isset($this->notices_content[$notice]['supported_positions']) && !in_array($position, $this->notices_content[$notice]['supported_positions'])) return false; + + // First check if the advert passed can be displayed and hasn't been dismissed, we do this by checking what dismissed value we should be checking. + $dismiss_time = $this->notices_content[$notice]['dismiss_time']; + + $dismiss = $this->check_notice_dismissed($dismiss_time); + + if ($dismiss) return false; + + // If the advert has a validity function, then require the advert to be valid + if (!empty($this->notices_content[$notice]['validity_function']) && !call_user_func(array($this, $this->notices_content[$notice]['validity_function']))) return false; + + return $this->notices_content[$notice]; + } + + // Create an array to add non-seasonal adverts to so that if a seasonal advert can't be returned we can choose a random advert from this array. + $available_notices = array(); + + // If Advert wasn't passed then next we should check to see if a seasonal advert can be returned. + foreach ($this->notices_content as $notice_id => $notice_data) { + // Does the notice support the position specified? + if (isset($this->notices_content[$notice_id]['supported_positions']) && !in_array($position, $this->notices_content[$notice_id]['supported_positions'])) continue; + + // If the advert has a validity function, then require the advert to be valid. + if (!empty($notice_data['validity_function']) && !call_user_func(array($this, $notice_data['validity_function']))) continue; + + + if (isset($notice_data['valid_from']) && isset($notice_data['valid_to'])) { + if ($this->skip_seasonal_notices($notice_data)) return $notice_data; + } else { + $dismiss_time = $this->notices_content[$notice_id]['dismiss_time']; + $dismiss = $this->check_notice_dismissed($dismiss_time); + + if (!$dismiss) $available_notices[$notice_id] = $notice_data; + } + } + + if (empty($available_notices)) return false; + + // If a seasonal advert can't be returned then we will return a random advert. + + // Here we give a 25% chance for the rate advert to be returned before selecting a random advert from the entire collection which also includes the rate advert + if (0 == rand(0, 3) && isset($available_notices['rate'])) return $available_notices['rate']; + + // Using shuffle here as something like rand which produces a random number and uses that as the array index fails, this is because in future an advert may not be numbered and could have a string as its key which will then cause errors. + shuffle($available_notices); + return $available_notices[0]; + } + + /** + * Skip seasonal notices + * + * @param array $notice_data - an array of data for the chosen notice + * + * @return boolean + */ + protected function skip_seasonal_notices($notice_data) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable + return false; + } + + /** + * Returns affiliate ID + * + * @return mixed Returns affiliate ID + */ + public function get_affiliate_id() { + return $this->self_affiliate_id; + } + + /** + * Checks if the notice has been dismissed + * + * @param string $dismiss_time - dismiss time + * + * @return mixed + */ + abstract protected function check_notice_dismissed($dismiss_time); +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-rpc/class-udrpc.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-rpc/class-udrpc.php new file mode 100755 index 00000000..715a12ad --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-rpc/class-udrpc.php @@ -0,0 +1,1127 @@ +set_key_local($our_private_key); +$ud_rpc->set_key_remote($their_public_key); +$encrypted = $ud_rpc->encrypt_message('blah blah'); + +// Use the saved WP site option +$ud_rpc = new UpdraftPlus_Remote_Communications($name_indicator); // $name_indicator is a key indicator - indicating which key is being used. +$ud_rpc->set_option_name('udrpc_remotekey'); +if (!$ud_rpc->get_key_remote()) throw new Exception('...'); +$encrypted = $ud_rpc->encrypt_message('blah blah'); + +// Generate a new key +$ud_rpc = new UpdraftPlus_Remote_Communications('myindicator.example.com'); +$ud_rpc->set_option_name('udrpc_localkey'); // Save as a WP site option +$new_pair = $ud_rpc->generate_new_keypair(); +if ($new_pair) { + $local_private_key = $ud_rpc->get_key_local(); + $remote_public_key = $ud_rpc->get_key_remote(); + // ... +} else { + throw new Exception('...'); +} + +// Send a message +$ud_rpc->activate_replay_protection(); +$ud_rpc->set_destination_url('https://example.com/path/to/wp'); +$ud_rpc->send_message('ping'); +$ud_rpc->send_message('somecommand', array('param1' => 'data', 'param2' => 'moredata')); + +// N.B. The data sent needs to be something that will pass json_encode(). So, it may be desirable to base64-encode it first. + +// Create a listener for incoming messages + +add_filter('udrpc_command_somecommand', 'my_function', 10, 3); +// function my_function($response, $data, $name_indicator) { ... ; return array('response' => 'my_reply', 'data' => 'any mixed data'); } +// Or: +// add_filter('udrpc_action', 'some_function', 10, 4); // Function must return something other than false to indicate that it handled the specific command. Any returned value will be sent as the reply. +// function some_function($response, $command, $data, $name_indicator) { ...; return array('response' => 'my_reply', 'data' => 'any mixed data'); } +$ud_rpc->set_option_name('udrpc_local_private_key'); +$ud_rpc->activate_replay_protection(); +if ($ud_rpc->get_key_local()) { + // Make sure you call this before the wp_loaded action is fired (e.g. at init) + $ud_rpc->create_listener(); +} + +// Instead of using activate_replay_protection(), you can use activate_sequence_protection() (receiving side) and set_next_send_sequence_id(). They are very similar; but, the sequence number code isn't tested, and is problematic if you may have multiple clients that don't share storage (you can use the current time as a sequence number, but if two clients send at the same millisecond (or whatever granularity you use), you may have problems); whereas the replay protection code relies on database storage on the sending side (not just the receiving). + +*/ +// @codingStandardsIgnoreEnd +if (!class_exists('UpdraftPlus_Remote_Communications')) : +class UpdraftPlus_Remote_Communications { + + // Version numbers relate to versions of this PHP library only (i.e. it's not a protocol support number, and version numbers of other compatible libraries (e.g. JavaScript) are not comparable) + public $version = '1.4.24'; + + private $key_name_indicator; + + private $key_option_name = false; + + private $key_remote = false; + + private $key_local = false; + + private $can_generate = false; + + private $destination_url = false; + + private $maximum_replay_time_difference = 300; + + private $extra_replay_protection = false; + + private $sequence_protection_tolerance; + + private $sequence_protection_table; + + private $sequence_protection_column; + + private $sequence_protection_where_sql; + + // Debug may log confidential data using $this->log() - so only use when you are in a secure environment + private $debug = false; + + private $next_send_sequence_id; + + private $allow_cors_from = array(); + + private $http_transport = null; + + // Default protocol version - this can be over-ridden with set_message_format + // Protocol version 1 (which uses only one RSA key-pair, instead of two) is legacy/deprecated + private $format = 2; + + private $http_credentials = array(); + + private $incoming_message = null; + + private $message_random_number = null; + + private $require_message_to_be_understood = false; + + public function __construct($key_name_indicator = 'default') { + $this->set_key_name_indicator($key_name_indicator); + } + + public function set_key_name_indicator($key_name_indicator) { + $this->key_name_indicator = $key_name_indicator; + } + + public function set_can_generate($can_generate = true) { + $this->can_generate = $can_generate; + } + + /** + * Which sites to allow CORS requests from + * + * @param string $allow_cors_from + */ + public function set_allow_cors_from($allow_cors_from) { + $this->allow_cors_from = $allow_cors_from; + } + + public function set_maximum_replay_time_difference($replay_time_difference) { + $this->maximum_replay_time_difference = (int) $replay_time_difference; + } + + /** + * This will cause more things to be sent to $this->log() + * + * @param boolean $debug + */ + public function set_debug($debug = true) { + $this->debug = (bool) $debug; + } + + /** + * Supported values: a Guzzle object, or, if not, then WP's HTTP API function siwll be used + * + * @param string $transport + */ + public function set_http_transport($transport) { + $this->http_transport = $transport; + } + + /** + * Sequence protection and replay protection perform similar functions, and using both is often over-kill; the distinction is that sequence protection can be used without needing to do database writes on the sending side (e.g. use the value of time() as the sequence number). + * The only rule of sequences is that the receiving side will reject any sequence number that is less than the last previously seen one, within the bounds of the tolerance (but it may also reject those if they are repeats). + * The given table/column will record a comma-separated list of recently seen sequences numbers within the tolerance threshold. + * + * @param string $table + * @param string $column + * @param string $where_sql + * @param integer $tolerance + */ + public function activate_sequence_protection($table, $column, $where_sql, $tolerance = 5) { + $this->sequence_protection_tolerance = (int) $tolerance; + $this->sequence_protection_table = (string) $table; + $this->sequence_protection_column = (string) $column; + $this->sequence_protection_where_sql = (string) $where_sql; + } + + private function ensure_crypto_loaded() { + if (!class_exists('Crypt_Rijndael') || !class_exists('Crypt_RSA') || !class_exists('Crypt_Hash')) { + global $updraftplus, $updraftcentral_host_plugin; + + $base_dir = ''; + if (is_a($updraftcentral_host_plugin, 'UpdraftCentral_Host') && is_callable(array($updraftcentral_host_plugin, 'get_host_dir'))) { + $base_dir = trailingslashit($updraftcentral_host_plugin->get_host_dir()); + } + + // phpseclib 1.x uses deprecated PHP4-style constructors + $this->no_deprecation_warnings_on_php7(); + if (is_a($updraftplus, 'UpdraftPlus')) { + // Since May 2019, the second parameter is unused; but, since we don't know the version, we send it. + $ensure_phpseclib = $updraftplus->ensure_phpseclib(array('Crypt_Rijndael', 'Crypt_RSA', 'Crypt_Hash'), array('Crypt/Rijndael', 'Crypt/RSA', 'Crypt/Hash')); + if (is_wp_error($ensure_phpseclib)) return $ensure_phpseclib; + } elseif (defined('UPDRAFTPLUS_DIR') && file_exists(UPDRAFTPLUS_DIR.'/vendor/phpseclib/phpseclib/phpseclib')) { + $pdir = UPDRAFTPLUS_DIR.'/vendor/phpseclib/phpseclib/phpseclib'; + if (false === strpos(get_include_path(), $pdir)) set_include_path($pdir.PATH_SEPARATOR.get_include_path()); + if (!class_exists('Crypt_Rijndael')) include_once 'Crypt/Rijndael.php'; + if (!class_exists('Crypt_RSA')) include_once 'Crypt/RSA.php'; + if (!class_exists('Crypt_Hash')) include_once 'Crypt/Hash.php'; + } elseif (file_exists(dirname(dirname(__FILE__)).'/vendor/phpseclib/phpseclib/phpseclib')) { + $pdir = dirname(dirname(__FILE__)).'/vendor/phpseclib/phpseclib/phpseclib'; + if (false === strpos(get_include_path(), $pdir)) set_include_path($pdir.PATH_SEPARATOR.get_include_path()); + if (!class_exists('Crypt_Rijndael')) include_once 'Crypt/Rijndael.php'; + if (!class_exists('Crypt_RSA')) include_once 'Crypt/RSA.php'; + if (!class_exists('Crypt_Hash')) include_once 'Crypt/Hash.php'; + } elseif ('' !== $base_dir && file_exists($base_dir.'vendor/phpseclib/phpseclib/phpseclib')) { + $phpseclib_dir = $base_dir.'vendor/phpseclib/phpseclib/phpseclib'; + if (false === strpos(get_include_path(), $phpseclib_dir)) set_include_path($phpseclib_dir.PATH_SEPARATOR.get_include_path()); + if (!class_exists('Crypt_Rijndael')) include_once 'Crypt/Rijndael.php'; + if (!class_exists('Crypt_RSA')) include_once 'Crypt/RSA.php'; + if (!class_exists('Crypt_Hash')) include_once 'Crypt/Hash.php'; + } + } + } + + /** + * Ugly, but necessary to prevent debug output breaking the conversation when the user has debug turned on + */ + private function no_deprecation_warnings_on_php7() { + // PHP_MAJOR_VERSION is defined in PHP 5.2.7+ + // We don't test for PHP > 7 because the specific deprecated element will be removed in PHP 8 - and so no warning should come anyway (and we shouldn't suppress other stuff until we know we need to). + // @codingStandardsIgnoreLine + if (defined('PHP_MAJOR_VERSION') && PHP_MAJOR_VERSION == 7) { + $old_level = error_reporting(); + // @codingStandardsIgnoreLine + $new_level = $old_level & ~E_DEPRECATED; + if ($old_level != $new_level) error_reporting($new_level); + } + } + + public function set_destination_url($destination_url) { + $this->destination_url = $destination_url; + } + + public function get_destination_url() { + return $this->destination_url; + } + + public function set_option_name($key_option_name) { + $this->key_option_name = $key_option_name; + } + + /** + * Method to get the remote key + * + * @return string + */ + public function get_key_remote() { + if (empty($this->key_remote) && $this->can_generate) { + $this->generate_new_keypair(); + } + + return empty($this->key_remote) ? false : $this->key_remote; + } + + /** + * Set the remote key + * + * @param string $key_remote + */ + public function set_key_remote($key_remote) { + $this->key_remote = $key_remote; + } + + /** + * Used for sending - when receiving, the format is part of the message + * + * @param integer $format + */ + public function set_message_format($format = 2) { + $this->format = $format; + } + + /** + * Used for sending - when receiving, the format is part of the message + * + * @return integer + */ + public function get_message_format() { + return $this->format; + } + + /** + * Method to get the local key + * + * @return string + */ + public function get_key_local() { + if (empty($this->key_local)) { + if ($this->key_option_name) { + $key_local = get_site_option($this->key_option_name); + if ($key_local) { + $this->key_local = $key_local; + } + } + } + if (empty($this->key_local) && $this->can_generate) { + $this->generate_new_keypair(); + } + + return empty($this->key_local) ? false : $this->key_local; + } + + /** + * Tests whether a supplied string (after trimming) is a valid portable bundle + * + * @param string $bundle [description] + * @param string $format same as get_portable_bundle() + * @return array (which the consumer is free to use - e.g. convert into internationalised string), with keys 'code' and (perhaps) 'data' + */ + public function decode_portable_bundle($bundle, $format = 'raw') { + $bundle = trim($bundle); + if ('base64_with_count' == $format) { + if (strlen($bundle) < 5) return array('code' => 'invalid_wrong_length', 'data' => 'too_short'); + $len = substr($bundle, 0, 4); + $bundle = substr($bundle, 4); + $len = hexdec($len); + if (strlen($bundle) != $len) return array('code' => 'invalid_wrong_length', 'data' => "1,$len,".strlen($bundle)); + if (false === ($bundle = base64_decode($bundle))) return array('code' => 'invalid_corrupt', 'data' => 'not_base64'); + if (null === ($bundle = json_decode($bundle, true))) return array('code' => 'invalid_corrupt', 'data' => 'not_json'); + } + if (empty($bundle['key'])) return array('code' => 'invalid_corrupt', 'data' => 'no_key'); + if (empty($bundle['url'])) return array('code' => 'invalid_corrupt', 'data' => 'no_url'); + if (empty($bundle['name_indicator'])) return array('code' => 'invalid_corrupt', 'data' => 'no_name_indicator'); + + return $bundle; + } + + /** + * Method to get a portable bundle sufficient to contact this site (i.e. remote site - so you need to have generated a key-pair, or stored the remote key somewhere and restored it) + * + * @param string $format Supported formats: base64_with_count and default)raw + * @param array $extra_info needs to be JSON-serialisable, so be careful about what you put into it. + * @param array $options [description] + * @return array + */ + public function get_portable_bundle($format = 'raw', $extra_info = array(), $options = array()) { + + $bundle = array_merge($extra_info, array( + 'key' => empty($options['key']) ? $this->get_key_remote() : $options['key'], + 'name_indicator' => $this->key_name_indicator, + 'url' => trailingslashit(network_site_url()), + 'admin_url' => trailingslashit(admin_url()), + 'network_admin_url' => trailingslashit(network_admin_url()), + 'format_support' => 2, + )); + + if ('base64_with_count' == $format) { + $bundle = base64_encode(json_encode($bundle)); + + $len = strlen($bundle); // Get the length + $len = dechex($len); // The first bytes of the message are the bundle length + $len = str_pad($len, 4, '0', STR_PAD_LEFT); // Zero pad + + return $len.$bundle; + + } else { + return $bundle; + } + + } + + public function set_key_local($key_local) { + $this->key_local = $key_local; + if ($this->key_option_name) update_site_option($this->key_option_name, $this->key_local); + } + + public function generate_new_keypair($key_size = 2048) { + + $this->ensure_crypto_loaded(); + + $rsa = new Crypt_RSA(); + $keys = $rsa->createKey($key_size); + + if (empty($keys['privatekey'])) { + $this->set_key_local(false); + } else { + $this->set_key_local($keys['privatekey']); + } + + if (empty($keys['publickey'])) { + $this->set_key_remote(false); + } else { + $this->set_key_remote($keys['publickey']); + } + + return empty($keys['publickey']) ? false : true; + } + + /** + * A base-64 encoded RSA hash (PKCS_1) of the message digest + * + * @param string $message + * @param boolean $use_key + * @return array + */ + public function signature_for_message($message, $use_key = false) { + + $hash_algorithm = 'sha256'; + + // Sign with the private (local) key + if (!$use_key) { + if (!$this->key_local) throw new Exception('No signing key has been set'); + $use_key = $this->key_local; + } + + $this->ensure_crypto_loaded(); + + $rsa = new Crypt_RSA(); + $rsa->loadKey($use_key); + // This is the older signature mode; phpseclib's default is the preferred CRYPT_RSA_SIGNATURE_PSS; however, Forge JS doesn't yet support this. More info: https://en.wikipedia.org/wiki/PKCS_1 + $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1); + + // Don't do this: Crypt_RSA::sign() already calculates the digest of the hash + // $hash = new Crypt_Hash($hash_algorithm); + // $hashed = $hash->hash($message); + + // if ($this->debug) $this->log("Message hash (hash=$hash_algorithm) (hex): ".bin2hex($hashed)); + + // phpseclib defaults to SHA1 + $rsa->setHash($hash_algorithm); + $encrypted = $rsa->sign($message); + + if ($this->debug) $this->log('Signed hash (mode='.CRYPT_RSA_SIGNATURE_PKCS1.') (hex): '.bin2hex($encrypted)); + + $signature = base64_encode($encrypted); + + if ($this->debug) $this->log("Message signature (base64): $signature"); + + return $signature; + } + + /** + * Log description + * + * @param string $message + * @param string $level $level is not yet used much + */ + private function log($message, $level = 'notice') { + // Allow other plugins to do something with the message + do_action('udrpc_log', $message, $level, $this->key_name_indicator, $this->debug, $this); + if ('info' != $level) error_log('UDRPC ('.$this->key_name_indicator.", $level): $message"); + } + + /** + * Encrypt the message, using the local key (which needs to exist) + * + * @param string $plaintext + * @param boolean $use_key + * @param integer $key_length + * @return array + */ + public function encrypt_message($plaintext, $use_key = false, $key_length = 32) { + + if (!$use_key) { + if (1 == $this->format) { + if (!$this->key_local) throw new Exception('No encryption key has been set'); + $use_key = $this->key_local; + } else { + if (!$this->key_remote) throw new Exception('No encryption key has been set'); + $use_key = $this->key_remote; + } + } + + $this->ensure_crypto_loaded(); + + $rsa = new Crypt_RSA(); + + if (defined('UDRPC_PHPSECLIB_ENCRYPTION_MODE')) $rsa->setEncryptionMode(UDRPC_PHPSECLIB_ENCRYPTION_MODE); + + $rij = new Crypt_Rijndael(); + + // Generate Random Symmetric Key + $sym_key = crypt_random_string($key_length); + + if ($this->debug) $this->log('Unencrypted symmetric key (hex): '.bin2hex($sym_key)); + + // Encrypt Message with new Symmetric Key + $rij->setKey($sym_key); + $ciphertext = $rij->encrypt($plaintext); + + if ($this->debug) $this->log('Encrypted ciphertext (hex): '.bin2hex($ciphertext)); + + $ciphertext = base64_encode($ciphertext); + + // Encrypt the Symmetric Key with the Asymmetric Key + $rsa->loadKey($use_key); + $sym_key = $rsa->encrypt($sym_key); + + if ($this->debug) $this->log('Encrypted symmetric key (hex): '.bin2hex($sym_key)); + + // Base 64 encode the symmetric key for transport + $sym_key = base64_encode($sym_key); + + if ($this->debug) $this->log('Encrypted symmetric key (b64): '.$sym_key); + + $len = str_pad(dechex(strlen($sym_key)), 3, '0', STR_PAD_LEFT); // Zero pad to be sure. + + // 16 characters of hex is enough for the payload to be to 16 exabytes (giga < tera < peta < exa) of data + $cipherlen = str_pad(dechex(strlen($ciphertext)), 16, '0', STR_PAD_LEFT); + + // Concatenate the length, the encrypted symmetric key, and the message + return $len.$sym_key.$cipherlen.$ciphertext; + + } + + /** + * Decrypt the message, using the local key (which needs to exist) + * + * @param string $message + * @return array + */ + public function decrypt_message($message) { + + if (!$this->key_local) throw new Exception('No decryption key has been set'); + + $this->ensure_crypto_loaded(); + + $rsa = new Crypt_RSA(); + if (defined('UDRPC_PHPSECLIB_ENCRYPTION_MODE')) $rsa->setEncryptionMode(UDRPC_PHPSECLIB_ENCRYPTION_MODE); + // Defaults to CRYPT_AES_MODE_CBC + $rij = new Crypt_Rijndael(); + + // Extract the Symmetric Key + $len = substr($message, 0, 3); + $len = hexdec($len); + $sym_key = substr($message, 3, $len); + + // Extract the encrypted message + $cipherlen = substr($message, ($len + 3), 16); + $cipherlen = hexdec($cipherlen); + + $ciphertext = substr($message, ($len + 19), $cipherlen); + $ciphertext = base64_decode($ciphertext); + + // Decrypt the encrypted symmetric key + $rsa->loadKey($this->key_local); + $sym_key = base64_decode($sym_key); + $sym_key = $rsa->decrypt($sym_key); + + // Decrypt the message + $rij->setKey($sym_key); + + return $rij->decrypt($ciphertext); + + } + + /** + * Creates a message + * + * @param string $command + * @param string $data + * @param boolean $is_response + * @param boolean $use_key_remote + * @param boolean $use_key_local + * @return array which the caller will then format as required (e.g. use as body in post, or JSON-encode, etc.) [description] + */ + public function create_message($command, $data = null, $is_response = false, $use_key_remote = false, $use_key_local = false) { + + if ($is_response) { + $send_array = array('response' => $command); + } else { + $send_array = array('command' => $command); + } + + $send_array['time'] = time(); + // This goes in the encrypted portion as well to prevent replays with a different unencrypted name indicator + $send_array['key_name'] = $this->key_name_indicator; + + // This random element means that if the site needs to send two identical commands or responses in the same second, then it can, and still use replay protection + // The value of PHP_INT_MAX on a 32-bit platform + $this->message_random_number = rand(1, 2147483647); + $send_array['rand'] = $this->message_random_number; + + if ($this->next_send_sequence_id) { + $send_array['sequence_id'] = $this->next_send_sequence_id; + ++$this->next_send_sequence_id; + } + + if ($is_response && !empty($this->incoming_message) && isset($this->incoming_message['rand'])) { + $send_array['incoming_rand'] = $this->incoming_message['rand']; + } + + if (null !== $data) $send_array['data'] = $data; + $send_data = $this->encrypt_message(json_encode($send_array), $use_key_remote); + + $message = array( + 'format' => $this->format, + 'key_name' => $this->key_name_indicator, + 'udrpc_message' => $send_data, + ); + + if ($this->format >= 2) { + $signature = $this->signature_for_message($send_data, $use_key_local); + $message['signature'] = $signature; + } + + return $message; + + } + + /** + * N.B. There's already some time-based replay protection. This can be turned on to beef it up. + * This is only for listeners. Replays can only be detection if transients are working on the WP site (which by default only means that the option table is working). + * + * @param boolean $activate + */ + public function activate_replay_protection($activate = true) { + $this->extra_replay_protection = (bool) $activate; + } + + public function set_next_send_sequence_id($id) { + $this->next_send_sequence_id = $id; + } + + /** + * Set_http_credentials + * + * @param string $credentials should be an array with entries for 'username' and 'password' + */ + public function set_http_credentials($credentials) { + $this->http_credentials = $credentials; + } + + /** + * This needs only to return an array with keys body and response - where response is also an array, with key 'code' (the HTTP status code) + * The $post_options array support these keys: timeout, body, + * Public, to allow short-circuiting of the library's own encoding/decoding (e.g. for acting as a proxy for a message already encrypted elsewhere) + * + * @param array $post_options + * @return array + */ + public function http_post($post_options) { + global $wp_version; + include ABSPATH.WPINC.'/version.php'; + $http_credentials = $this->http_credentials; + + if (is_a($this->http_transport, 'GuzzleHttp\Client')) { + + // https://guzzle.readthedocs.org/en/5.3/clients.html + + $client = $this->http_transport; + + $guzzle_options = array( + 'form_params' => $post_options['body'], + 'headers' => array( + 'User-Agent' => 'WordPress/'.$wp_version.'; class-udrpc.php-Guzzle/'.$this->version.'; '.get_bloginfo('url'), + ), + 'exceptions' => false, + 'timeout' => $post_options['timeout'], + ); + + if (!class_exists('WP_HTTP_Proxy')) include_once ABSPATH.WPINC.'/class-http.php'; + $proxy = new WP_HTTP_Proxy(); + if ($proxy->is_enabled()) { + $user = $proxy->username(); + $pass = $proxy->password(); + $host = $proxy->host(); + $port = (int) $proxy->port(); + if (empty($port)) $port = 8080; + if (!empty($host) && $proxy->send_through_proxy($this->destination_url)) { + $proxy_auth = ''; + if (!empty($user)) { + $proxy_auth = $user; + if (!empty($pass)) $proxy_auth .= ':'.$pass; + $proxy_auth .= '@'; + } + $guzzle_options['proxy'] = array( + 'http' => "http://{$proxy_auth}$host:$port", + 'https' => "http://{$proxy_auth}$host:$port", + ); + } + } + + if (defined('UDRPC_GUZZLE_SSL_VERIFY')) { + $verify = UDRPC_GUZZLE_SSL_VERIFY; + } elseif (file_exists(ABSPATH.WPINC.'/certificates/ca-bundle.crt')) { + $verify = ABSPATH.WPINC.'/certificates/ca-bundle.crt'; + } else { + $verify = true; + } + + $guzzle_options['verify'] = apply_filters('udrpc_guzzle_verify', $verify); + + if (!empty($http_credentials['username'])) { + + $authentication_method = empty($http_credentials['authentication_method']) ? 'basic' : $http_credentials['authentication_method']; + + $password = empty($http_credentials['password']) ? '' : $http_credentials['password']; + + $guzzle_options['auth'] = array( + $http_credentials['username'], + $password, + $authentication_method, + ); + + } + + $response = $client->post($this->destination_url, apply_filters('udrpc_guzzle_options', $guzzle_options, $this)); + + $formatted_response = array( + 'response' => array( + 'code' => $response->getStatusCode(), + ), + 'body' => $response->getBody(), + ); + + return $formatted_response; + + } else { + + $post_options['user-agent'] = 'WordPress/'.$wp_version.'; class-udrpc.php/'.$this->version.'; '.get_bloginfo('url'); + + if (!empty($http_credentials['username'])) { + + $authentication_type = empty($http_credentials['authentication_type']) ? 'basic' : $http_credentials['authentication_type']; + + if ('basic' != $authentication_type) { + return new WP_Error('unsupported_http_authentication_type', 'Only HTTP basic authentication is supported (for other types, use Guzzle)'); + } + + $password = empty($http_credentials['password']) ? '' : $http_credentials['password']; + $post_options['headers'] = array( + 'Authorization' => 'Basic '.base64_encode($http_credentials['username'].':'.$password), + ); + } + + return wp_remote_post( + $this->destination_url, + $post_options + ); + } + } + + public function send_message($command, $data = null, $timeout = 20) { + + if (empty($this->destination_url)) return new WP_Error('not_initialised', 'RPC error: URL not initialised'); + + $message = $this->create_message($command, $data); + + $post_options = array( + 'timeout' => $timeout, + 'body' => $message, + ); + + $post_options = apply_filters('udrpc_post_options', $post_options, $command, $data, $timeout, $this); + + // Make the memory available - may be useful if the message was large + unset($data); + + try { + $post = $this->http_post($post_options); + } catch (Exception $e) { + // Curl can return an error code 0, which causes WP_Error to return early, without recording the message. So, we prefix the code. + return new WP_Error('http_post_'.$e->getCode(), $e->getMessage()); + } + + if (is_wp_error($post)) return $post; + + $response_code = wp_remote_retrieve_response_code($post); + + if (empty($response_code)) return new WP_Error('empty_http_code', 'Unexpected HTTP response code'); + + if ($response_code < 200 || $response_code >= 300) return new WP_Error('unexpected_http_code', 'Unexpected HTTP response code ('.$response_code.')', $post); + + $response_body = wp_remote_retrieve_body($post); + + if (empty($response_body)) return new WP_Error('empty_response', 'Empty response from remote site'); + + $decoded = json_decode($response_body, true); + + if (empty($decoded)) { + + if (false != ($found_at = strpos($response_body, '{"format":'))) { + $new_body = substr($response_body, $found_at); + $decoded = json_decode($new_body, true); + } + + if (empty($decoded)) { + $this->log('response from remote site ('.$this->destination_url.') could not be understood: '.substr($response_body, 0, 100).' ... ', 'info'); + return new WP_Error('response_not_understood', 'Response from remote site could not be understood', $response_body); + } + } + + if (!is_array($decoded) || empty($decoded['udrpc_message'])) return new WP_Error('response_not_understood', 'Response from remote site was not in the expected format ('.$post['body'].')', $decoded); + + if ($this->format >= 2) { + if (empty($decoded['signature'])) { + $this->log('No message signature found'); + die; + } + if (!$this->key_remote) { + $this->log('No signature verification key has been set'); + die; + } + if (!$this->verify_signature($decoded['udrpc_message'], $decoded['signature'], $this->key_remote)) { + $this->log('Signature verification failed; discarding'); + die; + } + } + + $decoded = $this->decrypt_message($decoded['udrpc_message']); + + if (!is_string($decoded)) return new WP_Error('not_decrypted', 'Response from remote site was not successfully decrypted', $decoded['udrpc_message']); + + $json_decoded = json_decode($decoded, true); + + if (!is_array($json_decoded) || empty($json_decoded['response']) || empty($json_decoded['time']) || !is_numeric($json_decoded['time'])) return new WP_Error('response_corrupt', 'Response from remote site was not in the expected format', $decoded); + + // Don't do the reply detection until now, because $post['body'] may not be a message that originated from the remote component at all (e.g. an HTTP error) + if ($this->extra_replay_protection) { + $message_hash = $this->calculate_message_hash((string) $post['body']); + if ($this->message_hash_seen($message_hash)) { + return new WP_Error('replay_detected', 'Message refused: replay detected', $message_hash); + } + } + + $time_difference = absint((time() - $json_decoded['time'])); + if ($time_difference > $this->maximum_replay_time_difference) return new WP_Error('window_error', 'Message refused: maxium replay time difference exceeded', $time_difference); + + if (isset($json_decoded['incoming_rand']) && !empty($this->message_random_number) && $json_decoded['incoming_rand'] != $this->message_random_number) { + // @codingStandardsIgnoreLine + $this->log('UDRPC: Message mismatch (possibly MITM) (sent_rand=' + $this->message_random_number + ', returned_rand='.$json_decoded['incoming_rand'].'): dropping', 'error'); + + return new WP_Error('message_mismatch_error', 'Message refused: message mismatch (possible MITM)'); + + } + + // Should be an array with keys including 'response' and (if relevant) 'data' + return $json_decoded; + + } + + /** + * Returns a boolean indicating whether a listener was created - which depends on whether one was needed (so, false does not necessarily indicate an error condition) + * + * @return boolean + */ + public function create_listener() { + + $http_origin = function_exists('get_http_origin') ? get_http_origin() : (empty($_SERVER['HTTP_ORIGIN']) ? '' : $_SERVER['HTTP_ORIGIN']); + + // Create the WP actions to handle incoming commands, handle built-in commands (e.g. ping, create_keys (authenticate with admin creds)), dispatch them to the right place, and die + if ((!empty($_POST) && !empty($_POST['udrpc_message']) && !empty($_POST['format'])) || (!empty($_SERVER['REQUEST_METHOD']) && 'OPTIONS' == $_SERVER['REQUEST_METHOD'] && $http_origin)) { + add_action('wp_loaded', array($this, 'wp_loaded')); + add_action('wp_loaded', array($this, 'wp_loaded_final'), 10000); + return true; + } + + return false; + } + + public function wp_loaded_final() { + if (empty($this->require_message_to_be_understood)) return; + $message_for = empty($_POST['key_name']) ? '' : (string) $_POST['key_name']; + $this->log("Message was received, but not understood by local site (for: $message_for)"); + die; + } + + public function wp_loaded() { + + /* + // What if something else already set some response headers? + if (function_exists('apache_response_headers')) { + $apache_response_headers = apache_response_headers(); + // Do something... + } + */ + + // CORS: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS + // get_http_origin() : since WP 3.4 + $http_origin = function_exists('get_http_origin') ? get_http_origin() : (empty($_SERVER['HTTP_ORIGIN']) ? '' : $_SERVER['HTTP_ORIGIN']); + if (!empty($_SERVER['REQUEST_METHOD']) && 'OPTIONS' == $_SERVER['REQUEST_METHOD'] && $http_origin) { + if (in_array($http_origin, $this->allow_cors_from)) { + // @codingStandardsIgnoreLine + if (!defined('UDRPC_DO_NOT_SEND_CORS_HEADERS') || !UDRPC_DO_NOT_SEND_CORS_HEADERS) { + header("Access-Control-Allow-Origin: $http_origin"); + header('Access-Control-Allow-Credentials: true'); + if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) header('Access-Control-Allow-Methods: POST, OPTIONS'); + if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) header('Access-Control-Allow-Headers: '.$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']); + } + die; + } elseif ($this->debug) { + $this->log('Non-allowed CORS from: '.$http_origin); + } + // Having detected that this is a CORS request, there's nothing more to do. We return, because a different listener might pick it up, even though we didn't. + return; + } + + // Silently return, rather than dying, in case another instance is able to handle this + if (empty($_POST['format']) || (1 != $_POST['format'] && 2 != $_POST['format'])) return; + + $this->require_message_to_be_understood = true; + + $format = $_POST['format']; + + /* + In format 1 (legacy/obsolete), the one encrypts (the shared AES key) using one half of the key-pair, and decrypts with the other; whereas the other side of the conversation does the reverse when replying (and uses a different shared AES key). Though this is possible in RSA, this is the wrong thing to do - see https://crypto.stackexchange.com/questions/2123/rsa-encryption-with-private-key-and-decryption-with-a-public-key + In format 2, both sides have their own private and public key. The sender encrypts using the other side's public key, and decrypts using its own private key. Messages are signed (the message digest is SHA-256). + */ + + // Is this for us? + if (empty($_POST['key_name']) || $_POST['key_name'] != $this->key_name_indicator) { + return; + } + + // wp_unslash() does not exist until after WP 3.5 + // $udrpc_message = function_exists('wp_unslash') ? wp_unslash($_POST['udrpc_message']) : stripslashes_deep($_POST['udrpc_message']); + + // Data should not have any slashes - it is base64-encoded + $udrpc_message = (string) $_POST['udrpc_message']; + + // Check this now, rather than allow the decrypt method to thrown an Exception + + if (empty($this->key_local)) { + $this->log('no local key (format 1): cannot decrypt', 'error'); + die; + } + + if ($format >= 2) { + if (empty($_POST['signature'])) { + $this->log('No message signature found', 'error'); + die; + } + if (!$this->key_remote) { + $this->log('No signature verification key has been set', 'error'); + die; + } + if (!$this->verify_signature($udrpc_message, $_POST['signature'], $this->key_remote)) { + $this->log('Signature verification failed; discarding', 'error'); + die; + } + } + + try { + $udrpc_message = $this->decrypt_message($udrpc_message); + } catch (Exception $e) { + $this->log('Exception ('.get_class($e).'): '.$e->getMessage(), 'error'); + die; + } + + $udrpc_message = json_decode($udrpc_message, true); + + if (empty($udrpc_message) || !is_array($udrpc_message) || empty($udrpc_message['command']) || !is_string($udrpc_message['command'])) { + $this->log('Could not decode JSON on incoming message', 'error'); + die; + } + + if (empty($udrpc_message['time'])) { + $this->log('No time set in incoming message', 'error'); + die; + } + + // Mismatch indicating a replay of the message with a different key name in the unencrypted portion? + if (empty($udrpc_message['key_name']) || $_POST['key_name'] != $udrpc_message['key_name']) { + $this->log('key_name mismatch between encrypted and unencrypted portions', 'error'); + die; + } + + if ($this->extra_replay_protection) { + $message_hash = $this->calculate_message_hash((string) $_POST['udrpc_message']); + if ($this->message_hash_seen($message_hash)) { + $this->log("Message dropped: apparently a replay (hash: $message_hash)", 'error'); + die; + } + } + + // Do this after the extra replay protection, as that checks hashes within the maximum time window - so don't check the maximum time window until afterwards, to avoid a tiny window (race) in between. + $time_difference = absint($udrpc_message['time'] - time()); + if ($time_difference > $this->maximum_replay_time_difference) { + $this->log("Time in incoming message is outside of allowed window ($time_difference > ".$this->maximum_replay_time_difference.')', 'error'); + die; + } + + // The sequence number should always be larger than any previously-sent sequence number + if ($this->sequence_protection_tolerance) { + + if ($this->debug) $this->log('Sequence protection is active; tolerance: '.$this->sequence_protection_tolerance); + + global $wpdb; + + if (!isset($udrpc_message['sequence_id']) || !is_numeric($udrpc_message['sequence_id'])) { + $this->log('a numerical sequence number is required, but none was included in the message - dropping', 'error'); + die; + } + + $message_sequence_id = (int) $udrpc_message['sequence_id']; + $recently_seen_sequences_ids = $wpdb->get_var($wpdb->prepare('SELECT %s FROM %s LIMIT 1 WHERE '.$this->sequence_protection_where_sql, $this->sequence_protection_column, $this->sequence_protection_table)); + + if ('' === $recently_seen_sequences_ids) $recently_seen_sequences_ids = '0'; + + $recently_seen_sequences_ids_as_array = explode($recently_seen_sequences_ids, ','); + sort($recently_seen_sequences_ids_as_array); + + // Seen before? + if (in_array($message_sequence_id, $recently_seen_sequences_ids_as_array)) { + $this->log("message with duplicate sequence number received - dropping (received=$message_sequence_id, seen=$recently_seen_sequences_ids)"); + die; + } + + // Within the tolerance threshold? That means: a) either bigger than the max, or b) no more than lower than the least + if ($message_sequence_id > max($recently_seen_sequences_ids)) { + if ($this->debug) $this->log("Sequence id ($message_sequence_id) is greater than any previous (".max($recently_seen_sequences_ids).') - message is thus OK'); + // All is well + $recently_seen_sequences_ids_as_array[] = $message_sequence_id; + } elseif ((max($recently_seen_sequences_ids) - $message_sequence_id) <= $this->sequence_protection_tolerance) { + // All is well - was one of those 'missing' in the sequence + if ($this->debug) $this->log("Sequence id ($message_sequence_id) is within tolerance range of previous maximum (".max($recently_seen_sequences_ids).') - message is thus OK'); + $recently_seen_sequences_ids_as_array[] = $message_sequence_id; + } else { + $this->log("message received outside of allowed sequence window - dropping (received=$message_sequence_id, seen=$recently_seen_sequences_ids, tolerance=".$this->sequence_protection_tolerance.')', 'error'); + die; + } + + // Remove out-of-bounds seen IDs + $max_sequence_id_seen = max($recently_seen_sequences_ids_as_array); + foreach ($recently_seen_sequences_ids_as_array as $k => $id) { + if ($max_sequence_id_seen - $id > $this->sequence_protection_tolerance) { + if ($this->debug) $this->log("Removing no-longer-relevant sequence from list of those recently seen: $id"); + unset($recently_seen_sequences_ids_as_array[$k]); + } + } + + // Allow reset + if ($message_sequence_id > PHP_INT_MAX - 10) { + $recently_seen_sequences_ids_as_array = array(0); + } + + // Write them back to the database + $sql = $wpdb->prepare('UPDATE %s SET %s=%s WHERE '.$this->sequence_protection_where_sql, $this->sequence_protection_table, $this->sequence_protection_column, implode(',', $recently_seen_sequences_ids_as_array)); + if ($this->debug) $this->log("SQL to send recent sequence IDs back to the database: $sql"); + $wpdb->query($sql); + + } + + $this->incoming_message = $udrpc_message; + + $command = (string) $udrpc_message['command']; + $data = empty($udrpc_message['data']) ? null : $udrpc_message['data']; + + // @codingStandardsIgnoreLine + if ($http_origin && !empty($udrpc_message['cors_headers_wanted']) && (!defined('UDRPC_DO_NOT_SEND_CORS_HEADERS') || !UDRPC_DO_NOT_SEND_CORS_HEADERS)) { + header("Access-Control-Allow-Origin: $http_origin"); + header('Access-Control-Allow-Credentials: true'); + } + + $this->log('Command received: '.$command, 'info'); + + if ('ping' == $command) { + $response = array('response' => 'pong', 'data' => null); + } else { + if (has_filter('udrpc_command_'.$command)) { + $response = apply_filters('udrpc_command_'.$command, null, $data, $this->key_name_indicator); + } else { + $response = array('response' => 'rpcerror', 'data' => array('code' => 'unknown_rpc_command', 'data' => $command)); + } + } + + $response = apply_filters('udrpc_action', $response, $command, $data, $this->key_name_indicator, $this); + + if (is_array($response)) { + + if ($this->debug) { + $this->log('UDRPC response (pre-encoding/encryption): '.serialize($response)); + } + + $data = isset($response['data']) ? $response['data'] : null; + + $final_response = json_encode($this->create_message($response['response'], $data, true)); + + do_action('udrpc_action_send_response', $final_response, $command); + + echo $final_response; + } + + die; + + } + + /** + * The hash needs to be in a format that phpseclib likes. phpseclib uses lower case. + * Pass in a base64-encoded signature (i.e. just as signature_for_message creates) + * + * @param string $message + * @param string $signature + * @param string $key + * @param string $hash_algorithm + * @return boolean + */ + public function verify_signature($message, $signature, $key, $hash_algorithm = 'sha256') { + $this->ensure_crypto_loaded(); + $rsa = new Crypt_RSA(); + $rsa->setHash(strtolower($hash_algorithm)); + // This is not the default, but is what we use + $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1); + $rsa->loadKey($key); + + // Don't hash it - Crypt_RSA::verify() already does that + // $hash = new Crypt_Hash($hash_algorithm); + // $hashed = $hash->hash($message); + + $verified = $rsa->verify($message, base64_decode($signature)); + + if ($this->debug) $this->log('Signature verification result: '.serialize($verified)); + + return $verified; + } + + private function calculate_message_hash($message) { + return hash('sha256', $message); + } + + private function message_hash_seen($message_hash) { + // 39 characters - less than the WP site transient name limit (40). Though, we use a normal transient, as these don't auto-load at all times. + $transient_name = 'udrpch_'.md5($this->key_name_indicator); + $seen_hashes = get_transient($transient_name); + if (!is_array($seen_hashes)) $seen_hashes = array(); + $time_now = time(); + // $any_changes = false; + // Prune the old hashes + foreach ($seen_hashes as $hash => $last_seen) { + if ($last_seen < ($time_now - $this->maximum_replay_time_difference)) { + // $any_changes = true; + unset($seen_hashes[$hash]); + } + } + if (isset($seen_hashes[$message_hash])) { + return true; + } + $seen_hashes[$message_hash] = $time_now; + set_transient($transient_name, $seen_hashes, $this->maximum_replay_time_difference); + + return false; + } +} + +endif; diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-semaphore/class-updraft-semaphore.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-semaphore/class-updraft-semaphore.php new file mode 100755 index 00000000..acff6c04 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-semaphore/class-updraft-semaphore.php @@ -0,0 +1,213 @@ +lock(2)) { + * try { + * // do stuff ... + * } catch (Exception $e) { + * // We are making sure we release the lock in case of an error + * } catch (Error $e) { + * // We are making sure we release the lock in case of an error + * } + * $my_lock->release(); + * } else { + * error_log("Sorry, could not get the lock"); + * } + */ +class Updraft_Semaphore_3_0 { + + // Time after which the lock will expire (in seconds) + protected $locked_for; + + // Name for the lock in the WP options table + protected $option_name; + + // Lock status - a boolean + protected $acquired = false; + + // An array of loggers + protected $loggers = array(); + + /** + * Constructor. Instantiating does not lock anything, but sets up the details for future operations. + * + * @param String $name - a unique (across the WP site) name for the lock. Should be no more than 51 characters in length (because of the use of the WP options table, with some further characters used internally) + * @param Integer $locked_for - time (in seconds) after which the lock will expire if not released. This needs to be positive if you don't want bad things to happen. + * @param Array $loggers - an array of loggers + */ + public function __construct($name, $locked_for = 300, $loggers = array()) { + $this->option_name = 'updraft_lock_'.$name; + $this->locked_for = $locked_for; + $this->loggers = $loggers; + } + + /** + * Internal function to make sure that the lock is set up in the database + * + * @return Integer - 0 means 'failed' (which could include that someone else concurrently created it); 1 means 'already existed'; 2 means 'exists, because we created it). The intention is that non-zero results mean that the lock exists. + */ + private function ensure_database_initialised() { + + global $wpdb; + + $sql = $wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->options} WHERE option_name = %s", $this->option_name); + + if (1 === (int) $wpdb->get_var($sql)) { + $this->log('Lock option ('.$this->option_name.', '.$wpdb->options.') already existed in the database', 'debug'); + return 1; + } + + $sql = $wpdb->prepare("INSERT INTO {$wpdb->options} (option_name, option_value, autoload) VALUES(%s, '0', 'no');", $this->option_name); + + $rows_affected = $wpdb->query($sql); + + if ($rows_affected > 0) { + $this->log('Lock option ('.$this->option_name.', '.$wpdb->options.') was created in the database', 'debug'); + } else { + $this->log('Lock option ('.$this->option_name.', '.$wpdb->options.') failed to be created in the database (could already exist)', 'notice'); + } + + return ($rows_affected > 0) ? 2 : 0; + } + + /** + * Attempt to acquire the lock. If it was already acquired, then nothing extra will be done (the method will be a no-op). + * + * @param Integer $retries - how many times to retry (after a 1 second sleep each time) + * + * @return Boolean - whether the lock was successfully acquired or not + */ + public function lock($retries = 0) { + + if ($this->acquired) return true; + + global $wpdb; + + $time_now = time(); + $acquire_until = $time_now + $this->locked_for; + + $sql = $wpdb->prepare("UPDATE {$wpdb->options} SET option_value = %s WHERE option_name = %s AND option_value < %d", $acquire_until, $this->option_name, $time_now); + + if (1 === $wpdb->query($sql)) { + $this->log('Lock ('.$this->option_name.', '.$wpdb->options.') acquired', 'info'); + $this->acquired = true; + return true; + } + + // See if the failure was caused by the row not existing (we check this only after failure, because it should only occur once on the site) + if (!$this->ensure_database_initialised()) return false; + + do { + // Now that the row has been created, try again + if (1 === $wpdb->query($sql)) { + $this->log('Lock ('.$this->option_name.', '.$wpdb->options.') acquired after initialising the database', 'info'); + $this->acquired = true; + return true; + } + $retries--; + if ($retries >=0) { + $this->log('Lock ('.$this->option_name.', '.$wpdb->options.') not yet acquired; sleeping', 'debug'); + sleep(1); + // As a second has passed, update the time we are aiming for + $time_now = time(); + $acquire_until = $time_now + $this->locked_for; + $sql = $wpdb->prepare("UPDATE {$wpdb->options} SET option_value = %s WHERE option_name = %s AND option_value < %d", $acquire_until, $this->option_name, $time_now); + } + } while ($retries >= 0); + + $this->log('Lock ('.$this->option_name.', '.$wpdb->options.') could not be acquired (it is locked)', 'info'); + + return false; + } + + /** + * Release the lock + * + * N.B. We don't attempt to unlock it unless we locked it. i.e. Lost locks are left to expire rather than being forced. (If we want to force them, we'll need to introduce a new parameter). + * + * @return Boolean - if it returns false, then the lock was apparently not locked by us (and the caller will most likely therefore ignore the result, whatever it is). + */ + public function release() { + if (!$this->acquired) return false; + global $wpdb; + $sql = $wpdb->prepare("UPDATE {$wpdb->options} SET option_value = '0' WHERE option_name = %s", $this->option_name); + + $this->log('Lock option ('.$this->option_name.', '.$wpdb->options.') released', 'info'); + + $result = (int) $wpdb->query($sql) === 1; + + $this->acquired = false; + + return $result; + } + + /** + * Cleans up the DB of any residual data. This should not be used as part of ordinary unlocking; only as part of deinstalling, or if you otherwise know that the lock will not be used again. If calling this, it's redundant to first unlock (and a no-op to attempt to do so afterwards). + */ + public function delete() { + $this->acquired = false; + + global $wpdb; + $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->options} WHERE option_name = %s", $this->option_name)); + + $this->log('Lock option ('.$this->option_name.', '.$wpdb->options.') was deleted from the database'); + } + + /** + * Captures and logs any given messages + * + * @param String $message - the error message + * @param String $level - the message level (debug, notice, info, warning, error) + */ + public function log($message, $level = 'info') { + if (isset($this->loggers)) { + foreach ($this->loggers as $logger) { + $logger->log($message, $level); + } + } + } + + /** + * Sets the list of loggers for this instance (removing any others). + * + * @param Array $loggers - the loggers for this task + */ + public function set_loggers($loggers) { + $this->loggers = array(); + foreach ($loggers as $logger) { + $this->add_logger($logger); + } + } + + /** + * Add a logger to loggers list + * + * @param Callable $logger - a logger (a method with a callable function 'log', taking string parameters $level $message) + */ + public function add_logger($logger) { + $this->loggers[] = $logger; + } + + /** + * Return the current list of loggers + * + * @return Array + */ + public function get_loggers() { + return $this->loggers; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-semaphore/test.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-semaphore/test.php new file mode 100755 index 00000000..4ef23f25 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-semaphore/test.php @@ -0,0 +1,56 @@ +lock()) { + try { + // do stuff ... + $my_lock_again = new Updraft_Semaphore_3_0('my_test_lock_name', 4, array(new Test_Logger_2())); + $time_now = microtime(true); + if ($my_lock_again->lock(6)) { + echo "Eventually got it after ".round(microtime(true) - $time_now, 3)." seconds\n"; + $my_lock_again->release(); + } else { + echo("Sorry, could not get the second lock\n"); + } + + } catch (Exception $e) { + var_dump($e); + // We are making sure we release the lock in case of an error + } catch (Error $e) { // phpcs:ignore PHPCompatibility.Classes.NewClasses.errorFound + var_dump($e); + // We are making sure we release the lock in case of an error + } + + $my_lock->release(); + +} else { + echo("Sorry, could not get the first lock\n"); +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-manager-commands.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-manager-commands.php new file mode 100755 index 00000000..629f8b91 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-manager-commands.php @@ -0,0 +1,188 @@ +task_manager = $task_manager; + } + + /** + * A list of allowed commands via AJAX + * + * @return array - List of allowed commands + */ + public static function get_allowed_ajax_commands() { + + $commands = array( + 'process_task', + 'get_task_status', + 'end_task', + 'process_queue', + 'get_active_tasks', + 'clean_up_old_tasks', + ); + + return apply_filters('updraft_task_manager_allowed_ajax_commands', $commands); + } + + /** + * Process a single task in the queue + * + * @param array $data data passed via AJAX + * @return void|WP_Error status of the operation + */ + public function process_task($data) { + + if (!isset($data['task_id'])) + return new WP_Error('id_missing', 'Task ID is missing or invalid'); + + $task_id = (int) $data['task_id']; + + $response = apply_filters('updraft_task_manager_process_task_response', "Processing task: {$task_id}", $task_id); + $this->close_browser_connection($response); + $this->task_manager->process_task($task_id); + } + + /** + * Process a single task in the queue + * + * @param array $data data passed via AJAX + * @return String - status of task or false if none found + */ + public function get_task_status($data) { + + if (!isset($data['task_id'])) + return new WP_Error('id_missing', 'Task ID is missing or invalid'); + + $task_id = (int) $data['task_id']; + + return $this->task_manager->get_task_status($task_id); + } + + /** + * Ends a given task + * + * @param array $data data passed via AJAX + * @return boolean - Status of the operation. + */ + public function end_task($data) { + + if (!isset($data['task_id'])) + return new WP_Error('id_missing', 'Task ID is missing or invalid'); + + $task_id = (int) $data['task_id']; + + $status = $this->task_manager->end_task($task_id); + + if (!$status) return new WP_Error('end_task_failed', 'Task is already ended'); + + $response = apply_filters('updraft_task_manager_end_task_response', "Successfully ended task with id : {$task_id}", $task_id); + $this->close_browser_connection($response); + } + + /** + * Fetches a list of all active tasks + * + * @param array $data data passed via AJAX + * @return Mixed - array of UpdraftPlus_Task ojects or NULL if none found + */ + public function get_active_tasks($data) { + + if (!isset($data['type'])) + return new WP_Error('type_missing', 'Task type is missing or invalid'); + + $type = $data['type']; + $tasks = $this->task_manager->get_active_tasks($type); + + $ids = array(); + + if ($tasks) { + foreach ($tasks as $task) { + array_push($ids, $task->get_id()); + } + } + + $response = apply_filters('updraft_task_manager_get_active_tasks_response', $ids, $type); + return $response; + } + + /** + * Cleans out all complete tasks from the DB. + * + * @param array $data data passed via AJAX + * @return void|WP_Error status of the operation + */ + public function clean_up_old_tasks($data) { + + if (!isset($data['type'])) + return new WP_Error('type_missing', 'Task type is missing or invalid'); + + $type = $data['type']; + $status = $this->task_manager->clean_up_old_tasks($type); + + if (!$status) return new WP_Error('clean_up_failed', 'Queue is already empty or the task type invalid'); + + $response = apply_filters('updraft_task_manager_clean_up_old_tasks_response', "Cleaned up old tasks of type : $type", $type); + $this->close_browser_connection($response); + } + + /** + * Processes a queue of a specific type of task + * + * @param array $data data passed via AJAX + * @return void|WP_Error status of the operation + */ + public function process_queue($data) { + if (!isset($data['type'])) + return new WP_Error('type_missing', 'Task type is missing or invalid'); + + $type = $data['type']; + + $response = apply_filters('updraft_task_manager_process_queue_response', "Processing queue of type {$type}", $type); + + $this->close_browser_connection(json_encode($response)); + $status = $this->task_manager->process_queue($type); + + if (!$status) + return new WP_Error('process_queue_operation_failed', 'Failed to process the queue'); + } + + /** + * Close browser connection so that it can resume AJAX polling + * + * @param array $txt Response to browser + * @return void + */ + public function close_browser_connection($txt = '') { + header('Content-Length: '.((!empty($txt)) ? 5+strlen($txt) : '0')); + header('Connection: close'); + header('Content-Encoding: none'); + if (session_id()) session_write_close(); + echo "\r\n\r\n"; + echo $txt; + + $levels = ob_get_level(); + + for ($i = 0; $i < $levels; $i++) { + ob_end_flush(); + } + + flush(); + } +} + +endif; diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-manager.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-manager.php new file mode 100755 index 00000000..3e991b1f --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-manager.php @@ -0,0 +1,349 @@ +commands = new Updraft_Task_Manager_Commands_1_0($this); + + do_action('updraft_task_manager_loaded', $this); + } + + /** + * Process a single task in the queue + * + * @param int|Updraft_Task - $task Task ID or Updraft_Task object. + * @return boolean|WP_Error - status of task or error if task not found + */ + public function process_task($task) { + + if (!is_a($task, 'Updraft_Task_1_2')) { + $task_id = (int) $task; + $task = $this->get_task_instance($task_id); + } + + if (!$task) return new WP_Error('id_invalid', 'Task not found or ID is invalid'); + + return $task->attempt(apply_filters('updraft_task_lock_for', $this->use_per_task_lock, $this)); + + } + + /** + * Gets a list of all tasks that matches the $status flag + * + * @param int|Updraft_Task - $task Task ID or Updraft_Task object. + * @return String|WP_Error - status of task or error if task not found. + */ + public function get_task_status($task) { + + if (!($task instanceof Updraft_Task_1_2)) { + $task_id = (int) $task; + $task = $this->get_task_instance($task_id); + } + + if (!$task) return new WP_Error('id_invalid', 'Task not found or ID is invalid'); + + return $task->get_status(); + } + + /** + * Ends a given task + * + * @param int|Updraft_Task - $task Task ID or Updraft_Task object. + * @return boolean|WP_Error - Status of the operation or error if task not found. + */ + public function end_task($task) { + + if (!($task instanceof Updraft_Task_1_2)) { + $task_id = (int) $task; + $task = $this->get_task_instance($task_id); + } + + if (!$task) return new WP_Error('id_invalid', 'Task not found or ID is invalid'); + + return $task->complete(); + } + + /** + * Process a the queue of a specifed task type + * + * @param string $type queue type to process + * @return bool true on success, false otherwise + */ + public function process_queue($type) { + + $task_list = $this->get_active_tasks($type); + $total = is_array($task_list) ? count($task_list) : 0; + + if (1 > $total) { + $this->log(sprintf('The queue for tasks of type "%s" is empty. Aborting!', $type)); + return true; + } else { + $this->log(sprintf('A total of %d tasks of type %s found and will be processed in this iteration', $total, $type)); + } + + $this->queue_semaphore = new Updraft_Semaphore_3_0($type); + + // Prevent PHP warning which trigger from semaphore class set_loggers method if $this->loggers is empty + if (!empty($this->loggers)) { + $this->queue_semaphore->set_loggers($this->loggers); + } + + if (!$this->queue_semaphore->lock()) { + + $this->log(sprintf('Failed to gain semaphore lock (%s) - another process is already processing the queue - aborting (if this is wrong - i.e. if the other process crashed without removing the lock, then another can be started after 1 minute', $type)); + + return false; + } + + $done = 0; + foreach ($task_list as $task) { + $this->process_task($task); + $done++; + /** + * Filters if the queue should be interrupted. Used after processing each task. + * + * @param boolean $interrupt_queue - If the queue should be interrupted. Default to FALSE + * @param object $task - The current task object + * @param object $task_manager - The task manager instance + */ + if (apply_filters('updraft_interrupt_tasks_queue_'.$type, false, $task, $this)) { + break; + } + } + + $this->queue_semaphore->release(); + $this->log(sprintf('Successfully processed the queue (%s). %d tasks were processed out of %d.', $type, $done, $total)); + $this->queue_semaphore->delete(); + + return $done == $total; + } + + /** + * Cleans out all complete tasks from the DB. + * + * @param String $type type of the task + */ + public function clean_up_old_tasks($type) { + $completed_tasks = $this->get_completed_tasks($type); + + if (!$completed_tasks) return false; + + $this->log(sprintf('Cleaning up tasks of type (%s). A total of %d tasks will be deleted.', $type, count($completed_tasks))); + + foreach ($completed_tasks as $task) { + $task->delete_meta(); + $task->delete(); + } + + return true; + } + + /** + * Delete all tasks from queue. + * + * @param string $type + * + * @return boolean|integer Number of rows deleted, or (boolean)false upon error + */ + public function delete_tasks($task_type) { + global $wpdb; + + $sql = "DELETE t, tm FROM `{$wpdb->base_prefix}tm_tasks` t LEFT JOIN `{$wpdb->base_prefix}tm_taskmeta` tm ON t.id = tm.task_id WHERE t.type = '{$task_type}'"; + + return $wpdb->query($sql); + } + + /** + * Get count of completed and all tasks. + * + * @return array - [ ['complete_tasks' => , 'all_tasks' => ] ] + */ + public function get_status($task_type) { + global $wpdb; + + $query = $wpdb->prepare( + "SELECT complete_tasks, all_tasks FROM (SELECT COUNT(*) AS complete_tasks FROM {$wpdb->base_prefix}tm_tasks WHERE `type` = %s AND `status` = %s) a, (SELECT COUNT(*) AS all_tasks FROM {$wpdb->base_prefix}tm_tasks WHERE `type` = %s) b", + array( + $task_type, + 'complete', + $task_type, + ) + ); + + $status = $wpdb->get_row($query, ARRAY_A); + + if (empty($status)) { + $status = array( + 'complete_tasks' => 0, + 'all_tasks' => 0, + ); + } + + return $status; + } + + /** + * Fetches a list of all active tasks + * + * @param String $type type of the task + * @return Mixed - array of Task ojects or NULL if none found + */ + public function get_active_tasks($type) { + return $this->get_tasks('active', $type); + } + + /** + * Gets a list of all completed tasks + * + * @param String $type type of the task + * @return Mixed - array of Task ojects or NULL if none found + */ + public function get_completed_tasks($type) { + return $this->get_tasks('complete', $type); + } + + /** + * Gets a list of all tasks that matches the $status flag + * + * @param String $status - status of tasks to return, defaults to all tasks + * @param String $type - type of task + * + * @return Mixed - array of Task objects or NULL if none found + */ + public function get_tasks($status, $type) { + global $wpdb; + + $tasks = array(); + + if (array_key_exists($status, Updraft_Task_1_2::get_allowed_statuses())) { + $sql = $wpdb->prepare("SELECT * FROM {$wpdb->base_prefix}tm_tasks WHERE status = %s AND type = %s", $status, $type); + } else { + $sql = $wpdb->prepare("SELECT * FROM {$wpdb->base_prefix}tm_tasks WHERE type = %s", $type); + } + + $_tasks = $wpdb->get_results($sql); + + if (!$_tasks) { + // if we got an error then check if task manager tables are in the database + // and recreate them if needed. + if ($wpdb->last_error) { + Updraft_Tasks_Activation::reinstall_if_needed(); + } + return; + } + + + foreach ($_tasks as $_task) { + $task = $this->get_task_instance($_task->id); + if ($task) array_push($tasks, $task); + } + + return $tasks; + } + + /** + * Retrieve the task instance using its ID + * + * @access public + * + * @global wpdb $wpdb WordPress database abstraction object. + * + * @param int $task_id Task ID. + * @return Task|Boolean Task object, false otherwise. + */ + public function get_task_instance($task_id) { + global $wpdb; + + $task_id = (int) $task_id; + if (!$task_id) return false; + + $sql = $wpdb->prepare("SELECT * FROM {$wpdb->base_prefix}tm_tasks WHERE id = %d LIMIT 1", $task_id); + $_task = $wpdb->get_row($sql); + + if (!$_task) + return false; + + $class_identifier = $_task->class_identifier; + + if (class_exists($class_identifier)) { + $task_instance = new $class_identifier($_task); + $task_instance->set_loggers($this->loggers); + return $task_instance; + } + + return false; + } + + /** + * Sets the logger for this instance. + * + * @param array $loggers - the loggers for this task + */ + public function set_loggers($loggers) { + foreach ($loggers as $logger) { + $this->add_logger($logger); + } + } + + /** + * Add a logger to loggers list + * + * @param Object $logger - a logger for the instance + */ + public function add_logger($logger) { + $this->loggers[] = $logger; + } + + /** + * Return list of loggers + * + * @return array + */ + public function get_loggers() { + return $this->loggers; + } + + /** + * Captures and logs any interesting messages + * + * @param String $message - the error message + * @param String $error_type - the error type + */ + public function log($message, $error_type = 'info') { + if (isset($this->loggers)) { + foreach ($this->loggers as $logger) { + $logger->log($message, $error_type); + } + } + } + +} + +endif; diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-meta.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-meta.php new file mode 100755 index 00000000..81822f8a --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-meta.php @@ -0,0 +1,96 @@ +prepare("SELECT meta_value FROM {$wpdb->base_prefix}tm_taskmeta WHERE task_id = %d AND meta_key = %s LIMIT 1", $id, $key); + + $meta = $wpdb->get_var($sql); + + if ($meta) + return maybe_unserialize($meta); + else return false; + } + + + /** + * This method is used to update data stored in the WordPress database + * + * @param int $id the instance id of the task + * @param String $key the key of the data to update + * @param Mixed $value the value to save to the option + * + * @return Mixed the status of the update operation + */ + public static function update_task_meta($id, $key, $value) { + global $wpdb; + + $id = (int) $id; + if (!$id) return false; + + $value = maybe_serialize($value); + + if (false !== self::get_task_meta($id, $key)) { + $sql = $wpdb->prepare("UPDATE {$wpdb->base_prefix}tm_taskmeta SET meta_value = %s WHERE meta_key = %s AND task_id = %d", $value, $key, $id); + } else { + $sql = $wpdb->prepare("INSERT INTO {$wpdb->base_prefix}tm_taskmeta (task_id, meta_key, meta_value) VALUES (%d, %s, %s)", $id, $key, $value); + } + + return $wpdb->query($sql); + } + + /** + * This method is used to delete task data stored in the WordPress database + * + * @param int $id the instance id of the task + * @param String $key the key to delete + * + * @return Mixed the status of the delete operation + */ + public static function delete_task_meta($id, $key) { + global $wpdb; + + $id = (int) $id; + if (!$id) return false; + + $sql = $wpdb->prepare("DELETE FROM {$wpdb->base_prefix}tm_taskmeta WHERE task_id = %d AND meta_key = %s LIMIT 1", $id, $key); + return $wpdb->query($sql); + } + + /** + * Bulk delete task + * + * @param int $id the instance id of the task + */ + public static function bulk_delete_task_meta($id) { + global $wpdb; + + $id = (int) $id; + if (!$id) return false; + + $sql = $wpdb->prepare("DELETE FROM {$wpdb->base_prefix}tm_taskmeta WHERE task_id = %d", $id); + return $wpdb->query($sql); + } +} + +endif; diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-options.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-options.php new file mode 100755 index 00000000..7e38b78f --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-options.php @@ -0,0 +1,127 @@ + + */ + protected $extra_properties = array(); + + /** + * The Task constructor + * + * @param UpdraftPlus_Task|object $task UpdraftPlus_Task object. + */ + public function __construct($task) { + foreach (get_object_vars($task) as $key => $value) + $this->$key = $value; + } + + /** + * Sets the instance ID. + * + * @param String $instance_id - the instance ID + */ + public function set_id($instance_id) { + $this->id = $instance_id; + } + + /** + * Gets the instance ID. + * + * @return String the instance ID + */ + public function get_id() { + return $this->id; + } + + /** + * Sets the description. + * + * @param String $description - the description of the task + */ + public function set_description($description) { + $this->description = $description; + } + + /** + * Gets the task description + * + * @return String $description - the description of the task + */ + public function get_description() { + return $this->description; + } + + /** + * Sets the type. + * + * @param String $type - the type of the task + */ + public function set_type($type) { + $this->type = $type; + } + + /** + * Gets the number of times this task was attempted + * + * @return int $attempts - the count + */ + public function get_attempts() { + return $this->attempts; + } + + /** + * Sets the number of times this task was attempted + * + * @param String $attempts - the count + */ + public function set_attempts($attempts) { + if (is_numeric($attempts)) + $this->attempts = $attempts; + else return false; + + return $this->update_attempts($this->id, $this->attempts); + } + + /** + * Gets the task type + * + * @return String $type - the type of the task + */ + public function get_type() { + return $this->type; + } + + /** + * Sets the task status. + * + * @param String $status - the status of the task + * + * @return Boolean - the result of the status update + */ + public function set_status($status) { + + if (array_key_exists($status, self::get_allowed_statuses())) + $this->status = $status; + else return false; + + return $this->update_status($this->id, $this->status); + } + + /** + * Gets the task status + * + * @return String $status - the status of the task + */ + public function get_status() { + return $this->status; + } + + /** + * Sets the logger for this task. + * + * @param array $loggers - the loggers for this task + */ + public function set_loggers($loggers) { + if (is_array($loggers)) { + foreach ($loggers as $logger) { + $this->add_logger($logger); + } + } + } + + /** + * Add a logger to loggers list + * + * @param Object $logger - a logger for the task + */ + public function add_logger($logger) { + $this->_loggers[] = $logger; + } + + /** + * Return list of loggers + * + * @return array + */ + public function get_loggers() { + return $this->_loggers; + } + + /** + * The initialisation function that accepts and processes any parameters needed before the task starts + * + * @param Array $options - array of options + * + * @uses update_option + */ + public function initialise($options = array()) { + + do_action('ud_task_before_initialise', $this, $options); + + /** + * Parse incoming $options into an array and merge it with defaults + */ + $defaults = $this->get_default_options(); + $options = wp_parse_args($options, $defaults); + + foreach ($options as $option => $value) { + $this->update_option($option, $value); + } + + do_action('ud_task_initialise_complete', $this, $options); + + } + + /** + * Attempts to perform the task + * + * @param integer $lock_for - if greater than zero, then lock the task, and don't break until this number of seconds has passed + * + * @return boolean Status of the attempt + */ + public function attempt($lock_for = 0) { + + $_task = $this->get_task_from_db($this->get_id()); + + if (!$_task) { + $this->log("The task with id : {$this->get_id()}, and type '{$this->get_type()}' seems to have been deleted from the database."); + return false; + } + + if ('complete' == $this->get_status()) { + $this->log("Attempting already complete task with ID : {$this->get_id()}, and type '{$this->get_type()}'. Aborting !"); + return true; + } + + if ($lock_for) { + $try = 1; + $locked = false; + while ($try < 4) { + if ($locked = $this->lock($this->get_id(), true, $lock_for)) break; + $try ++; + sleep(1); + } + if (!$locked) { + $this->fail('could_not_lock', 'The task could not be locked'); + return false; + } + } + + $attempts = $this->get_attempts(); + + if ($attempts >= $this->get_max_attempts()) { + $this->fail("max_attempts_exceeded", "Maximum attempts ($attempts) exceeded for task"); + return false; + } + + $this->log("Processing task with ID : {$this->get_id()}, and type '{$this->get_type()}'"); + $this->set_attempts(++$attempts); + $status = $this->run(); + + if ($status) { + $this->complete(); + $this->log("Completed processing task with ID : {$this->get_id()}, and type '{$this->get_type()}'"); + } + + if ($lock_for) $this->lock($this->get_id(), false); + + return $status; + } + + /** + * Lock or unlock a task + * + * @param Integer - $task_id - task identifier + * @param Boolean - $lock - whether to lock or unlock + * @param Integer - $lock_for - if already locked, how long after which to break the lock + * + * @return Boolean - whether the operation was successful + */ + public function lock($task_id, $lock = true, $lock_for = 60) { + + global $wpdb; + + if (!$lock) { + return $wpdb->update($wpdb->base_prefix.'tm_tasks', array('last_locked_at' => 0), array('id' => $task_id)) ? true : false; + } + + // Mode: lock. Attempt to set the lock + $affected = $wpdb->update($wpdb->base_prefix.'tm_tasks', array('last_locked_at' => time()), array('id' => $task_id, 'last_locked_at' => 0)); + + // Success. + if (1 == $affected) return true; + + // Failed - something else already had it locked. Grab the lock if it had expired. + $affected = $wpdb->update($wpdb->base_prefix.'tm_tasks', array('last_locked_at' => time()), array('id' => $task_id, 'last_locked_at' => 0)); + + $expires_at = time() - $lock_for; + + $affected = $wpdb->query($wpdb->prepare(" + UPDATE {$wpdb->base_prefix}tm_tasks + SET last_locked_at = %d + WHERE id = %d + AND last_locked_at <= %s + ", time(), $task_id, $expires_at)); + + return $affected ? true : false; + } + + /** + * This function is called to allow for the task to perform a small chunk of work. + * It should be written in a way that anticipates it being killed off at any time. + */ + abstract public function run(); + + /** + * Any clean up code goes here. + */ + public function complete() { + + do_action('ud_task_before_complete', $this); + + $this->set_status('complete'); + + do_action('ud_task_completed', $this); + + return true; + } + + /** + * Fires if the task fails, any clean up code and logging should go here + * + * @param String $error_code - A code for the failure + * @param String $error_message - A description for the failure + */ + public function fail($error_code = "Unknown", $error_message = "Unknown") { + + do_action('ud_task_before_failed', $this); + + $this->set_status('failed'); + $this->log(sprintf("Task with ID %d and type (%s) failed with error code %s - %s", $this->id, $this->type, $error_code, $error_message)); + + $this->update_option("error_code", $error_code); + $this->update_option("error_message", $error_message); + + do_action('ud_task_failed', $this); + + return true; + } + + /** + * Prints any information about the task that the UI can use on the front end for debugging + * @param String $title the header to use in the report + * + * @return String The task report HTML + */ + public function print_task_report_widget($title = 'Task Summary') { + + $ret = ""; + + $status = $this->get_status(); + $stage = $this->get_option('stage') ? $this->get_option('stage') : 'Unknown'; + $description = $this->get_status_description($status); + + + $ret .= "
            "; + $ret .= "

            Task Summary

            "; + $ret .= "
              "; + + foreach ($this as $key => $value) { + $ret .= sprintf("
            • %s : %s
            • ", $key, $value); + } + $ret .='
            '; + + $ret .= "

            $title

            "; + $ret .= "
              "; + + foreach ($this->get_all_options() as $key => $value) { + if (is_array(maybe_unserialize($value))) { + $ret .= sprintf("
            • %s
            • ", $key); + $ret .= "
                "; + foreach (maybe_unserialize($value) as $k => $v) { + $ret .= sprintf("
              • %s => %s
              • ", $k, $v); + } + $ret .= "
              "; + } else { + $ret .= sprintf("
            • %s : %s
            • ", $key, $value); + } + } + $ret .='
            '; + $ret .='
            '; + + return apply_filters('ud_print_task_report_widget', $ret, $this); + + } + + /** + * This method gets an option from the task options in the WordPress database if available, + * otherwise returns the default for this task type + * + * @param String $option the name of the option to get + * @param Mixed $default a value to return if the option is not currently set + * + * @return Mixed The option from the database + */ + public function get_option($option = null, $default = null) { + return Updraft_Task_Options::get_task_option($this->id, $option, $default); + } + + /** + * This method is used to add a task option stored in the WordPress database + * + * @param String $option the name of the option to update + * @param Mixed $value the value to save to the option + * + * @return Mixed the status of the add operation + */ + public function add_option($option, $value) { + return Updraft_Task_Options::update_task_option($this->id, $option, $value); + } + + /** + * This method is used to update a task option stored in the WordPress database + * + * @param String $option the name of the option to update + * @param Mixed $value the value to save to the option + * + * @return Mixed the status of the update operation + */ + public function update_option($option, $value) { + return Updraft_Task_Options::update_task_option($this->id, $option, $value); + } + + /** + * This method is used to delete a task option stored in the WordPress database + * + * @param String $option the option to delete + * + * @return Boolean the result of the delete operation + */ + public function delete_option($option) { + return Updraft_Task_Options::delete_task_option($this->id, $option); + } + + /** + * This method gets all options assoicated with a task + */ + public function get_all_options() { + return Updraft_Task_Options::get_all_task_options($this->id); + } + + /** + * Retrieve default options for this task. + * This method should normally be over-ridden by the child. + * + * @return Array - an array of options + */ + public function get_default_options() { + + $this->log(sprintf('The get_default_options() method was not over-ridden for the class : %s', $this->get_description())); + + return array(); + } + + /** + * Returns a unique label for this instance that can be used as an identifier + * + * @return String - a unique label for this instance + */ + protected function get_unique_label() { + return apply_filters('ud_task_unique_label', $this->id."-".$this->type, $this); + } + + /** + * Updates the status of the given task in the DB + * + * @param String $id - the id of the task + * @param String $status - the status of the task + * + * @return Boolean - the stauts of the update operation + */ + public function update_status($id, $status) { + + if (!array_key_exists($status, self::get_allowed_statuses())) + return false; + + global $wpdb; + $sql = $wpdb->prepare("UPDATE {$wpdb->base_prefix}tm_tasks SET status = %s WHERE id = %d", $status, $id); + + return $wpdb->query($sql); + } + + /** + * Updates the number of attempts made for the given task in the DB + * + * @param String $id - the id of the task + * @param int $attempts - the status of the task + * + * @return Boolean - the stauts of the update operation + */ + public function update_attempts($id, $attempts) { + + if (!is_numeric($attempts)) + return false; + + global $wpdb; + $sql = $wpdb->prepare("UPDATE {$wpdb->base_prefix}tm_tasks SET attempts = %s WHERE id = %d", $attempts, $id); + + return $wpdb->query($sql); + } + + /** + * Cleans out the given task from the DB + * + * @return Boolean - the status of the delete operation + */ + public function delete() { + global $wpdb; + + $sql = $wpdb->prepare("DELETE FROM {$wpdb->base_prefix}tm_tasks WHERE id = %d", $this->id); + return $wpdb->query($sql); + } + + /** + * Cleans out the given task meta from the DB + * + * @return Boolean - the status of the delete operation + */ + public function delete_meta() { + return Updraft_Task_Meta::bulk_delete_task_meta($this->id); + } + + /** + * Helper function to convert object to array. + * + * @return array Object as array. + */ + public function to_array() { + $task = get_object_vars($this); + + foreach (array( 'task_options', 'task_data', 'task_logs', 'task_extras' ) as $key) { + if ($this->__isset($key)) + $task[$key] = $this->__get($key); + } + + return $task; + } + + /** + * Captures and logs any interesting messages + * + * @param String $message - the error message + * @param String $error_type - the error type + */ + public function log($message, $error_type = 'info') { + + if (isset($this->_loggers)) { + foreach ($this->_loggers as $logger) { + $logger->log($message, $error_type); + } + } + } + + /** + * Retrieve all the supported task statuses. + * + * Tasks should have a limited set of valid status values, this method provides a + * list of values and descriptions. + * + * @return array List of task statuses. + */ + public static function get_allowed_statuses() { + $status = array( + 'initialised' => __('Initialised'), + 'active' => __('Active'), + 'paused' => __('Paused'), + 'complete' => __('Completed'), + 'failed' => __('Failed') + ); + + return apply_filters('ud_allowed_task_statuses', $status); + } + + + /** + * Retrieve the max attempts permitted for task type + * + * @return int Max attempts permitted for task type + */ + private function get_max_attempts() { + return apply_filters('ud_max_attempts', 5, $this); + } + + /** + * Retrieve the text description of the task status. + * + * @param String $status - The task status + * + * @return String Description of the task status. + */ + public static function get_status_description($status) { + $list = self::get_allowed_statuses(); + + if (!array_key_exists($status, self::get_allowed_statuses())) + return __('Unknown'); + + return apply_filters("ud_task_status_description_{$status}", $list[$status], $status, $list); + } + + + /** + * Creates a new task instance and returns it + * + * @access public + * + * @global wpdb $wpdb WordPress database abstraction object. + * + * @param String $type A identifier for the task + * @param String $description A description of the task + * @param Mixed $options A list of options to initialise the task + * @param String $task_class Class name of task; only needed/used on PHP 5.2 (due to lack of late static binding) + * + * @return Updraft_Task|false Task object, false otherwise. + */ + public static function create_task($type, $description, $options = array(), $task_class = '') { + global $wpdb; + + $user_id = get_current_user_id(); + $class_identifier = function_exists('get_called_class') ? get_called_class() : $task_class;// phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.get_called_classFound + + $is_anonymous_user_allowed = isset($options['anonymous_user_allowed']) && $options['anonymous_user_allowed']; + if (!$user_id && !$is_anonymous_user_allowed) return false; + + $sql = $wpdb->prepare("INSERT INTO {$wpdb->base_prefix}tm_tasks (type, user_id, description, class_identifier, status) VALUES (%s, %d, %s, %s, %s)", $type, $user_id, $description, $class_identifier, 'active'); + + $wpdb->query($sql); + + $task_id = $wpdb->insert_id; + + if (!$task_id) return false; + + $_task = $wpdb->get_row("SELECT * FROM {$wpdb->base_prefix}tm_tasks WHERE id = {$task_id} LIMIT 1"); + + $task = new $class_identifier($_task); + + if (!$task) return false; + + $task->initialise($options); + + return $task; + } + + /** + * Select the current task from the database + * + * @param int $task_id - The task ID + * @return object|false + */ + private function get_task_from_db($task_id) { + global $wpdb; + $sql = $wpdb->prepare("SELECT * FROM {$wpdb->base_prefix}tm_tasks WHERE id = %d LIMIT 1", $task_id); + return $wpdb->get_row($sql); + } + + /** + * Writing data to inaccessible/non-existing property + * + * @param string $name + * @param mixed $value + * + * @return void + */ + public function __set($name, $value) { + $this->extra_properties[$name] = $value; + } + + /** + * Reading data from inaccessible/non-existing property + * + * @param string $name + * + * @return mixed|null + */ + public function __get($name) { + return isset($this->extra_properties[$name]) ? $this->extra_properties[$name] : null; + } + + /** + * Invoked when `isset` or `empty` are called on inaccessible/non-existing property + * + * @param string $name + * + * @return bool + */ + public function __isset($name) { + return isset($this->extra_properties[$name]); + } + + /** + * Invoked when `unset` is called on inaccessible/non-existing property + * + * @param string $name + * + * @return void + */ + public function __unset($name) { + unset($this->extra_properties[$name]); + } +} +endif; diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-tasks-activation.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-tasks-activation.php new file mode 100755 index 00000000..dbd99edd --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-tasks-activation.php @@ -0,0 +1,303 @@ +, value=array of method names to call + * Example Usage: + * private static $db_updates = array( + * '1.0.1' => array( + * 'update_101_add_new_column', + * ), + * ); + * + * @var Mixed + */ + private static $db_updates = array( + '0.0.1' => array('create_tables'), + '1.0.1' => array('add_attempts_and_class_identifier'), + '1.1' => array('add_lock_column'), + ); + + + const UPDRAFT_TASKS_DB_VERSION = '1.1'; + + /** + * Initialise the use of Task Manager library + * Example Usage: + * Updraft_Tasks_Activation::init(plugin_basename(__FILE__)); + * Updraft_Tasks_Activation::reinstall_if_needed(); + * + * @param string $plugin_slug Plugin slug + * + * @return void + */ + public static function init($plugin_slug) { + $used_by_plugins = self::get_used_by_plugins(); + if (!in_array($plugin_slug, $used_by_plugins)) { + self::update_used_by_plugins(array_merge($used_by_plugins, array($plugin_slug))); + } + } + + /** + * Initialise this class + */ + public static function init_db() { + self::$table_prefix = defined('UPDRAFT_TASKS_TABLE_PREFIX') ? UPDRAFT_TASKS_TABLE_PREFIX : 'tm_'; + } + + /** + * This is the class entry point + */ + public static function install() { + self::init_db(); + self::create_tables(); + // we need walk through all updates when install at first. + self::check_updates(); + } + + /** + * Check needed tables in data base and if one of them doesn't exist force reinstall. + */ + public static function reinstall_if_needed() { + static $done = false; + + if ($done) return; + + if (!self::check_if_tables_exist()) self::reinstall(); + + $done = true; + } + + /** + * Drop database version variable from option from database and run install again. + */ + public static function reinstall() { + self::delete_db_version_variable(); + self::install(); + } + + /** + * Delete database version variable from options table + */ + public static function delete_db_version_variable() { + delete_site_option('updraft_task_manager_dbversion'); + } + + /** + * Drop database tables and version variable from option from database + * + * @param string $plugin_slug Plugin slug + * + * @return void + */ + public static function uninstall($plugin_slug) { + self::delete_used_by_plugins($plugin_slug); + $used_by_plugins = self::get_used_by_plugins(); + if (!empty($used_by_plugins)) return; + self::delete_db_version_variable(); + if (empty(self::$table_prefix)) { + self::init_db(); + } + global $wpdb; + $tables = array('tasks', 'taskmeta'); + foreach($tables as $table) { + $table_name = $wpdb->prefix . self::$table_prefix . $table; + $wpdb->query("DROP TABLE IF EXISTS $table_name"); + } + self::delete_used_by_plugins(); + } + + /** + * Check if needed task manager tables exist. + * + * @return bool + */ + public static function check_if_tables_exist() { + global $wpdb; + self::init_db(); + $our_prefix = $wpdb->base_prefix.self::$table_prefix; + $tables = array($our_prefix.'tasks', $our_prefix.'taskmeta'); + + foreach ($tables as $table) { + $query = "SHOW TABLES LIKE '{$table}'"; + $tables = $wpdb->get_results($query, ARRAY_A); + if (!is_array($tables) || 0 == count($tables)) return false; + } + + return true; + } + + /** + * See if any database schema updates are needed, and perform them if so. + * Example Usage: + * public static function update_101_add_new_column() { + * $wpdb = $GLOBALS['wpdb']; + * $wpdb->query('ALTER TABLE tm_tasks ADD task_expiry varchar(300) AFTER id'); + * } + */ + public static function check_updates() { + self::init_db(); + $our_version = self::get_version(); + if (is_multisite()) { + $db_version = get_site_option('updraft_task_manager_dbversion'); + } else { + $db_version = get_option('updraft_task_manager_dbversion'); + } + if (!$db_version || version_compare($our_version, $db_version, '>')) { + foreach (self::$db_updates as $version => $updates) { + if (version_compare($version, $db_version, '>')) { + foreach ($updates as $update) { + call_user_func(array(__CLASS__, $update)); + } + } + } + if (is_multisite()) { + update_site_option('updraft_task_manager_dbversion', self::get_version()); + } else { + update_option('updraft_task_manager_dbversion', self::get_version()); + } + } + } + + /** + * Returns the current version of the plugin + */ + public static function get_version() { + return self::UPDRAFT_TASKS_DB_VERSION; + } + + /** + * Create the database tables + */ + public static function create_tables() { + + $wpdb = $GLOBALS['wpdb']; + + $our_prefix = $wpdb->base_prefix.self::$table_prefix; + $collate = ''; + + if ($wpdb->has_cap('collation')) { + if (!empty($wpdb->charset)) { + $collate .= "DEFAULT CHARACTER SET $wpdb->charset"; + } + if (!empty($wpdb->collate)) { + $collate .= " COLLATE $wpdb->collate"; + } + } + + include_once ABSPATH.'wp-admin/includes/upgrade.php'; + + // Important: obey the magical/arbitrary rules for formatting this stuff: https://codex.wordpress.org/Creating_Tables_with_Plugins + // Otherwise, you get SQL errors and unwanted header output warnings when activating + + $create_tables = 'CREATE TABLE '.$our_prefix."tasks ( + task_id bigint(20) NOT NULL auto_increment, + user_id bigint(20) NOT NULL, + type varchar(300) NOT NULL, + description varchar(300), + PRIMARY KEY (task_id), + KEY user_id (user_id), + time_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, + status varchar(300) + ) $collate; + "; + // KEY attribute_name (attribute_name) + dbDelta($create_tables); + + $max_index_length = 191; + + $create_tables = 'CREATE TABLE '.$our_prefix."taskmeta ( + meta_id bigint(20) NOT NULL auto_increment, + task_id bigint(20) NOT NULL default '0', + meta_key varchar(255) DEFAULT NULL, + meta_value longtext, + PRIMARY KEY (meta_id), + KEY meta_key (meta_key($max_index_length)), + KEY task_id (task_id) + ) $collate; + "; + + dbDelta($create_tables); + } + + public static function add_attempts_and_class_identifier() { + $wpdb = $GLOBALS['wpdb']; + $our_prefix = $wpdb->base_prefix.self::$table_prefix; + + $wpdb->query("ALTER TABLE ".$our_prefix."tasks CHANGE COLUMN `task_id` `id` INT NOT NULL"); + $wpdb->query("ALTER TABLE ".$our_prefix."tasks MODIFY COLUMN `id` INT auto_increment"); + $wpdb->query("ALTER TABLE ".$our_prefix."tasks ADD attempts INT DEFAULT 0 AFTER type"); + $wpdb->query("ALTER TABLE ".$our_prefix."tasks ADD class_identifier varchar(300) DEFAULT 0 AFTER type"); + } + + public static function add_lock_column() { + $wpdb = $GLOBALS['wpdb']; + $our_prefix = $wpdb->base_prefix.self::$table_prefix; + $wpdb->query('ALTER TABLE '.$our_prefix.'tasks ADD last_locked_at BIGINT DEFAULT 0 AFTER time_created'); + } + + /** + * Get an array of plugin slugs that uses this library + * + * @return array + */ + private static function get_used_by_plugins() { + return get_site_option('updraft_task_manager_plugins', array()); + } + + /** + * Update the array of plugin slugs that uses this library + * + * @param array $used_by_plugins An array of plugin slugs + */ + private static function update_used_by_plugins($used_by_plugins) { + if (is_multisite()) { + update_site_option('updraft_task_manager_plugins', $used_by_plugins); + } else { + update_option('updraft_task_manager_plugins', $used_by_plugins); + } + } + + /** + * Removes either given plugin slug. If plugin slug is not provided removes option itself + * + * @param string $plugin_slug Plugin slug + */ + private static function delete_used_by_plugins($plugin_slug = '') { + if (!empty($plugin_slug)) { + $used_by_plugins = self::get_used_by_plugins(); + $used_by_plugins = self::remove_plugin_from_array($used_by_plugins, $plugin_slug); + self::update_used_by_plugins($used_by_plugins); + } else { + delete_site_option('updraft_task_manager_plugins'); + } + } + + /** + * Remove given plugin slug from an array of plugin slugs + * + * @param array $used_by_plugins An array of plugin slugs + * @param string $plugin_slug Plugin slug + * + * @return array + */ + private static function remove_plugin_from_array($used_by_plugins, $plugin_slug) { + $key = array_search($plugin_slug, $used_by_plugins); + if (false !== $key) { + unset($used_by_plugins[$key]); + } + return $used_by_plugins; + } +} + +endif; diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/README.md b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/README.md new file mode 100755 index 00000000..603d72ce --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/README.md @@ -0,0 +1,93 @@ +# lib-central + + + +## Getting started + +To make it easy for you to get started with GitLab, here's a list of recommended next steps. + +Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! + +## Add your files + +- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files +- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: + +``` +cd existing_repo +git remote add origin https://source.updraftplus.com/team-updraft/lib-central.git +git branch -M master +git push -uf origin master +``` + +## Integrate with your tools + +- [ ] [Set up project integrations](https://source.updraftplus.com/team-updraft/lib-central/-/settings/integrations) + +## Collaborate with your team + +- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) +- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) +- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) +- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) +- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) + +## Test and Deploy + +Use the built-in continuous integration in GitLab. + +- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html) +- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) +- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) +- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) +- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) + +*** + +# Editing this README + +When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template. + +## Suggestions for a good README + +Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. + +## Name +Choose a self-explaining name for your project. + +## Description +Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. + +## Badges +On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. + +## Visuals +Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. + +## Installation +Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. + +## Usage +Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. + +## Support +Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. + +## Roadmap +If you have ideas for releases in the future, it is a good idea to list them in the README. + +## Contributing +State if you are open to contributions and what your requirements are for accepting them. + +For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. + +You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. + +## Authors and acknowledgment +Show your appreciation to those who have contributed to the project. + +## License +For open source projects, say how it is licensed. + +## Project status +If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/bootstrap.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/bootstrap.php new file mode 100755 index 00000000..7fa5f005 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/bootstrap.php @@ -0,0 +1,851 @@ +is_host_dir_set()) die('No access.'); + +// This file is included during plugins_loaded + +// Load the listener class that we rely on to pick up messages +if (!class_exists('UpdraftCentral_Listener')) require_once('listener.php'); + +// We exit if class already exists. More common if two or more plugins integrated +// the same `UpdraftCentral` client folder. +if (!class_exists('UpdraftCentral_Main')) : + +class UpdraftCentral_Main { + + /** + * Class constructor + */ + public function __construct() { + + add_action('udrpc_log', array($this, 'udrpc_log'), 10, 3); + + add_action('wp_ajax_updraftcentral_receivepublickey', array($this, 'wp_ajax_updraftcentral_receivepublickey')); + add_action('wp_ajax_nopriv_updraftcentral_receivepublickey', array($this, 'wp_ajax_updraftcentral_receivepublickey')); + + // The host plugin's command class is registered in its "plugins_loaded" method (e.g. UpdraftPlus::plugins_loaded()). + // + // N.B. The new filter "updraftcentral_remotecontrol_command_classes" was introduced on Jan. 2021 and will soon replace the + // old filter "updraftplus_remotecontrol_command_classes" (below). This was done in order to synchronize all available filters + // and actions related to UpdraftCentral so that we can easily port the UpdraftCentral client code into our other plugins. + // + // If you happened to use the old filter from any of your projects then you might as well update it with the new filter as the + // old filter has already been marked as deprecated, though currently supported as can be seen below but will soon be remove + // from this code block. + $command_classes = apply_filters('updraftcentral_remotecontrol_command_classes', array( + 'core' => 'UpdraftCentral_Core_Commands', + 'updates' => 'UpdraftCentral_Updates_Commands', + 'users' => 'UpdraftCentral_Users_Commands', + 'comments' => 'UpdraftCentral_Comments_Commands', + 'analytics' => 'UpdraftCentral_Analytics_Commands', + 'plugin' => 'UpdraftCentral_Plugin_Commands', + 'theme' => 'UpdraftCentral_Theme_Commands', + 'posts' => 'UpdraftCentral_Posts_Commands', + 'media' => 'UpdraftCentral_Media_Commands', + 'pages' => 'UpdraftCentral_Pages_Commands', + 'backups' => 'UpdraftCentral_Backups_Commands' + )); + + // N.B. This "updraftplus_remotecontrol_command_classes" filter has been marked as deprecated and will be remove after May 2021. + // Please see above code comment for further explanation and its alternative. + $command_classes = apply_filters('updraftplus_remotecontrol_command_classes', $command_classes); + + // If nothing was sent, then there is no incoming message, so no need to set up a listener (or CORS request, etc.). This avoids a DB SELECT query on the option below in the case where it didn't get autoloaded, which is the case when there are no keys. + if (!empty($_SERVER['REQUEST_METHOD']) && ('GET' == $_SERVER['REQUEST_METHOD'] || 'POST' == $_SERVER['REQUEST_METHOD']) && (empty($_REQUEST['action']) || 'updraft_central' !== $_REQUEST['action']) && empty($_REQUEST['udcentral_action']) && empty($_REQUEST['udrpc_message'])) return; + + // Remote control keys + // These are different from the remote send keys, which are set up in the Migrator add-on + $our_keys = $this->get_central_localkeys(); + + if (is_array($our_keys) && !empty($our_keys)) { + new UpdraftCentral_Listener($our_keys, $command_classes); + } + + } + + /** + * Enqueues the needed styles and scripts for UpdraftCentral + * + * @return void + */ + public function enqueue_central_scripts() { + + // This is an additional check; the caller is assumed to have already run checks before painting its page in general + if (!current_user_can('manage_options')) return; + + global $updraftcentral_host_plugin; + $version = $updraftcentral_host_plugin->get_version(); + + $enqueue_version = (defined('WP_DEBUG') && WP_DEBUG) ? $version.'.'.time() : $version; + $min_or_not = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '.min'; + + // Fallback to unminified version if the minified version is not found. + if (!empty($min_or_not) && !file_exists(UPDRAFTCENTRAL_CLIENT_DIR.'/js/central'.$min_or_not.'.js')) { + $min_or_not = ''; + } + + wp_enqueue_script('updraft-central', UPDRAFTCENTRAL_CLIENT_URL.'/js/central'.$min_or_not.'.js', array(), $enqueue_version); + wp_enqueue_style('updraft-central', UPDRAFTCENTRAL_CLIENT_URL.'/css/central'.$min_or_not.'.css', array(), $enqueue_version); + + $localize = array_merge( + array( + 'central_url' => UPDRAFTCENTRAL_CLIENT_URL, + 'plugin_name' => $updraftcentral_host_plugin->get_plugin_name(), + 'updraftcentral_request_nonce' => wp_create_nonce('updraftcentral-request-nonce'), + ), + $updraftcentral_host_plugin->translations + ); + + wp_localize_script('updraft-central', 'uclion', apply_filters('updraftcentral_uclion', $localize)); + } + + /** + * Retrieves current clean url for anchor link where href attribute value is not url (for ex. #div) or empty. Output is not escaped (caller should escape). + * + * @return String - current clean url + */ + public function get_current_clean_url() { + + // Within an UpdraftCentral context, there should be no prefix on the anchor link + if (defined('UPDRAFTCENTRAL_COMMAND') && UPDRAFTCENTRAL_COMMAND || defined('WP_CLI') && WP_CLI) return ''; + + if (defined('DOING_AJAX') && DOING_AJAX && !empty($_SERVER['HTTP_REFERER'])) { + $current_url = $_SERVER['HTTP_REFERER']; + } else { + $url_prefix = is_ssl() ? 'https' : 'http'; + $host = empty($_SERVER['HTTP_HOST']) ? parse_url(network_site_url(), PHP_URL_HOST) : $_SERVER['HTTP_HOST']; + $current_url = $url_prefix."://".$host.wp_unslash($_SERVER['REQUEST_URI']); + } + $remove_query_args = array('state', 'action', 'oauth_verifier', 'nonce', 'updraftplus_instance', 'access_token', 'user_id', 'updraftplus_googledriveauth'); + + $query_string = remove_query_arg($remove_query_args, $current_url); + return function_exists('wp_unslash') ? wp_unslash($query_string) : stripslashes_deep($query_string); + } + + /** + * Get the WordPress version + * + * @return String - the version + */ + public function get_wordpress_version() { + static $got_wp_version = false; + if (!$got_wp_version) { + @include(ABSPATH.WPINC.'/version.php');// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. + $got_wp_version = $wp_version;// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- The variable is defined inside the ABSPATH.WPINC.'/version.php'. + } + return $got_wp_version; + } + + /** + * Retrieves the UpdraftCentral generated keys + * + * @param Mixed $default default value to return when option is not found + * + * @return Mixed + */ + private function get_central_localkeys($default = null) { + + $option = 'updraft_central_localkeys'; + $ret = get_option($option, $default); + return apply_filters('updraftcentral_get_option', $ret, $option, $default); + } + + /** + * Updates the UpdraftCentral's keys + * + * @param string $value Specify option value + * @param bool $use_cache Whether or not to use the WP options cache + * @param string $autoload Whether to autoload (only takes effect on a change of value) + * + * @return bool + */ + private function update_central_localkeys($value, $use_cache = true, $autoload = 'yes') { + $option = 'updraft_central_localkeys'; + + return update_option($option, apply_filters('updraftcentral_update_option', $value, $option, $use_cache), $autoload); + } + + /** + * Receive a new public key in $_GET, and echo a response. Will die() if called. + */ + public function wp_ajax_updraftcentral_receivepublickey() { + global $updraftcentral_host_plugin; + + // The actual nonce check is done in the method below + if (empty($_GET['_wpnonce']) || empty($_GET['public_key']) || !isset($_GET['updraft_key_index'])) die; + + $result = $this->receive_public_key(); + if (!is_array($result) || empty($result['responsetype'])) die; + + ?> + + + UpdraftCentral + + + +
            +

            retrieve_show_message('updraftcentral_connection', true); ?>

            + retrieve_show_message('updraftcentral_connection_successful', true); + } else { + ?> + + retrieve_show_message('updraftcentral_connection_failed', true); ?> +
            + retrieve_show_message('unknown_key', true); + break; + case 'not_logged_in': + echo esc_html($updraftcentral_host_plugin->retrieve_show_message('not_logged_in')).' '; + $updraftcentral_host_plugin->retrieve_show_message('must_visit_url', true); + break; + case 'nonce_failure': + $updraftcentral_host_plugin->retrieve_show_message('security_check', true); + $updraftcentral_host_plugin->retrieve_show_message('must_visit_link', true); + break; + case 'already_have': + $updraftcentral_host_plugin->retrieve_show_message('connection_already_made', true); + break; + case 'insufficient_privilege': + $updraftcentral_host_plugin->retrieve_show_message('insufficient_privilege', true); + break; + default: + echo esc_html(print_r($result, true)); + break; + } + } + ?> +

            +

            retrieve_show_message('close', true); ?> +

            + 'error', 'code' => 'not_logged_in'); + } + + if (!wp_verify_nonce($_GET['_wpnonce'], 'updraftcentral_receivepublickey')) return array('responsetype' => 'error', 'code' => 'nonce_failure'); + + $updraft_key_index = $_GET['updraft_key_index']; + $our_keys = $this->get_central_localkeys(); + + if (!is_array($our_keys)) $our_keys = array(); + + if (!isset($our_keys[$updraft_key_index])) { + return array('responsetype' => 'error', 'code' => 'unknown_key'); + } + + if (!empty($our_keys[$updraft_key_index]['publickey_remote'])) { + return array('responsetype' => 'error', 'code' => 'already_have'); + } + + $our_keys[$updraft_key_index]['publickey_remote'] = base64_decode(stripslashes($_GET['public_key'])); + $this->update_central_localkeys($our_keys, true, 'no'); + + return array('responsetype' => 'ok', 'code' => 'ok'); + } + + /** + * Action parameters, from udrpc: $message, $level, $this->key_name_indicator, $this->debug, $this + * + * @param string $message The log message + * @param string $level Log level + * @param string $key_name_indicator This indicates the key name + */ + public function udrpc_log($message, $level, $key_name_indicator) { + + $udrpc_log = get_site_option('updraftcentral_client_log'); + if (!is_array($udrpc_log)) $udrpc_log = array(); + + $new_item = array( + 'time' => time(), + 'level' => $level, + 'message' => $message, + 'key_name_indicator' => $key_name_indicator + ); + + if (!empty($_SERVER['REMOTE_ADDR'])) { + $new_item['remote_ip'] = $_SERVER['REMOTE_ADDR']; + } + if (!empty($_SERVER['HTTP_USER_AGENT'])) { + $new_item['http_user_agent'] = $_SERVER['HTTP_USER_AGENT']; + } + if (!empty($_SERVER['HTTP_X_SECONDARY_USER_AGENT'])) { + $new_item['http_secondary_user_agent'] = $_SERVER['HTTP_X_SECONDARY_USER_AGENT']; + } + + $udrpc_log[] = $new_item; + + if (count($udrpc_log) > 50) array_shift($udrpc_log); + + update_site_option('updraftcentral_client_log', $udrpc_log); + } + + /** + * Delete UpdraftCentral Key + * + * @param array $key_id key_id of UpdraftCentral + * + * @return array which contains deleted flag and key table. If error, Returns array which contains fatal_error flag and fatal_error_message + */ + public function delete_key($key_id) { + + $our_keys = $this->get_central_localkeys(); + if (is_array($key_id) && isset($key_id['key_id'])) { + $key_id = $key_id['key_id']; + } + + if (!is_array($our_keys)) $our_keys = array(); + if (isset($our_keys[$key_id])) { + unset($our_keys[$key_id]); + $this->update_central_localkeys($our_keys); + } + return array('deleted' => 1, 'keys_table' => $this->get_keys_table()); + } + + /** + * Get UpdraftCentral Log + * + * @return array which contains log_contents. If error, Returns array which contains fatal_error flag and fatal_error_message + */ + public function get_log() { + + global $updraftcentral_host_plugin; + + $udrpc_log = get_site_option('updraftcentral_client_log'); + if (!is_array($udrpc_log)) $udrpc_log = array(); + + $log_contents = ''; + + // Events are appended to the array in the order they happen. So, reversing the order gets them into most-recent-first order. + rsort($udrpc_log); + + if (empty($udrpc_log)) { + $log_contents = ''.$updraftcentral_host_plugin->retrieve_show_message('nothing_yet_logged').''; + } + + foreach ($udrpc_log as $m) { + + // Skip invalid data + if (!isset($m['time'])) continue; + + $time = gmdate('Y-m-d H:i:s O', $m['time']); + // $level is not used yet. We could put the message in different colours for different levels, if/when it becomes used. + + $key_name_indicator = empty($m['key_name_indicator']) ? '' : $m['key_name_indicator']; + + $log_contents .= ''."$time "; + + if (!empty($m['remote_ip'])) $log_contents .= '['.htmlspecialchars($m['remote_ip']).'] '; + + $log_contents .= "[".htmlspecialchars($key_name_indicator)."] ".htmlspecialchars($m['message'])."\n"; + } + + return array('log_contents' => $log_contents); + + } + + public function create_key($params) { + + global $updraftcentral_host_plugin; + + // Use the site URL - this means that if the site URL changes, communication ends; which is the case anyway + $user = wp_get_current_user(); + + if (!is_object($user) || empty($user->ID)) return array('error' => $updraftcentral_host_plugin->retrieve_show_message('insufficient_privilege')); + + if (!current_user_can('manage_options')) return array('error' => $updraftcentral_host_plugin->retrieve_show_message('insufficient_privilege')); + + $where_send = empty($params['where_send']) ? '' : (string) $params['where_send']; + + if ('__updraftpluscom' != $where_send) { + $purl = parse_url($where_send); + if (empty($purl) || !array($purl) || empty($purl['scheme']) || empty($purl['host'])) return array('error' => $updraftcentral_host_plugin->retrieve_show_message('invalid_url')); + } + + // ENT_HTML5 exists only on PHP 5.4+ + // @codingStandardsIgnoreLine + $flags = defined('ENT_HTML5') ? ENT_QUOTES | ENT_HTML5 : ENT_QUOTES; + + $extra_info = array( + 'user_id' => $user->ID, + 'user_login' => $user->user_login, + 'ms_id' => get_current_blog_id(), + 'site_title' => html_entity_decode(get_bloginfo('name'), $flags), + ); + + if ($where_send) { + $extra_info['mothership'] = $where_send; + if (!empty($params['mothership_firewalled'])) { + $extra_info['mothership_firewalled'] = true; + } + } + + if (!empty($params['key_description'])) { + $extra_info['name'] = (string) $params['key_description']; + } + + $key_size = (empty($params['key_size']) || !is_numeric($params['key_size']) || $params['key_size'] < 512) ? 2048 : (int) $params['key_size']; + + $extra_info['key_size'] = $key_size; + + $created = $this->create_remote_control_key(false, $extra_info, $where_send); + + if (is_array($created)) { + $created['keys_table'] = $this->get_keys_table(); + + $created['keys_guide'] = '

            '. $updraftcentral_host_plugin->retrieve_show_message('updraftcentral_key_created') .'

            '; + + if ('__updraftpluscom' != $where_send) { + $created['keys_guide'] .= '

            '.sprintf($updraftcentral_host_plugin->retrieve_show_message('need_to_copy_key'), 'UpdraftCentral dashboard').'

            '.$updraftcentral_host_plugin->retrieve_show_message('press_add_site_button').'

            '.sprintf($updraftcentral_host_plugin->retrieve_show_message('detailed_instructions'), 'UpdraftPlus.com').'

            '; + } else { + $created['keys_guide'] .= '

            '. sprintf($updraftcentral_host_plugin->retrieve_show_message('control_this_site'), 'UpdraftPlus.com').'

            '; + } + } + + return $created; + } + + /** + * Given an index, return the indicator name + * + * @param String $index + * + * @return String + */ + private function indicator_name_from_index($index) { + return $index.'.central.updraftplus.com'; + } + + /** + * Gets an RPC object, and sets some defaults on it that we always want + * + * @param string $indicator_name indicator name + * + * @return array + */ + public function get_udrpc($indicator_name = 'migrator.updraftplus.com') { + + global $updraftcentral_host_plugin, $updraftplus; + + $updraftplus->ensure_phpseclib(); + + if (!class_exists('UpdraftPlus_Remote_Communications_V2')) include_once($updraftcentral_host_plugin->get_host_dir().'/vendor/team-updraft/common-libs/src/updraft-rpc/class-udrpc2.php'); + $ud_rpc = new UpdraftPlus_Remote_Communications_V2($indicator_name); + $ud_rpc->set_can_generate(true); + + return $ud_rpc; + } + + private function create_remote_control_key($index = false, $extra_info = array(), $post_it = false) { + global $updraftcentral_host_plugin; + + $our_keys = $this->get_central_localkeys(); + if (!is_array($our_keys)) $our_keys = array(); + + if (false === $index) { + if (empty($our_keys)) { + $index = 0; + } else { + $index = max(array_keys($our_keys))+1; + } + } + + $name_hash = $index; + + if (isset($our_keys[$name_hash])) { + unset($our_keys[$name_hash]); + } + + $indicator_name = $this->indicator_name_from_index($name_hash); + $ud_rpc = $this->get_udrpc($indicator_name); + + if ('__updraftpluscom' == $post_it) { + $post_it = defined('UPDRAFTPLUS_OVERRIDE_UDCOM_DESTINATION') ? UPDRAFTPLUS_OVERRIDE_UDCOM_DESTINATION : 'https://updraftplus.com/?updraftcentral_action=receive_key'; + $post_it_description = 'UpdraftPlus.Com'; + } else { + $post_it_description = $post_it; + } + + // Normally, key generation takes seconds, even on a slow machine. However, some Windows machines appear to have a setup in which it takes a minute or more. And then, if you're on a double-localhost setup on slow hardware - even worse. It doesn't hurt to just raise the maximum execution time. + + if (function_exists('set_time_limit')) @set_time_limit(UPDRAFTCENTRAL_SET_TIME_LIMIT);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. + + $key_size = (empty($extra_info['key_size']) || !is_numeric($extra_info['key_size']) || $extra_info['key_size'] < 512) ? 2048 : (int) $extra_info['key_size']; + + if (is_object($ud_rpc) && $ud_rpc->generate_new_keypair($key_size)) { + + if ($post_it && empty($extra_info['mothership_firewalled'])) { + + $p_url = parse_url($post_it); + if (is_array($p_url) && !empty($p_url['user'])) { + $http_username = $p_url['user']; + $http_password = empty($p_url['pass']) ? '' : $p_url['pass']; + $post_it = $p_url['scheme'].'://'.$p_url['host']; + if (!empty($p_url['port'])) $post_it .= ':'.$p_url['port']; + $post_it .= $p_url['path']; + if (!empty($p_url['query'])) $post_it .= '?'.$p_url['query']; + } + + $post_options = array( + 'timeout' => 90, + 'body' => array( + 'updraftcentral_action' => 'receive_key', + 'key' => $ud_rpc->get_key_remote() + ) + ); + + if (!empty($http_username)) { + $post_options['headers'] = array( + 'Authorization' => 'Basic '.base64_encode($http_username.':'.$http_password) + ); + } + + // This option allows the key to be sent to the other side via a known-secure channel (e.g. http over SSL), rather than potentially allowing it to travel over an unencrypted channel (e.g. http back to the user's browser). As such, if specified, it is compulsory for it to work. + + $updraftcentral_host_plugin->register_wp_http_option_hooks(); + + $sent_key = wp_remote_post( + $post_it, + $post_options + ); + + $updraftcentral_host_plugin->register_wp_http_option_hooks(false); + + $connection_troubleshooting_url = 'https://updraftplus.com/troubleshooting-updraftcentral-connection-issues/'; + if (is_wp_error($sent_key) || empty($sent_key)) { + + $err_msg = sprintf($updraftcentral_host_plugin->retrieve_show_message('attempt_to_register_failed'), (string) $post_it_description, $connection_troubleshooting_url); + if (is_wp_error($sent_key)) $err_msg .= ' '.$sent_key->get_error_message().' ('.$sent_key->get_error_code().')'; + return array( + 'r' => $err_msg + ); + } + + $response = json_decode(wp_remote_retrieve_body($sent_key), true); + + if (!is_array($response) || !isset($response['key_id']) || !isset($response['key_public'])) { + return array( + 'r' => sprintf($updraftcentral_host_plugin->retrieve_show_message('attempt_to_register_failed'), (string) $post_it_description, $connection_troubleshooting_url), + 'raw' => wp_remote_retrieve_body($sent_key) + ); + } + + $key_hash = hash('sha256', $ud_rpc->get_key_remote()); + + $local_bundle = $ud_rpc->get_portable_bundle('base64_with_count', $extra_info, array('key' => array('key_hash' => $key_hash, 'key_id' => $response['key_id']))); + + } elseif ($post_it) { + // Don't send; instead, include in the bundle info that the mothership is firewalled; this will then tell the mothership to try the reverse connection instead + + if (is_array($extra_info)) { + $extra_info['mothership_firewalled_callback_url'] = wp_nonce_url(admin_url('admin-ajax.php'), 'updraftcentral_receivepublickey'); + $extra_info['updraft_key_index'] = $index; + } + + + $local_bundle = $ud_rpc->get_portable_bundle('base64_with_count', $extra_info, array('key' => $ud_rpc->get_key_remote())); + } + + + if (isset($extra_info['name'])) { + $name = (string) $extra_info['name']; + unset($extra_info['name']); + } else { + $name = 'UpdraftCentral Remote Control'; + } + + $our_keys[$name_hash] = array( + 'name' => $name, + 'key' => $ud_rpc->get_key_local(), + 'extra_info' => $extra_info, + 'created' => time(), + ); + // Store the other side's public key + if (!empty($response) && is_array($response) && !empty($response['key_public'])) { + $our_keys[$name_hash]['publickey_remote'] = $response['key_public']; + } + $this->update_central_localkeys($our_keys, true, 'no'); + + return array( + 'bundle' => $local_bundle, + 'r' => $updraftcentral_host_plugin->retrieve_show_message('key_created_successfully').' '.$updraftcentral_host_plugin->retrieve_show_message('copy_paste_key'), + ); + } + + return false; + + } + + /** + * Get the HTML for the keys table + * + * @param Boolean $echo_instead_of_return Whether the result should be echoed or returned + * @return String + */ + public function get_keys_table($echo_instead_of_return = false) { + + // This is an additional check - it implies requirement for a dashboard context + if (!current_user_can('manage_options')) return; + + global $updraftcentral_host_plugin; + + if (!$echo_instead_of_return) ob_start(); + + $our_keys = $this->get_central_localkeys(); + if (!is_array($our_keys)) $our_keys = array(); + + if (empty($our_keys)) { + ?> + retrieve_show_message('no_updraftcentral_dashboards', true); ?> + +
            + + retrieve_show_message('manage_keys'), count($our_keys))); ?> + + + + + + + + + + $key) { + + if (empty($key['extra_info'])) continue; + + $user_id = $key['extra_info']['user_id']; + + if (!empty($key['extra_info']['mothership'])) { + + $mothership_url = $key['extra_info']['mothership']; + + if ('__updraftpluscom' == $mothership_url) { + $reconstructed_url = 'https://updraftplus.com'; + } else { + $purl = parse_url($mothership_url); + $path = empty($purl['path']) ? '' : $purl['path']; + + $reconstructed_url = $purl['scheme'].'://'.$purl['host'].(!empty($purl['port']) ? ':'.$purl['port'] : '').$path; + } + + } else { + $reconstructed_url = $updraftcentral_host_plugin->retrieve_show_message('unknown'); + } + + $name = $key['name']; + + $user = get_user_by('id', $user_id); + + $user_display = is_a($user, 'WP_User') ? $user->user_login.' ('.$user->user_email.')' : $updraftcentral_host_plugin->retrieve_show_message('unknown'); + ?> + + + +
            retrieve_show_message('key_description', true); ?>retrieve_show_message('details', true); ?>
            retrieve_show_message('access_as_user', true); ?>
            retrieve_show_message('public_key_sent', true); ?>
            + retrieve_show_message('created').' '.date_i18n(get_option('date_format').' '.get_option('time_format'), $key['created'])).'.'; + if (!empty($key['extra_info']['key_size'])) { + echo ' '.esc_html(sprintf($updraftcentral_host_plugin->retrieve_show_message('key_size'), $key['extra_info']['key_size'])).'.'; + } + ?> +
            + + retrieve_show_message('delete', true); ?>
            +
            + +
            +

            retrieve_show_message('connect_to_updraftcentral_dashboard', true); ?>

            + + + + + + + + + + + + + + + + + + + + + + + +
            +
            +
            + + +
            +
            +
            +
            retrieve_show_message('website_installed')), 'UpdraftCentral')); ?>
            +
            + +
            +
            +

            + '.' '.esc_html__('Follow this link to read about how to set browser permission', 'updraftplus').''; ?> +

            +
            +
            + + + enqueue_central_scripts(); + + global $updraftcentral_host_plugin; + + $including_desc = ''; + if (function_exists('get_current_screen')) { + $screen = get_current_screen(); + $hosts = apply_filters('updraftcentral_host_plugins', array()); + $includes = $updraftcentral_host_plugin->retrieve_show_message('including_description'); + + foreach ($hosts as $plugin) { + if (false !== stripos($screen->id, $plugin)) { + $key = str_replace('-', '_', strtolower($plugin)).'_desc'; + if (isset($includes[$key])) { + $including_desc = $includes[$key]; + break; + } + } + } + } + + $updraftcentral_description = preg_replace('/\s+/', ' ', sprintf($updraftcentral_host_plugin->retrieve_show_message('updraftcentral_description'), $including_desc)); + ?> +
            +

            retrieve_show_message('updraftcentral_remote_control', true); ?>

            +

            + retrieve_show_message('read_more', true); ?> +

            +
            + create_key_markup(true); ?> + get_keys_table(true); ?> + + get_log_markup(true); ?> +
            +
            + options['context'] = $context; + } + // TODO: fix up request_filesystem_credentials(), or split it, to allow us to request a no-output version + // This will output a credentials form in event of failure, We don't want that, so just hide with a buffer + ob_start(); + $result = parent::request_filesystem_credentials($error, $context, $allow_relaxed_file_ownership); + ob_end_clean(); + return $result; + } + + /** + * Get update message + * + * @return array reti=urns an array of messages + */ + public function get_upgrade_messages() { + return $this->messages; + } + + /** + * Feedback + * + * @param string|array|WP_Error $data THis is the data to be used for the feedback + */ + protected function updraft_feedback($data) { + if (is_wp_error($data)) { + $string = $data->get_error_message(); + } elseif (is_array($data)) { + return; + } else { + $string = $data; + } + if (!empty($this->upgrader->strings[$string])) + $string = $this->upgrader->strings[$string]; + + if (false !== strpos($string, '%')) { + $args = func_get_args(); + $args = array_splice($args, 1); + if (!empty($args)) + $string = vsprintf($string, $args); + } + + $string = trim($string); + + // Only allow basic HTML in the messages, as it'll be used in emails/logs rather than direct browser output. + $string = wp_kses($string, array( + 'a' => array( + 'href' => true + ), + 'br' => true, + 'em' => true, + 'strong' => true, + )); + + if (empty($string)) + return; + + $this->messages[] = $string; + } + + public function header() { + ob_start(); + } + + public function footer() { + $output = ob_get_clean(); + if (!empty($output)) + $this->feedback($output); + } + + /** + * @access public + */ + public function bulk_header() {} + + public function bulk_footer() { + } +} + +global $updraftcentral_main; +$wp_version = $updraftcentral_main->get_wordpress_version(); + +if (version_compare($wp_version, '5.3', '>=')) { + if (!class_exists('Automatic_Upgrader_Skin')) require_once(dirname(__FILE__).'/automatic-upgrader-skin-compatibility.php'); +} else { + class Automatic_Upgrader_Skin extends Automatic_Upgrader_Skin_Main { + + public function feedback($string) { + parent::updraft_feedback($string); + } + } +} \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/classes/class-updraftcentral-wp-upgrader.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/classes/class-updraftcentral-wp-upgrader.php new file mode 100755 index 00000000..04afcdaf --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/classes/class-updraftcentral-wp-upgrader.php @@ -0,0 +1,49 @@ + (string - a code), 'data' => (mixed)); + * + * RPC commands are not allowed to begin with an underscore. So, any private methods can be prefixed with an underscore. + */ +abstract class UpdraftCentral_Commands { + + protected $rc; + + protected $ud; + + protected $installed_data; + + /** + * Class constructor + * + * @param string $rc + */ + public function __construct($rc) { + $this->rc = $rc; + global $updraftplus; + $this->ud = $updraftplus; + $this->installed_data = array(); + } + + /** + * Include a file or files from wp-admin/includes + */ + final protected function _admin_include() { + $files = func_get_args(); + foreach ($files as $file) { + include_once(ABSPATH.'/wp-admin/includes/'.$file); + } + } + + /** + * Include a file or files from wp-includes + */ + final protected function _frontend_include() { + $files = func_get_args(); + foreach ($files as $file) { + include_once(ABSPATH.WPINC.'/'.$file); + } + } + + /** + * Return a response in the expected format + * + * @param Mixed $data + * @param String $code + * + * @return Array + */ + final protected function _response($data = null, $code = 'rpcok') { + return array( + 'response' => $code, + 'data' => $data + ); + } + + /** + * Return an error in the expected format + * + * @param String $code + * @param Mixed $data + * + * @return Array + */ + final protected function _generic_error_response($code = 'central_unspecified', $data = null) { + return $this->_response( + array( + 'code' => $code, + 'data' => $data + ), + 'rpcerror' + ); + } + + /** + * Checks whether a backup and a security credentials is required for the given request + * + * @param array $dir The directory location to check + * @return array + */ + final protected function _get_backup_credentials_settings($dir) { + + // Do we need to ask the user for filesystem credentials? when installing and/or deleting items in the given directory + $filesystem_method = get_filesystem_method(array(), $dir); + + ob_start(); + $filesystem_credentials_are_stored = request_filesystem_credentials(site_url(), $filesystem_method); + ob_end_clean(); + $request_filesystem_credentials = ('direct' != $filesystem_method && !$filesystem_credentials_are_stored); + + // Do we need to execute a backup process before installing/managing items + $automatic_backups = (class_exists('UpdraftPlus_Options') && class_exists('UpdraftPlus_Addon_Autobackup') && UpdraftPlus_Options::get_updraft_option('updraft_autobackup_default')) ? true : false; + + return array( + 'request_filesystem_credentials' => $request_filesystem_credentials, + 'automatic_backups' => $automatic_backups + ); + } + + /** + * Retrieves the information of the currently installed item (e.g. plugin or theme) through filter + * + * @param bool $response Indicates whether the installation was a success or failure + * @param array $args Extra argument for the hook + * @param array $data Contains paths used and other relevant information regarding the file + * @return array + */ + final public function get_install_data($response, $args, $data) { + + if ($response) { + switch ($args['type']) { + case 'plugin': + $plugin_data = get_plugins('/'.$data['destination_name']); + if (!empty($plugin_data)) { + $info = reset($plugin_data); + $key = key($plugin_data); + + $info['slug'] = $data['destination_name'].'/'.$key; + $this->installed_data = $info; + } + break; + case 'theme': + $theme = wp_get_theme($data['destination_name']); + if ($theme->exists()) { + // Minimalistic info here, if you need to add additional information + // you can add them here. For now, the "Name" and "slug" fields will suffice + // in the succeeding process. + $this->installed_data = array( + 'Name' => $theme->get('Name'), + 'slug' => $data['destination_name'], + 'template' => $theme->get_template() + ); + } + break; + default: + break; + } + } + + return $response; + } + + /** + * Installs and activates either a plugin or theme through zip file upload + * + * @param array $params Parameter array containing information pertaining the currently uploaded item + * @param string $type Indicates whether this current process is intended for a 'plugin' or a 'theme' item + * @return array + */ + final protected function process_chunk_upload($params, $type) { + global $updraftcentral_host_plugin, $updraftcentral_main; + + if (!in_array($type, array('plugin', 'theme'))) { + return $this->_generic_error_response('upload_type_not_supported'); + } + + $permission_error = false; + if ('plugin' === $type) { + if (!current_user_can('install_plugins') || !current_user_can('activate_plugins')) $permission_error = true; + } else { + if (!current_user_can('install_themes') || !current_user_can('switch_themes')) $permission_error = true; + } + + if ($permission_error) { + return $this->_generic_error_response($type.'_insufficient_permission'); + } + + // Pull any available and writable directory where we can store + // our data/file temporarily before running the installation process. + $upload_dir = untrailingslashit(get_temp_dir()); + if (!is_writable($upload_dir)) { + $upload_dir = WP_CONTENT_DIR.'/upgrade'; + + if (!is_dir($upload_dir)) { + $wp_dir = wp_upload_dir(); + if (!empty($wp_dir['basedir'])) $upload_dir = $wp_dir['basedir']; + } + } + + // If we haven't found any writable directory to temporarily store our file then + // we bail and send an error back to the caller. + if (!is_dir($upload_dir) || !is_writable($upload_dir)) { + return $this->_generic_error_response('upload_dir_not_available'); + } + + // Preloads the submitted credentials to the global $_POST variable + if (!empty($params) && isset($params['filesystem_credentials'])) { + parse_str($params['filesystem_credentials'], $filesystem_credentials); + if (is_array($filesystem_credentials)) { + foreach ($filesystem_credentials as $key => $value) { + // Put them into $_POST, which is where request_filesystem_credentials() checks for them. + $_POST[$key] = $value; + } + } + } + + // Save uploaded file + $filename = basename($params['filename']).md5(get_home_url()); + $is_chunked = false; + + if (isset($params['chunks']) && 1 < (int) $params['chunks']) { + $filename .= '.part'; + $is_chunked = true; + } + + if (!$is_chunked || ($is_chunked && isset($params['chunk']) && 0 === (int) $params['chunk'])) { + // if it's not a chunk upload or if it's a chunk upload operation and the current chunk variable is zero, then it means a new upload operation has just begun therefore we should remove previous left-over file (if any and due to error during the previous upload of the same file), because it can lead to a corrupt/invalid zip file (we use file_put_contents a few lines below with FILE_APPEND attribute) + if (file_exists($upload_dir.'/'.$filename) && !unlink($upload_dir.'/'.$filename)) return $this->_generic_error_response('unable_to_delete_existing_file'); + } + + if (empty($params['data'])) { + return $this->_generic_error_response('data_empty_or_invalid'); + } + + $result = file_put_contents($upload_dir.'/'.$filename, base64_decode($params['data']), FILE_APPEND | LOCK_EX); + + if (false === $result) { + return $this->_generic_error_response('unable_to_write_content'); + } + + // Set $install_now to true for single upload and for the last chunk of a multi-chunks upload process + $install_now = true; + + if ($is_chunked) { + if ($params['chunk'] == (int) $params['chunks'] - 1) { + // If this is the last chunk of the request, then we're going to restore the + // original filename of the file (without the '.part') since our upload is now complete. + $orig_filename = basename($filename, '.part'); + $success = rename($upload_dir.'/'.$filename, $upload_dir.'/'.$orig_filename); + + // If renaming the file was successful then restore the original name and override the $filename variable. + // Overriding the $filename variable makes it easy for us to use the same variable for both + // non-chunked and chunked zip file for the installation process. + if ($success) { + $filename = $orig_filename; + } else { + return $this->_generic_error_response('unable_to_rename_file'); + } + } else { + // Bypass installation for now since we're waiting for the last chunk to arrive + // to complete the uploading of the zip file. + $install_now = false; + } + } + + // Everything is already good (upload completed), thus, we proceed with the installation + if ($install_now) { + + // We have successfully uploaded the zip file in this location with its original filename intact. + $zip_filepath = $upload_dir.'/'.$filename; + + // Making sure that the file does actually exists, since we've just run through + // a renaming process above. + if (file_exists($zip_filepath)) { + add_filter('upgrader_post_install', array($this, 'get_install_data'), 10, 3); + + // WP < 3.7 + if (!class_exists('Automatic_Upgrader_Skin')) include_once(UPDRAFTCENTRAL_CLIENT_DIR.'/classes/class-automatic-upgrader-skin.php'); + require_once(UPDRAFTCENTRAL_CLIENT_DIR.'/classes/class-updraftcentral-wp-upgrader.php'); + + $skin = new Automatic_Upgrader_Skin(); + $upgrader = ('plugin' === $type) ? new UpdraftCentral_Plugin_Upgrader($skin) : new UpdraftCentral_Theme_Upgrader($skin); + + $install_result = $upgrader->install($zip_filepath); + remove_filter('upgrader_post_install', array($this, 'get_install_data'), 10, 3); + + // Remove zip file on success and on error (cleanup) + if ($install_result || is_null($install_result) || is_wp_error($install_result)) { + @unlink($zip_filepath);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise if the file doesn't exist. + } + + if (false === $install_result || is_wp_error($install_result)) { + $message = $updraftcentral_host_plugin->retrieve_show_message('unable_to_connect'); + if (is_wp_error($install_result)) $message = $install_result->get_error_message(); + + return $this->_generic_error_response($type.'_install_failed', array('message' => $message)); + } else { + // Pull installed data + $data = $this->installed_data; + + // For WP 3.4 the intended filter hook isn't working or not available + // so we're going to pull the data manually. + if ($install_result && empty($data)) { + $result = $this->get_install_data($install_result, array('type' => $type), $skin->result); + if ($result) { + // Getting the installed data one more time after manually calling + // the "get_install_data" function. + $data = $this->installed_data; + } + } + + if (!empty($data)) { + // Activate item if set + $is_active = ('plugin' === $type) ? is_plugin_active($data['slug']) : ((wp_get_theme()->get('Name') === $data['Name']) ? true : false); + + if ((bool) $params['activate'] && !$is_active) { + if ('plugin' === $type) { + if (is_multisite()) { + $activate = activate_plugin($data['slug'], '', true); + } else { + $activate = activate_plugin($data['slug']); + } + } else { + // In order to make it compatible with older versions of switch_theme which takes two + // arguments we're going to pass two arguments instead of one. Latest versions have backward + // compatibility so it's safe to do it this way. + switch_theme($data['template'], $data['slug']); + $activate = (wp_get_theme()->get_stylesheet() === $data['slug']) ? true : false; + } + + if (false === $activate || is_wp_error($activate)) { + $wp_version = $updraftcentral_main->get_wordpress_version(); + + $message = is_wp_error($activate) ? array('message' => $activate->get_error_message()) : array('message' => sprintf($updraftcentral_host_plugin->retrieve_show_message('unable_to_activate'), $type, $type, $wp_version)); + return $this->_generic_error_response('unable_to_activate_'.$type, $message); + } + } + + return $this->_response( + array( + 'installed' => true, + 'installed_data' => $data, + ) + ); + } + + if (is_wp_error($skin->result)) { + $code = $skin->result->get_error_code(); + $message = $skin->result->get_error_message(); + + $error_data = $skin->result->get_error_data($code); + if (!empty($error_data)) { + if (is_array($error_data)) $error_data = json_encode($error_data); + + $message .= ' '.$error_data; + } + + return $this->_generic_error_response($code, $message); + } else { + return $this->_response( + array( + 'installed' => false, + 'message' => sprintf($updraftcentral_host_plugin->retrieve_show_message('unable_to_install'), $type, $type, $type, $type, 'wp-content/'.$type.'s'), + ) + ); + } + } + } + } else { + // Returning response to a chunk requests while still processing and + // completing the file upload process. If we don't return a positive response + // for every chunk requests then the caller will assumed an error has occurred + // and will eventually stop the upload process. + return $this->_response(array('in_progress' => true)); + } + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/css/central.css b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/css/central.css new file mode 100755 index 00000000..9e33c5ec --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/css/central.css @@ -0,0 +1,57 @@ +.updraftcentral_wizard_option { + width: 45%; + float: left; + text-align: center; +} + +.updraftcentral_wizard_option label { + margin-bottom: 8px; +} + +#updraftcentral_keys_table { + display: none; +} + +.create_key_container { + border: 1px solid; + border-radius: 4px; + padding: 0 0 6px 6px; + margin-bottom: 8px; +} + +.updraftcentral-subheading { + font-size: 14px; + margin-top: -10px; + margin-bottom: 20px; +} + +.updraftcentral-data-consent { + font-size: 13px; + margin-bottom: 10px; +} + +#updraftcentral_keys_table { + width: 100%; +} + +#updraftcentral_stage1_go { + cursor: pointer; +} + +.updraftcentral_wizard_option > div { + margin-top: 5px; +} + +#updraftcentral_keys_table td { + line-height: 1.4em; +} + +#updraftcentral_keys_table .updraftcentral_key_delete { + display: inline-block; + margin-top: 4px; + margin-bottom: 4px; +} + +#updraftcentral_keys_table .updraft_debugrow td { + min-width: auto !important; +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/factory.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/factory.php new file mode 100755 index 00000000..8cff8908 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/factory.php @@ -0,0 +1,81 @@ +get_plugin_name()) + // + // N.B. You can add additional host plugins here. Just make sure that you will create + // a host class for that particular plugin (see central/wp-optimize.php as an example). + $mapped_classes = array( + 'updraftplus' => 'UpdraftPlus_Host', + 'wp-optimize' => 'WP_Optimize_Host', + ); + + $path = $host_class = ''; + foreach ($hosts as $plugin) { + // Make sure that we have a registered host class with a valid file that exist + $host_file = dirname(__FILE__).'/'.$plugin.'.php'; + if (isset($mapped_classes[$plugin]) && file_exists($host_file)) { + $path = $host_file; + $host_class = $mapped_classes[$plugin]; + break; + } + } + + // The host file was not found under this plugin thus, we let the other plugins + // create or build the host plugin (global) variable instead. + if (empty($path)) return null; + + if (!class_exists($host_class)) include_once($path); + + // Re-check host class once again just to make sure that we have the desired + // class loaded before calling its instance method + if (class_exists($host_class)) { + return call_user_func(array($host_class, 'instance')); + } + + return null; + } +} + +endif; + +global $updraftcentral_host_plugin; +$updraftcentral_host_plugin = UpdraftCentral_Factory::create_host(); + +if ($updraftcentral_host_plugin) { + $updraftcentral_host_plugin->load_updraftcentral(); +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/host.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/host.php new file mode 100755 index 00000000..ca88c1a3 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/host.php @@ -0,0 +1,311 @@ +plugin_name; + } + + /** + * Retrieves or shows a message from the translations collection based on its identifier key + * + * @param string $key The ID of the the message + * @param bool $echo Indicate whether the message is to be shown directly (echoed) or just for retrieval + * + * @return string/void + */ + public function retrieve_show_message($key, $echo = false) { + if (empty($key) || !isset($this->translations[$key])) return ''; + + if ($echo) { + echo esc_html($this->translations[$key]); + return; + } + + return $this->translations[$key]; + } + + /** + * Adds a section to a designated area primarily used for generating UpdraftCentral keys + * + * @return void + */ + public function debugtools_dashboard() { + if (!current_user_can('manage_options')) return; + + global $updraftcentral_main; + + if (!class_exists('UpdraftCentral_Main')) { + if (defined('UPDRAFTCENTRAL_CLIENT_DIR') && file_exists(UPDRAFTCENTRAL_CLIENT_DIR.'/bootstrap.php')) { + include_once(UPDRAFTCENTRAL_CLIENT_DIR.'/bootstrap.php'); + $updraftcentral_main = new UpdraftCentral_Main(); + } + } + + if ($updraftcentral_main) { + $updraftcentral_main->debugtools_dashboard(); + } + } + + /** + * Whether the current user can perform key control AJAX actions + * + * @return Boolean + */ + public function current_user_can_ajax() { + return current_user_can('manage_options'); + } + + /** + * Handles ajax requests coming from the section or area generated by the + * "debugtools_dashboard" method (below) + * + * @return void + */ + public function updraft_central_ajax_handler() { + global $updraftcentral_main; + + $nonce = empty($_REQUEST['nonce']) ? '' : $_REQUEST['nonce']; + if (empty($nonce) || !wp_verify_nonce($nonce, 'updraftcentral-request-nonce') || !$this->current_user_can_ajax() || empty($_REQUEST['subaction'])) die('Security check'); + + if (is_a($updraftcentral_main, 'UpdraftCentral_Main')) { + + $subaction = $_REQUEST['subaction']; + if ($this->is_action_whitelisted($subaction) && is_callable(array($updraftcentral_main, $subaction))) { + + // Undo WP's slashing of POST data + $data = $this->wp_unslash($_POST); + + // TODO: Once all commands come through here and through updraft_send_command(), the data should always come from this attribute (once updraft_send_command() is modified appropriately). + if (isset($data['action_data'])) $data = $data['action_data']; + try { + + $results = call_user_func(array($updraftcentral_main, $subaction), $data); + } catch (Exception $e) { + $log_message = 'PHP Fatal Exception error ('.get_class($e).') has occurred during '.$subaction.' subaction. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')'; + error_log($log_message); + echo json_encode(array( + 'fatal_error' => true, + 'fatal_error_message' => $log_message + )); + die; + // @codingStandardsIgnoreLine + } catch (Error $e) { + $log_message = 'PHP Fatal error ('.get_class($e).') has occurred during '.$subaction.' subaction. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')'; + error_log($log_message); + echo json_encode(array( + 'fatal_error' => true, + 'fatal_error_message' => $log_message + )); + die; + } + if (is_wp_error($results)) { + $results = array( + 'result' => false, + 'error_code' => $results->get_error_code(), + 'error_message' => $results->get_error_message(), + 'error_data' => $results->get_error_data(), + ); + } + + if (is_string($results)) { + // A handful of legacy methods, and some which are directly the source for iframes, for which JSON is not appropriate. + echo $results; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- We don't escape here to avoid double escaping and keep the HTML code needed by the receiver of this request. + } else { + echo json_encode($results); + } + die; + } + } + die; + } + + /** + * Verifies whether the submitted action is valid and allowed for execution over AJAX + * + * @param string $action The action to execute + * + * @return bool + */ + private function is_action_whitelisted($action) { + $allowed_actions = array('delete_key', 'get_log', 'create_key'); + return in_array($action, $allowed_actions); + } + + /** + * Retrieves the filter used by UpdraftCentral to log errors or certain events + * + * @return string + */ + public function get_logline_filter() { + return 'updraftcentral_logline'; + } + + /** + * Gets an RPC object, and sets some defaults on it that we always want + * + * @param string $indicator_name indicator name + * @return array + */ + public function get_udrpc($indicator_name = 'migrator.updraftplus.com') { + global $updraftplus; + $updraftplus->ensure_phpseclib(); + if (!class_exists('UpdraftPlus_Remote_Communications_V2')) include_once($this->get_host_dir().'/vendor/team-updraft/common-libs/src/updraft-rpc/class-udrpc2.php'); + $ud_rpc = new UpdraftPlus_Remote_Communications_V2($indicator_name); + $ud_rpc->set_can_generate(true); + return $ud_rpc; + } + + /** + * Noop method. + * Depending on the host plugin this method may or may not be used. + * + * N.B. The UpdraftPlus plugin is using and overriding this method in its host file. + * + * @param boolean $register Indicate whether to add or remote filter hooks + * @ignore + */ + // @codingStandardsIgnoreLine + public function register_wp_http_option_hooks($register = true) {} + + /** + * Remove slashes from a string or array of strings. + * + * The function wp_unslash() is WP 3.6+, so therefore we have a compatibility method here + * + * @param String|Array $value String or array of strings to unslash. + * @return String|Array Unslashed $value + */ + public function wp_unslash($value) { + return function_exists('wp_unslash') ? wp_unslash($value) : stripslashes_deep($value); + } + + /** + * Generate a log line based from the PHP error information + * + * @param Integer $errno Error number + * @param String $errstr Error string + * @param String $errfile Error file + * @param String $errline Line number where the error occurred + * + * @return string|bool + */ + public function php_error_to_logline($errno, $errstr, $errfile, $errline) { + switch ($errno) { + case 1: + $e_type = 'E_ERROR'; + break; + case 2: + $e_type = 'E_WARNING'; + break; + case 4: + $e_type = 'E_PARSE'; + break; + case 8: + $e_type = 'E_NOTICE'; + break; + case 16: + $e_type = 'E_CORE_ERROR'; + break; + case 32: + $e_type = 'E_CORE_WARNING'; + break; + case 64: + $e_type = 'E_COMPILE_ERROR'; + break; + case 128: + $e_type = 'E_COMPILE_WARNING'; + break; + case 256: + $e_type = 'E_USER_ERROR'; + break; + case 512: + $e_type = 'E_USER_WARNING'; + break; + case 1024: + $e_type = 'E_USER_NOTICE'; + break; + case 2048: + $e_type = 'E_STRICT'; + break; + case 4096: + $e_type = 'E_RECOVERABLE_ERROR'; + break; + case 8192: + $e_type = 'E_DEPRECATED'; + break; + case 16384: + $e_type = 'E_USER_DEPRECATED'; + break; + case 30719: + $e_type = 'E_ALL'; + break; + default: + $e_type = "E_UNKNOWN ($errno)"; + break; + } + + if (false !== stripos($errstr, 'table which is not valid in this version of Gravity Forms')) return false; + + if (!is_string($errstr)) $errstr = serialize($errstr); + + if (0 === strpos($errfile, ABSPATH)) $errfile = substr($errfile, strlen(ABSPATH)); + + if ('E_DEPRECATED' == $e_type && !empty($this->no_deprecation_warnings)) { + return false; + } + + return "PHP event: code $e_type: $errstr (line $errline, $errfile)"; + } + + /** + * PHP error handler + * + * @param Integer $errno Error number + * @param String $errstr Error string + * @param String $errfile Error file + * @param String $errline Line number where the error occurred + * + * @return bool + */ + public function php_error($errno, $errstr, $errfile, $errline) { + if (0 == error_reporting()) return true; + $logline = $this->php_error_to_logline($errno, $errstr, $errfile, $errline); + if (false !== $logline) $this->log($logline, 'notice', 'php_event'); + // Pass it up the chain + return $this->error_reporting_stop_when_logged; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/images/ud-logo.png b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/images/ud-logo.png new file mode 100755 index 0000000000000000000000000000000000000000..aa83be9559598e9e428ae831326d59628af709fc GIT binary patch literal 6789 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 t(-JF)3ZHv!W -1 && json_last_pos > -1) { + var json_str = json_mix_str.slice(json_start_pos, json_last_pos + 1); + try { + var parsed = JSON.parse(json_str); + if (!analyse) { console.log(uclion.plugin_name+': JSON re-parse successful'); } + return analyse ? { parsed: parsed, json_start_pos: json_start_pos, json_last_pos: json_last_pos + 1 } : parsed; + } catch (e) { + console.log(uclion.plugin_name+': Exception when trying to parse JSON (2) - will attempt to fix/re-parse based upon bracket counting'); + + var cursor = json_start_pos; + var open_count = 0; + var last_character = ''; + var inside_string = false; + + // Don't mistake this for a real JSON parser. Its aim is to improve the odds in real-world cases seen, not to arrive at universal perfection. + while ((open_count > 0 || cursor == json_start_pos) && cursor <= json_last_pos) { + + var current_character = json_mix_str.charAt(cursor); + + if (!inside_string && '{' == current_character) { + open_count++; + } else if (!inside_string && '}' == current_character) { + open_count--; + } else if ('"' == current_character && '\\' != last_character) { + inside_string = inside_string ? false : true; + } + + last_character = current_character; + cursor++; + } + console.log("Started at cursor="+json_start_pos+", ended at cursor="+cursor+" with result following:"); + console.log(json_mix_str.substring(json_start_pos, cursor)); + + try { + var parsed = JSON.parse(json_mix_str.substring(json_start_pos, cursor)); + console.log(uclion.plugin_name+': JSON re-parse successful'); + return analyse ? { parsed: parsed, json_start_pos: json_start_pos, json_last_pos: cursor } : parsed; + } catch (e) { + // Throw it again, so that our function works just like JSON.parse() in its behaviour. + throw e; + } + } + } + + throw uclion.plugin_name+": could not parse the JSON"; + +} + +jQuery(function($) { + $('#updraftcentral_keys').on('click', 'a.updraftcentral_keys_show', function(e) { + e.preventDefault(); + $(this).remove(); + $('#updraftcentral_keys_table').slideDown(); + }); + + $('#updraftcentral_keycreate_altmethod_moreinfo_get').on('click', function(e) { + e.preventDefault(); + $(this).remove(); + $('#updraftcentral_keycreate_altmethod_moreinfo').slideDown(); + }); + + function updraftcentral_keys_setupform(on_page_load) { + var is_other = jQuery('#updraftcentral_mothership_other').is(':checked') ? true : false; + if (is_other) { + jQuery('#updraftcentral_keycreate_mothership').prop('disabled', false); + if (on_page_load) { + jQuery('#updraftcentral_keycreate_mothership_firewalled_container').show(); + } else { + jQuery('.updraftcentral_wizard_self_hosted_stage2').show(); + jQuery('#updraftcentral_keycreate_mothership_firewalled_container').slideDown(); + jQuery('#updraftcentral_keycreate_mothership').trigger('focus'); + } + } else { + jQuery('#updraftcentral_keycreate_mothership').prop('disabled', true); + if (!on_page_load) { + jQuery('.updraftcentral_wizard_self_hosted_stage2').hide(); + updraftcentral_stage2_go(); + } + } + } + + function updraftcentral_stage2_go() { + // Reset the error message before we continue + jQuery('#updraftcentral_wizard_stage1_error').text(''); + + var host = ''; + + if (jQuery('#updraftcentral_mothership_updraftpluscom').is(':checked')) { + jQuery('.updraftcentral_keycreate_description').hide(); + host = 'updraftplus.com'; + } else if (jQuery('#updraftcentral_mothership_other').is(':checked')) { + jQuery('.updraftcentral_keycreate_description').show(); + var mothership = jQuery('#updraftcentral_keycreate_mothership').val(); + if ('' == mothership) { + jQuery('#updraftcentral_wizard_stage1_error').text(uclion.updraftcentral_wizard_empty_url); + return; + } + try { + var url = new URL(mothership); + host = url.hostname; + } catch (e) { + // Try and grab the host name a different way if it failed because of no URL object (e.g. Firefox version 25 and below). + if ('undefined' === typeof URL) { + host = jQuery('').prop('href', mothership).prop('hostname'); + } + if (!host || 'undefined' !== typeof URL) { + jQuery('#updraftcentral_wizard_stage1_error').text(uclion.updraftcentral_wizard_invalid_url); + return; + } + } + } + + jQuery('#updraftcentral_keycreate_description').val(host); + + jQuery('.updraftcentral_wizard_stage1').hide(); + jQuery('.updraftcentral_wizard_stage2').show(); + } + + jQuery('#updraftcentral_keys').on('click', 'input[type="radio"]', function() { + updraftcentral_keys_setupform(false); + }); + // Initial setup (for browsers, e.g. Firefox, that remember form selection state but not DOM state, which can leave an inconsistent state) + updraftcentral_keys_setupform(true); + + jQuery('#updraftcentral_keys').on('click', '#updraftcentral_view_log', function(e) { + e.preventDefault(); + jQuery('#updraftcentral_view_log_container').block({ message: '

            '+uclion.fetching+'
            '}); + try { + updraftcentral_send_command('get_log', null, function(response) { + jQuery('#updraftcentral_view_log_container').unblock(); + if (response.hasOwnProperty('log_contents')) { + jQuery('#updraftcentral_view_log_contents').html('
            '+response.log_contents+'
            '); + } else { + console.log(response); + } + }, { error_callback: function(response, status, error_code, resp) { + jQuery('#updraftcentral_view_log_container').unblock(); + if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) { + console.error(resp.fatal_error_message); + alert(resp.fatal_error_message); + } else { + var error_message = "updraftcentral_send_command: error: "+status+" ("+error_code+")"; + console.log(error_message); + alert(error_message); + console.log(response); + } + } + }); + } catch (err) { + jQuery('#updraft_central_key').html(); + console.log(err); + } + }); + + // UpdraftCentral + jQuery('#updraftcentral_keys').on('click', '#updraftcentral_wizard_go', function(e) { + jQuery('#updraftcentral_wizard_go').hide(); + jQuery('.updraftcentral_wizard_success').remove(); + jQuery('.create_key_container').show(); + }); + + jQuery('#updraftcentral_keys').on('click', '#updraftcentral_stage1_go', function(e) { + e.preventDefault(); + jQuery('.updraftcentral_wizard_stage2').hide(); + jQuery('.updraftcentral_wizard_stage1').show(); + }); + + jQuery('#updraftcentral_keys').on('click', '#updraftcentral_stage2_go', function(e) { + e.preventDefault(); + + updraftcentral_stage2_go(); + }); + + jQuery('#updraftcentral_keys').on('click', '#updraftcentral_keycreate_go', function(e) { + e.preventDefault(); + + var is_other = jQuery('#updraftcentral_mothership_other').is(':checked') ? true : false; + + var key_description = jQuery('#updraftcentral_keycreate_description').val(); + var key_size = jQuery('#updraftcentral_keycreate_keysize').val(); + + var where_send = '__updraftpluscom'; + + data = { + key_description: key_description, + key_size: key_size, + }; + + if (is_other) { + where_send = jQuery('#updraftcentral_keycreate_mothership').val(); + if (where_send.substring(0, 4) != 'http') { + alert(uclion.enter_mothership_url); + return; + } + } + + data.mothership_firewalled = jQuery('#updraftcentral_keycreate_mothership_firewalled').is(':checked') ? 1 : 0; + data.where_send = where_send; + + jQuery('.create_key_container').hide(); + jQuery('.updraftcentral_wizard_stage1').show(); + jQuery('.updraftcentral_wizard_stage2').hide(); + + jQuery('#updraftcentral_keys').block({ message: '

            '+uclion.creating_please_allow+'
            '}); + + try { + updraftcentral_send_command('create_key', data, function(resp) { + jQuery('#updraftcentral_keys').unblock(); + try { + if (resp.hasOwnProperty('error')) { + alert(resp.error); + console.log(resp); + return; + } + alert(resp.r); + + if (resp.hasOwnProperty('bundle') && resp.hasOwnProperty('keys_guide')) { + jQuery('#updraftcentral_keys_content').html(resp.keys_guide); + jQuery('#updraftcentral_keys_content').append('
            '+resp.r+'
            '); + } else { + console.log(resp); + } + + if (resp.hasOwnProperty('keys_table')) { + jQuery('#updraftcentral_keys_content').append(resp.keys_table); + } + + jQuery('#updraftcentral_wizard_go').show(); + + } catch (err) { + alert(uclion.unexpectedresponse+' '+response); + console.log(err); + } + }, { error_callback: function(response, status, error_code, resp) { + jQuery('#updraftcentral_keys').unblock(); + if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) { + console.error(resp.fatal_error_message); + alert(resp.fatal_error_message); + } else { + var error_message = "updraftcentral_send_command: error: "+status+" ("+error_code+")"; + console.log(error_message); + alert(error_message); + console.log(response); + } + } + }); + } catch (err) { + jQuery('#updraft_central_key').html(); + console.log(err); + } + }); + + + var updraft_copy_modal_buttons = {}; + updraft_copy_modal_buttons[updraftlion.close] = function() { + jQuery(this).dialog("close"); + }; + + jQuery("#updraft-copy-modal").dialog({ + autoOpen: false, + resizeOnWindowResize: true, + scrollWithViewport: true, + resizeAccordingToViewport: true, + modal: true, + buttons: updraft_copy_modal_buttons, + }); + + jQuery('#updraftcentral_keys_content').on('click', '#updraftplus-copy', function(e) { + e.preventDefault(); + var ele = jQuery('#updraftcentral-key'); + if (ele[0].value) { + navigator.clipboard.writeText(ele[0].value).then(function() { + alert(uclion.key_copied); + }, function(err) { + jQuery('#updraft-copy-modal').dialog('open'); + }); + } + }); + + jQuery('#updraftcentral_keys').on('click', '.updraftcentral_key_delete', function(e) { + e.preventDefault(); + var key_id = jQuery(this).data('key_id'); + if ('undefined' == typeof key_id) { + console.log("UpdraftPlus: .updraftcentral_key_delete clicked, but no key ID found"); + return; + } + + jQuery('#updraftcentral_keys').block({ message: '

            '+uclion.deleting+'
            '}); + + updraftcentral_send_command('delete_key', { key_id: key_id }, function(response) { + jQuery('#updraftcentral_keys').unblock(); + if (response.hasOwnProperty('keys_table')) { + jQuery('#updraftcentral_keys_content').html(response.keys_table); + } + }, { error_callback: function(response, status, error_code, resp) { + jQuery('#updraftcentral_keys').unblock(); + if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) { + console.error(resp.fatal_error_message); + alert(resp.fatal_error_message); + } else { + var error_message = "updraftcentral_send_command: error: "+status+" ("+error_code+")"; + console.log(error_message); + alert(error_message); + console.log(response); + } + } + }); + }); +}); \ No newline at end of file diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/listener.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/listener.php new file mode 100755 index 00000000..de648418 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/listener.php @@ -0,0 +1,372 @@ +host = $updraftcentral_host_plugin; + + // It seems impossible for this condition to result in a return; but it seems Plesk can do something odd within the control panel that causes a problem - see HS#6276 + if (!is_a($this->host, 'UpdraftCentral_Host')) return; + + $this->command_classes = $command_classes; + + foreach ($keys as $name_hash => $key) { + // publickey_remote isn't necessarily set yet, depending on the key exchange method + if (!is_array($key) || empty($key['extra_info']) || empty($key['publickey_remote'])) continue; + $indicator = $name_hash.'.central.updraftplus.com'; + $ud_rpc = $this->host->get_udrpc($indicator); + $this->udrpc_version = $ud_rpc->version; + + // Only turn this on if you are comfortable with potentially anything appearing in your PHP error log + if (defined('UPDRAFTCENTRAL_UDRPC_FORCE_DEBUG') && UPDRAFTCENTRAL_UDRPC_FORCE_DEBUG) $ud_rpc->set_debug(true); + + $this->receivers[$indicator] = $ud_rpc; + $this->extra_info[$indicator] = isset($key['extra_info']) ? $key['extra_info'] : null; + $ud_rpc->set_key_local($key['key']); + $ud_rpc->set_key_remote($key['publickey_remote']); + // Create listener (which causes WP actions to be fired when messages are received) + $ud_rpc->activate_replay_protection(); + if (!empty($key['extra_info']) && isset($key['extra_info']['mothership'])) { + $mothership = $key['extra_info']['mothership']; + $url = ''; + if ('__updraftpluscom' == $mothership) { + $url = 'https://teamupdraft.com'; + } elseif (false != ($parsed = parse_url($key['extra_info']['mothership'])) && is_array($parsed)) { + $url = $parsed['scheme'].'://'.$parsed['host']; + } + if (!empty($url)) $ud_rpc->set_allow_cors_from(array($url)); + } + $ud_rpc->create_listener(); + } + + // If we ever need to expand beyond a single GET action, this can/should be generalised and put into the commands class + if (!empty($_GET['udcentral_action']) && 'login' == $_GET['udcentral_action']) { + // auth_redirect() does not return, according to the documentation; but the code shows that it can + // auth_redirect(); + + if (!empty($_GET['login_id']) && is_numeric($_GET['login_id']) && !empty($_GET['login_key'])) { + $login_user = get_user_by('id', $_GET['login_id']); + + // THis is included so we can get $wp_version + include_once(ABSPATH.WPINC.'/version.php'); + + if (is_a($login_user, 'WP_User') || (version_compare($wp_version, '3.5', '<') && !empty($login_user->ID))) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- The variable is defined inside the ABSPATH.WPINC.'/version.php'. + // Allow site implementers to disable this functionality + $allow_autologin = apply_filters('updraftcentral_allow_autologin', true, $login_user); + if ($allow_autologin) { + $login_key = get_user_meta($login_user->ID, 'updraftcentral_login_key', true); + if (is_array($login_key) && !empty($login_key['created']) && $login_key['created'] > time() - 60 && !empty($login_key['key']) && $login_key['key'] == $_GET['login_key']) { + $autologin = empty($login_key['redirect_url']) ? network_admin_url() : $login_key['redirect_url']; + } + } + } + } + if (!empty($autologin)) { + // Allow use once only + delete_user_meta($login_user->ID, 'updraftcentral_login_key'); + $this->autologin_user($login_user, $autologin); + } + } + + add_filter('udrpc_action', array($this, 'udrpc_action'), 10, 5); + add_filter('updraftcentral_get_command_info', array($this, 'updraftcentral_get_command_info'), 10, 2); + add_filter('updraftcentral_get_updraftplus_status', array($this, 'get_updraftplus_status'), 10, 1); + + } + + /** + * Retrieves the UpdraftPlus plugin status whether it has been installed or activated + * + * @param mixed $data Default data to return + * @return array + */ + public function get_updraftplus_status($data) { + + // Handle cases of users who rename their plugin folders + if (class_exists('UpdraftPlus')) { + $data['is_updraftplus_installed'] = true; + $data['is_updraftplus_active'] = true; + } else { + if (!function_exists('get_plugins')) require_once(ABSPATH.'wp-admin/includes/plugin.php'); + $plugins = get_plugins(); + $key = 'updraftplus/updraftplus.php'; + + if (array_key_exists($key, $plugins)) { + $data['is_updraftplus_installed'] = true; + if (is_plugin_active($key)) $data['is_updraftplus_active'] = true; + } + } + + return $data; + } + + /** + * Retrieves command class information and includes class file if class + * is currently not available. + * + * @param mixed $response The default response to return if the submitted command does not exists + * @param string $command The command to parse and check + * @return array Contains the following command information "command_php_class", "class_prefix" and "command" + */ + public function updraftcentral_get_command_info($response, $command) { + if (!preg_match('/^([a-z0-9]+)\.(.*)$/', $command, $matches)) return $response; + $class_prefix = $matches[1]; + $command = $matches[2]; + + // Other plugins might have registered the filter rather later so we need to make + // sure that we get all the commands intended for UpdraftCentral. + $this->command_classes = apply_filters('updraftcentral_remotecontrol_command_classes', $this->command_classes); + + // We only handle some commands - the others, we let something else deal with + if (!isset($this->command_classes[$class_prefix])) return $response; + + $command_php_class = $this->command_classes[$class_prefix]; + $command_base_class_at = apply_filters('updraftcentral_command_base_class_at', UPDRAFTCENTRAL_CLIENT_DIR.'/commands.php'); + + if (!class_exists('UpdraftCentral_Commands')) include_once($command_base_class_at); + + // Second parameter has been passed since + do_action('updraftcentral_command_class_wanted', $command_php_class); + + if (!class_exists($command_php_class)) { + if (file_exists(UPDRAFTCENTRAL_CLIENT_DIR.'/modules/'.$class_prefix.'.php')) { + include_once(UPDRAFTCENTRAL_CLIENT_DIR.'/modules/'.$class_prefix.'.php'); + } + } + + return array( + 'command_php_class' => $command_php_class, + 'class_prefix' => $class_prefix, + 'command' => $command + ); + } + + /** + * In response to auto logging in the user; set a corresponding logged_in cookie to the $login_user_cookie class variable + * + * @param String $cookie Authentication cookie + * @param Integer $user_id User ID + * @param Integer $expiration The time the cookie expires as a UNIX timestamp + * @param String $scheme Cookie scheme used. Accepts 'auth', 'secure_auth', or 'logged_in' + */ + public function set_global_logged_in_cookie($cookie, $user_id, $expiration, $scheme) { + if ('logged_in' === $scheme) { + $this->auto_logged_in_cookie = $cookie; + } + return $cookie; + } + + /** + * Do verification before calling this method + * + * @param WP_User|Object $user user object for autologin + * @param boolean $redirect_url Redirect URL + */ + private function autologin_user($user, $redirect_url = false) { + if (!is_user_logged_in()) { + // $user = get_user_by('id', $user_id); + // Don't check that it's a WP_User - that's WP 3.5+ only + if (!is_object($user) || empty($user->ID)) return; + wp_set_current_user($user->ID, $user->user_login); + add_filter('auth_cookie', array($this, 'set_global_logged_in_cookie'), 10, 4); + wp_set_auth_cookie($user->ID); + remove_filter('auth_cookie', array($this, 'set_global_logged_in_cookie'), 10, 4); + do_action('wp_login', $user->user_login, $user); + } + if ($redirect_url) { + // the wp_set_auth_cookie() above uses setcookie() function but the corresponding LOGGED_IN_COOKIE variable is visible and can only be accessible on the next page load + // so we set the auth cookie into the superglobal $_COOKIE variable manually, we do this because the previously non logged-in user is now being auto-logged in and wp_create_nonce() needs the value of LOGGED_IN_COOKIE variable to produce a correct nonce + if ($this->auto_logged_in_cookie) $_COOKIE[LOGGED_IN_COOKIE] = $this->auto_logged_in_cookie; + $redirect_url = add_query_arg('restore_initiation_nonce', wp_create_nonce('updraftplus_udcentral_initiate_restore'), $redirect_url); + if ($this->auto_logged_in_cookie) unset($_COOKIE[LOGGED_IN_COOKIE]); + wp_safe_redirect($redirect_url); + exit; + } + } + + /** + * WP filter udrpc_action + * + * @param Array $response - the unfiltered response that will be returned + * @param String $command - the command being called + * @param Array $data - the parameters to the command + * @param String $key_name_indicator - the UC key that is in use + * @param Object $ud_rpc - the UDRP object + * + * @return Array - filtered response + */ + public function udrpc_action($response, $command, $data, $key_name_indicator, $ud_rpc) { + try { + + if (empty($this->receivers[$key_name_indicator])) return $response; + + // This can be used to detect an UpdraftCentral context + if (!defined('UPDRAFTCENTRAL_COMMAND')) define('UPDRAFTCENTRAL_COMMAND', $command); + + $this->initialise_listener_error_handling(); + + // UpdraftCentral needs this extra information especially now that the UpdraftCentral + // libraries can be totally embedded in other plugins (e.g. WP-Optimize, etc.) thus, + // that makes the UpdraftPlus plugin optional. + // + // This will give UpdraftCentral a proper way of disabling the backup feature + // for this site if the UpdraftPlus plugin is currently not installed or activated. + // + // In addition, we need to attached the host plugin who is handling the UpdraftCentral requests + global $updraftcentral_host_plugin; + $extra = apply_filters('updraftcentral_get_updraftplus_status', array( + 'is_updraftplus_installed' => false, + 'is_updraftplus_active' => false, + 'host_plugin' => $updraftcentral_host_plugin->plugin_name, + )); + + $command_info = apply_filters('updraftcentral_get_command_info', false, $command); + if (!$command_info) { + if (isset($response['data']) && is_array($response['data'])) $response['data']['extra'] = $extra; + return $response; + } + + $class_prefix = $command_info['class_prefix']; + $command = $command_info['command']; + $command_php_class = $command_info['command_php_class']; + + if (empty($this->commands[$class_prefix])) { + if (class_exists($command_php_class)) { + $this->commands[$class_prefix] = new $command_php_class($this); + } + } + + $command_class = isset($this->commands[$class_prefix]) ? $this->commands[$class_prefix] : new stdClass; + + if ('_' == substr($command, 0, 1) || !is_a($command_class, $command_php_class) || (!method_exists($command_class, $command) && !method_exists($command_class, '__call'))) { + if (defined('UPDRAFTCENTRAL_UDRPC_FORCE_DEBUG') && UPDRAFTCENTRAL_UDRPC_FORCE_DEBUG) error_log("Unknown RPC command received: ".$command); + + return $this->return_rpc_message(array('response' => 'rpcerror', 'data' => array('code' => 'unknown_rpc_command', 'data' => array('prefix' => $class_prefix, 'command' => $command, 'class' => $command_php_class)))); + } + + $extra_info = isset($this->extra_info[$key_name_indicator]) ? $this->extra_info[$key_name_indicator] : null; + + // Make it so that current_user_can() checks can apply + work + if (!empty($extra_info['user_id'])) wp_set_current_user($extra_info['user_id']); + + $this->current_udrpc = $ud_rpc; + + do_action('updraftcentral_listener_pre_udrpc_action', $command, $command_class, $data, $extra_info); + + // Allow the command class to perform any boiler-plate actions. + if (is_callable(array($command_class, '_pre_action'))) call_user_func(array($command_class, '_pre_action'), $command, $data, $extra_info); + + // Despatch + $msg = apply_filters('updraftcentral_listener_udrpc_action', call_user_func(array($command_class, $command), $data, $extra_info), $command_class, $class_prefix, $command, $data, $extra_info); + + if (is_callable(array($command_class, '_post_action'))) call_user_func(array($command_class, '_post_action'), $command, $data, $extra_info); + + do_action('updraftcentral_listener_post_udrpc_action', $command, $command_class, $data, $extra_info); + + if (isset($msg['data']) && is_array($msg['data'])) { + $msg['data']['extra'] = $extra; + } + + return $this->return_rpc_message($msg); + } catch (Exception $e) { + $log_message = 'PHP Fatal Exception error ('.get_class($e).') has occurred during UpdraftCentral command execution. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')'; + error_log($log_message); + + return $this->return_rpc_message(array('response' => 'rpcerror', 'data' => array('code' => 'rpc_fatal_error', 'data' => array('command' => $command, 'message' => $log_message)))); + // @codingStandardsIgnoreLine + } catch (Error $e) { + $log_message = 'PHP Fatal error ('.get_class($e).') has occurred during UpdraftCentral command execution. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')'; + error_log($log_message); + + return $this->return_rpc_message(array('response' => 'rpcerror', 'data' => array('code' => 'rpc_fatal_error', 'data' => array('command' => $command, 'message' => $log_message)))); + } + } + + public function get_current_udrpc() { + return $this->current_udrpc; + } + + private function initialise_listener_error_handling() { + global $updraftcentral_host_plugin; + + $this->host->error_reporting_stop_when_logged = true; + $error_levels = version_compare(PHP_VERSION, '8.4.0', '>=') ? E_ALL : E_ALL & ~E_STRICT; + set_error_handler(array($this->host, 'php_error'), $error_levels); + $this->php_events = array(); + @ob_start();// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Might be a bigger picture that I am missing but do we need to silence errors here? + add_filter($updraftcentral_host_plugin->get_logline_filter(), array($this, 'updraftcentral_logline'), 10, 4); + if (!$updraftcentral_host_plugin->get_debug_mode()) return; + } + + public function updraftcentral_logline($line, $nonce, $level, $uniq_id) {// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found -- Unused parameter is present because the method is used as a WP filter. + if ('notice' === $level && 'php_event' === $uniq_id) { + $this->php_events[] = $line; + } + return $line; + } + + public function return_rpc_message($msg) { + if (is_array($msg) && isset($msg['response']) && 'error' == $msg['response']) { + $this->host->log('Unexpected response code in remote communications: '.serialize($msg)); + } + + $caught_output = @ob_get_contents();// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Might be a bigger picture that I am missing but do we need to silence errors here? + @ob_end_clean();// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Might be a bigger picture that I am missing but do we need to silence errors here? + // If turning output-catching off, turn this on instead: + // $caught_output = ''; @ob_end_flush(); + + // If there's higher-level output buffering going on, then get rid of that + if (ob_get_level()) ob_end_clean(); + + if ($caught_output) { + if (!isset($msg['data'])) $msg['data'] = null; + $msg['data'] = array('caught_output' => $caught_output, 'previous_data' => $msg['data']); + $already_rearranged_data = true; + } + + if (!empty($this->php_events)) { + if (!isset($msg['data'])) $msg['data'] = null; + if (!empty($already_rearranged_data)) { + $msg['data']['php_events'] = array(); + } else { + $msg['data'] = array('php_events' => array(), 'previous_data' => $msg['data']); + } + foreach ($this->php_events as $logline) { + $msg['data']['php_events'][] = $logline; + } + } + restore_error_handler(); + + return $msg; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/analytics.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/analytics.php new file mode 100755 index 00000000..841fd16f --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/analytics.php @@ -0,0 +1,440 @@ +auth_endpoint = defined('UPDRAFTPLUS_GOOGLE_ANALYTICS_CALLBACK_URL') ? UPDRAFTPLUS_GOOGLE_ANALYTICS_CALLBACK_URL : 'https://auth.updraftplus.com/auth/googleanalytics'; + $this->client_id = defined('UPDRAFTPLUS_GOOGLE_ANALYTICS_CLIENT_ID') ? UPDRAFTPLUS_GOOGLE_ANALYTICS_CLIENT_ID : '306245874349-6s896c3tjpra26ns3dpplhqcl6rv6qlb.apps.googleusercontent.com'; + + // Set transient expiration - default for 24 hours + $this->expiration = 86400; + } + + /** + * Checks whether Google Analytics (GA) is installed or setup + * + * N.B. This check assumes GA is installed either using "wp_head" or "wp_footer" (e.g. attached + * to the or somewhere before ). It does not recursively check all the pages + * of the website to find if GA is installed on each or one of those pages, but only on the main/root page. + * + * @return array $result An array containing "ga_installed" property which returns "true" if GA (Google Analytics) is installed, "false" otherwise. + */ + public function ga_checker() { + + try { + + // Retrieves the tracking code/id if available + $tracking_id = $this->get_tracking_id(); + $installed = true; + + // If tracking code/id is currently not available then we + // parse the needed information from the buffered content through + // the "wp_head" and "wp_footer" hooks. + if (false === $tracking_id) { + $info = $this->extract_tracking_id(); + + $installed = $info['installed']; + $tracking_id = $info['tracking_id']; + } + + // Get access token to be use to generate the report. + $access_token = $this->_get_token(); + + if (empty($access_token)) { + // If we don't get a valid access token then that would mean + // the access has been revoked by the user or UpdraftCentral was not authorized yet + // to access the user's analytics data, thus, we're clearing + // any previously stored user access so we're doing some housekeeping here. + $this->clear_user_access(); + } + + // Wrap and combined information for the requesting + // client's consumption + $result = array( + 'ga_installed' => $installed, + 'tracking_id' => $tracking_id, + 'client_id' => $this->client_id, + 'redirect_uri' => $this->auth_endpoint, + 'scope' => $this->scope, + 'access_token' => $access_token, + 'endpoint' => $this->endpoint + ); + + } catch (Exception $e) { + $result = array('error' => true, 'message' => 'generic_response_error', 'values' => array($e->getMessage())); + } + + return $this->_response($result); + } + + /** + * Extracts Google Tracking ID from contents rendered through the "wp_head" and "wp_footer" action hooks + * + * @internal + * @return array $result An array containing the result of the extraction. + */ + private function extract_tracking_id() { + + // Define result array + $result = array(); + + // Retrieve header content + ob_start(); + do_action('wp_head'); + $header_content = ob_get_clean(); + + // Extract analytics information if available. + $output = $this->parse_content($header_content); + $result['installed'] = $output['installed']; + $result['tracking_id'] = $output['tracking_id']; + + // If it was not found, then now try the footer + if (empty($result['tracking_id'])) { + // Retrieve footer content + ob_start(); + do_action('wp_footer'); + $footer_content = ob_get_clean(); + $output = $this->parse_content($footer_content); + $result['installed'] = $output['installed']; + $result['tracking_id'] = $output['tracking_id']; + } + + if (!empty($result['tracking_id'])) { + set_transient($this->tracking_id_key, $result['tracking_id'], $this->expiration); + } + + return $result; + } + + /** + * Gets access token + * + * Validates whether the system currently have a valid token to use when connecting to Google Analytics API. + * If not, then it will send a token request based on the authorization code we stored during the + * authorization phase. Otherwise, it will return an empty token. + * + * @return array $result An array containing the Google Analytics API access token. + */ + public function get_access_token() { + + try { + + // Loads or request a valid token to use + $access_token = $this->_get_token(); + + if (!empty($access_token)) { + $result = array('access_token' => $access_token); + } else { + $result = array('error' => true, 'message' => 'ga_token_retrieval_failed', 'values' => array()); + } + + } catch (Exception $e) { + $result = array('error' => true, 'message' => 'generic_response_error', 'values' => array($e->getMessage())); + } + + return $this->_response($result); + } + + /** + * Clears any previously stored user access + * + * @return bool + */ + public function clear_user_access() { + return delete_option($this->access_key); + } + + /** + * Saves user is and access token received from the auth server + * + * @param array $query Parameter array containing the user id and access token from the auth server. + * @return array $result An array containing a "success" or "failure" message as a result of the current process. + */ + public function save_user_access($query) { + + try { + + $token = get_option($this->access_key, false); + $result = array(); + + if (false === $token) { + $token = array( + 'user_id' => base64_decode(urldecode($query['user_id'])), + 'access_token' => base64_decode(urldecode($query['access_token'])) + ); + + if (false !== update_option($this->access_key, $token)) { + $result = array('error' => false, 'message' => 'ga_access_saved', 'values' => array()); + } else { + $result = array('error' => true, 'message' => 'ga_access_saving_failed', 'values' => array($query['access_token'])); + } + } + + } catch (Exception $e) { + $result = array('error' => true, 'message' => 'generic_response_error', 'values' => array($e->getMessage())); + } + + return $this->_response($result); + } + + /** + * Saves the tracking code/id manually (user input) + * + * @param array $query Parameter array containing the tracking code/id to save. + * @return array $result An array containing the result of the process. + */ + public function save_tracking_id($query) { + try { + $tracking_id = $query['tracking_id']; + $saved = false; + + if (!empty($tracking_id)) { + $saved = set_transient($this->tracking_id_key, $tracking_id, $this->expiration); + } + + $result = array('saved' => $saved); + } catch (Exception $e) { + $result = array('error' => true, 'message' => 'generic_response_error', 'values' => array($e->getMessage())); + } + + return $this->_response($result); + } + + /** + * Retrieves any available access token either previously saved info or + * from a new request from the Google Server. + * + * @internal + * @return string $authorization_code + */ + private function _get_token() { + + // Retrieves the tracking code/id if available + $tracking_id = $this->get_tracking_id(); + $access_token = ''; + + $token = get_option($this->access_key, false); + if (false !== $token) { + $access_token = isset($token['access_token']) ? $token['access_token'] : ''; + $user_id = isset($token['user_id']) ? $token['user_id'] : ''; + + if ((!empty($access_token) && !$this->_token_valid($access_token)) || (!empty($user_id) && empty($access_token) && !empty($tracking_id))) { + if (!empty($user_id)) { + $args = array( + 'headers' => apply_filters('updraftplus_auth_headers', array()) + ); + + $response = wp_remote_get($this->auth_endpoint.'?user_id='.$user_id.'&code=ud_googleanalytics_code', $args); + if (is_wp_error($response)) { + throw new Exception($response->get_error_message()); // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- The escaping should be happening when the exception is printed + } else { + if (is_array($response)) { + + $body = json_decode($response['body'], true); + $token_response = array(); + + if (is_array($body) && !isset($body['error'])) { + $token_response = json_decode(base64_decode($body[0]), true); + } + + if (is_array($token_response) && isset($token_response['access_token'])) { + $access_token = $token_response['access_token']; + } else { + // If we don't get any valid response then that would mean that the + // permission was already revoked. Thus, we need to re-authorize the + // user before using the analytics feature once again. + $access_token = ''; + } + + $token['access_token'] = $access_token; + update_option($this->access_key, $token); + } + } + } + } + } + + return $access_token; + } + + /** + * Verifies whether the access token is still valid for use + * + * @internal + * @param string $token The access token to be check and validated + * @return bool + * @throws Exception If an error has occurred while connecting to the Google Server. + */ + private function _token_valid($token) { + + $response = wp_remote_get($this->token_info_endpoint.'?access_token='.$token); + if (is_wp_error($response)) { + throw new Exception($response->get_error_message()); // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- The escaping should be happening when the exception is printed + } else { + if (is_array($response)) { + $response = json_decode($response['body'], true); + if (!empty($response)) { + if (!isset($response['error']) && !isset($response['error_description'])) { + return true; + } + } + } + } + + return false; + } + + /** + * Parses and extracts the google analytics information (NEEDED) + * + * @internal + * @param string $content The content to parse + * @return array An array containing the status of the process along with the tracking code/id + */ + private function parse_content($content) { + + $installed = false; + $gtm_installed = false; + $tracking_id = ''; + $script_file_found = false; + $tracking_id_found = false; + + // Pull google analytics script file(s) + preg_match_all('/]*>([\s\S]*?)<\/script>/i', $content, $scripts); + for ($i=0; $i < count($scripts[0]); $i++) { + // Check for Google Analytics file + if (stristr($scripts[0][$i], 'ga.js') || stristr($scripts[0][$i], 'analytics.js')) { + $script_file_found = true; + } + + // Check for Google Tag Manager file + // N.B. We are not checking for GTM but this check will be useful when + // showing the notice to the user if we haven't found Google Analytics + // directly being installed on the page. + if (stristr($scripts[0][$i], 'gtm.js')) { + $gtm_installed = true; + } + } + + // Pull tracking code + preg_match_all('/UA-[0-9]{5,}-[0-9]{1,}/i', $content, $codes); + if (count($codes) > 0) { + if (!empty($codes[0])) { + $tracking_id_found = true; + $tracking_id = $codes[0][0]; + } + } + + // If we found both the script and the tracking code then it is safe + // to say that Google Analytics (GA) is installed. Thus, we're returning + // "true" as a response. + if ($script_file_found && $tracking_id_found) { + $installed = true; + } + + // Return result of process. + return array( + 'installed' => $installed, + 'gtm_installed' => $gtm_installed, + 'tracking_id' => $tracking_id + ); + } + + /** + * Retrieves the "analytics_tracking_id" transient + * + * @internal + * @return mixed Returns the value of the saved transient. Returns "false" if the transient does not exist. + */ + private function get_tracking_id() { + return get_transient($this->tracking_id_key); + } + + + /** + * Returns the current tracking id + * + * @return array $result An array containing the Google Tracking ID. + */ + public function get_current_tracking_id() { + try { + + // Get current site transient stored for this key + $tracking_id = get_transient($this->tracking_id_key); + + // Checks whether we have a valid token + $access_token = $this->_get_token(); + if (empty($access_token)) { + $tracking_id = ''; + } + + if (false === $tracking_id) { + $result = $this->extract_tracking_id(); + } else { + $result = array( + 'installed' => true, + 'tracking_id' => $tracking_id + ); + } + + } catch (Exception $e) { + $result = array('error' => true, 'message' => 'generic_response_error', 'values' => array($e->getMessage())); + } + + return $this->_response($result); + } + + /** + * Clears user access from database + * + * @return array $result An array containing the "Remove" confirmation whether the action succeeded or not. + */ + public function remove_user_access() { + try { + + // Clear user access + $is_cleared = $this->clear_user_access(); + + if (false !== $is_cleared) { + $result = array('removed' => true); + } else { + $result = array('error' => true, 'message' => 'user_access_remove_failed', 'values' => array()); + } + + } catch (Exception $e) { + $result = array('error' => true, 'message' => 'generic_response_error', 'values' => array($e->getMessage())); + } + + return $this->_response($result); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/backups.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/backups.php new file mode 100755 index 00000000..d6d95e84 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/backups.php @@ -0,0 +1,391 @@ +switched = switch_to_blog($blog_id); + } + } + + /** + * Function that gets called after every action + * + * @param string $command a string that corresponds to UDC command to call a certain method for this class. + * @param array $data an array of data post or get fields + * @param array $extra_info extrainfo use in the udrpc_action, e.g. user_id + * + * link to udrpc_action main function in class UpdraftCentral_Listener + */ + public function _post_action($command, $data, $extra_info) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Unused parameter is present because the caller from UpdraftCentral_Listener class uses 3 arguments. + // Here, we're restoring to the current (default) blog before we switched + if ($this->switched) restore_current_blog(); + } + + /** + * Retrieves the UpdraftPlus plugin status, UpdraftVault storage usage status, Next backup + * schedule, etc. Used primarily by UpdraftCentral background process. + * + * @return array + */ + public function get_status() { + + if (!current_user_can('manage_options')) { + $response = array( + 'status' => 'error', + 'error_code' => 'insufficient_permission', + ); + } else { + + if (!function_exists('get_mu_plugins')) include_once(ABSPATH.'wp-admin/includes/plugin.php'); + $mu_plugins = get_mu_plugins(); + + $is_premium = false; + if (defined('UPDRAFTPLUS_DIR') && file_exists(UPDRAFTPLUS_DIR.'/udaddons')) $is_premium = true; + + // Set default response + $response = array( + 'updraftplus_version' => '', + 'is_premium' => $is_premium, + 'installed' => false, + 'active' => false, + 'backup_count' => 0, + 'has_mu_plugins' => !empty($mu_plugins) ? true : false, + 'last_backup' => array( + 'backup_nonce' => '', + 'has_errors' => false, + 'has_warnings' => false, + 'has_succeeded' => false, + ), + 'updraftvault' => array( + 'site_connected' => false, + 'storage' => array('quota_used' => '0 MB', 'quota' => '0 MB', 'percentage_usage' => '0.0%'), + ), + 'meta' => array(), + ); + + if (class_exists('UpdraftPlus')) { + global $updraftplus; + + $response['updraftplus_version'] = $updraftplus->version; + $response['updraftvault'] = $this->get_updraftvault_status(); + $response['installed'] = true; + $response['active'] = true; + $response['meta'] = $this->get_filesystem_credentials_info(); + + $schedule = $this->get_next_backup_schedule(); + if ($schedule) { + $response['next_backup_schedule'] = $schedule; + } + + $backup_history = UpdraftPlus_Backup_History::add_jobdata(UpdraftPlus_Backup_History::get_history()); + + $response['backup_count'] = count($backup_history); + + $updraft_last_backup = UpdraftPlus_Options::get_updraft_option('updraft_last_backup'); + if ($updraft_last_backup) { + $response['last_backup']['backup_nonce'] = $updraft_last_backup['backup_nonce']; + if (isset($updraft_last_backup['backup_time'])) { + $response['last_backup']['backup_date'] = gmdate('n/j/Y', $updraft_last_backup['backup_time']); + $response['last_backup']['backup_time'] = $updraft_last_backup['backup_time']; + } + + $errors = 0; + $warnings = 0; + + if (is_array($updraft_last_backup['errors'])) { + foreach ($updraft_last_backup['errors'] as $err) { + $level = (is_array($err)) ? $err['level'] : 'error'; + if ('warning' == $level) { + $warnings++; + } elseif ('error' == $level) { + $errors++; + } + } + } + + if ($errors > 0) $response['last_backup']['has_errors'] = true; + if ($warnings > 0) $response['last_backup']['has_warnings'] = true; + if (isset($updraft_last_backup['success']) && $updraft_last_backup['success']) $response['last_backup']['has_succeeded'] = true; + } + + } else { + if (!function_exists('get_plugins')) require_once(ABSPATH.'wp-admin/includes/plugin.php'); + $plugins = get_plugins(); + $key = 'updraftplus/updraftplus.php'; + + if (array_key_exists($key, $plugins)) { + $response['installed'] = true; + if (is_plugin_active($key)) $response['active'] = true; + } + } + } + + return $this->_response($response); + } + + /** + * Retrieves the next backup schedule for Files and Database backups + * + * @return string + */ + private function get_next_backup_schedule() { + + // Get the next (nearest) scheduled backups + $files = wp_next_scheduled('updraft_backup'); + $db = wp_next_scheduled('updraft_backup_database'); + + if ($files && $db) { + $timestamp = min($files, $db); // Get the nearest schedule among the two schedules + } elseif ($files && !$db) { + $timestamp = $files; + } elseif (!$files && $db) { + $timestamp = $db; + } else { + $timestamp = null; + } + + if (!empty($timestamp)) { + return gmdate('g:i A - D', $timestamp); + } + + return false; + } + + /** + * Retrieves the UpdrafVault storage usage status + * + * @return array + */ + private function get_updraftvault_status() { + + if (!class_exists('UpdraftCentral_UpdraftVault_Commands')) { + include_once(UPDRAFTPLUS_DIR.'/includes/updraftvault.php'); + } + + $updraftvault = new UpdraftCentral_UpdraftVault_Commands($this->rc); + $creds = $updraftvault->get_credentials(); + + $site_connected = false; + $storage = array('quota_used' => '0 MB', 'quota' => '0 MB', 'percentage_usage' => '0.0%'); + $remote_service = false; + + if (isset($creds['data'])) { + if (!isset($creds['data']['error']) && isset($creds['data']['accesskey'])) { + $site_connected = true; + + $storage_objects_and_ids = UpdraftPlus_Storage_Methods_Interface::get_storage_objects_and_ids(array('updraftvault')); + + if (isset($storage_objects_and_ids['updraftvault']['instance_settings'])) { + $instance_settings = $storage_objects_and_ids['updraftvault']['instance_settings']; + $instance_id = key($instance_settings); + $opts = $instance_settings[$instance_id]; + + if (!class_exists('UpdraftPlus_BackupModule_updraftvault')) { + include_once(UPDRAFTPLUS_DIR.'/methods/updraftvault.php'); + } + + $vault = new UpdraftPlus_BackupModule_updraftvault(); + $vault->set_options($opts, false, $instance_id); + + $quota_root = $opts['quota_root']; + $quota = $opts['quota']; + + if (empty($quota_root)) { + // This next line is wrong: it lists the files *in this site's sub-folder*, rather than the whole Vault + $current_files = $vault->listfiles(''); + } else { + $current_files = $vault->listfiles_with_path($quota_root, '', true); + } + + if (!is_wp_error($current_files) && is_array($current_files)) { + $quota_used = 0; + foreach ($current_files as $file) { + $quota_used += $file['size']; + } + + $storage = array( + 'quota_used' => round($quota_used / 1048576, 1).' MB', + 'quota' => round($quota / 1048576, 1).' MB', + 'percentage_usage' => sprintf('%.1f', 100*$quota_used / $quota).'%', + ); + + $remote_service = array( + 'name' => 'updraft_include_remote_service_updraftvault', + 'value' => $instance_id, + ); + } + } + } + } + + return array( + 'site_connected' => $site_connected, + 'storage' => $storage, + 'remote_service' => $remote_service, + ); + } + + /** + * Retrieves information whether filesystem credentials (e.g. FTP/SSH) are required + * when updating plugins + * + * @return array + */ + private function get_filesystem_credentials_info() { + + if (!function_exists('get_filesystem_method')) { + include_once(ABSPATH.'/wp-admin/includes/file.php'); + } + + $filesystem_method = get_filesystem_method(array(), WP_PLUGIN_DIR); + + ob_start(); + $filesystem_credentials_are_stored = request_filesystem_credentials(site_url()); + $filesystem_form = strip_tags(ob_get_contents(), '

            '); + ob_end_clean(); + + $request_filesystem_credentials = ('direct' != $filesystem_method && !$filesystem_credentials_are_stored); + + return array( + 'request_filesystem_credentials' => $request_filesystem_credentials, + 'filesystem_form' => base64_encode($filesystem_form), + ); + } + + /** + * Retrieves the backup progress in terms of entities completed. Used primarily by UpdraftCentral + * for polling backup progress in the background. + * + * @param array $params Submitted arguments for the current request + * @return array + */ + public function get_backup_progress($params) { + + $nonce = isset($params['nonce']) ? $params['nonce'] : false; + $response = array('nonce' => $params['nonce']); + + if (!current_user_can('manage_options')) { + $response['status'] = 'error'; + $response['error_code'] = 'insufficient_permission'; + } else { + global $updraftplus; + + if ($nonce && $updraftplus && is_a($updraftplus, 'UpdraftPlus')) { + + // Check the job is not still running. + $jobdata = $updraftplus->jobdata_getarray($nonce); + + if (!empty($jobdata)) { + $response['status'] = 'in-progress'; + + $file_entities = 0; + $db_entities = 0; + $processed = 0; + + if (isset($jobdata['backup_database']) && 'no' != $jobdata['backup_database']) { + $backup_database = $jobdata['backup_database']; + $db_entities += count($backup_database); + + foreach ($backup_database as $whichdb => $info) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- In this check we only need the status contained in the $info for now. + $status = $info; // For default: 'wp' + if (is_array($info)) { + $status = $info['status']; + } + + if ('finished' == $status) { + $processed++; + } + } + } + + if (isset($jobdata['backup_files']) && 'no' != $jobdata['backup_files']) { + $file_entities = count($jobdata['job_file_entities']); + + $backup_files = $jobdata['backup_files']; + if ('finished' == $backup_files) { + $processed += $file_entities; + } elseif (isset($jobdata['filecreating_substatus'])) { + $substatus = $jobdata['filecreating_substatus']; + $processed += max(0, intval($substatus['i']) - 1); + } + } + + $response['progress'] = array( + 'file_entities' => $file_entities, + 'db_entities' => $db_entities, + 'total_entities' => $file_entities+$db_entities, + 'processed' => $processed, + 'percentage' => floor(($processed/($file_entities+$db_entities))*100), + 'nonce' => $nonce, + ); + + UpdraftPlus_Options::update_updraft_option('updraft_central_last_backup_progress', $response['progress'], false); + } else { + $last_backup = UpdraftPlus_Options::get_updraft_option('updraft_last_backup'); + if ($nonce == $last_backup['backup_nonce']) { + $response['status'] = 'finished'; + $response['progress'] = array('percentage' => 100); + $response['progress']['errors'] = $last_backup['errors']; + $response['progress']['backup_time'] = $last_backup['backup_time']; + $response['progress']['completed_time'] = gmdate('g:ia', $last_backup['backup_time']); + $response['progress']['completed_date'] = gmdate('M d, Y', $last_backup['backup_time']); + + $errors = 0; + $warnings = 0; + + if (!empty($last_backup['errors']) && is_array($last_backup['errors'])) { + foreach ($last_backup['errors'] as $err) { + $level = (is_array($err)) ? $err['level'] : 'error'; + if ('warning' == $level) { + $warnings++; + } elseif ('error' == $level) { + $errors++; + } + } + } + + $response['progress']['has_errors'] = ($errors > 0) ? true : false; + $response['progress']['has_warnings'] = ($warnings > 0) ? true : false; + } else { + // We might be too early to check the `updraft_last_backup` thus, we'll + // give it a few rounds to check by setting the status to "in-progress" + // and returning the last backup progress (if applicable). + $last_progress = UpdraftPlus_Options::get_updraft_option('updraft_central_last_backup_progress'); + + $response['status'] = 'in-progress'; + if (!empty($last_progress) && isset($last_progress['nonce'])) { + $response['progress'] = $last_progress; + + if ($nonce == $last_progress['nonce']) { + UpdraftPlus_Options::delete_updraft_option('updraft_central_last_backup_progress'); + } + } + } + } + } + } + + return $this->_response($response); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/comments.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/comments.php new file mode 100755 index 00000000..26f97983 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/comments.php @@ -0,0 +1,842 @@ + 'ID', + 'order' => 'DESC', + 'type' => $query['type'], + 'status' => $query['status'], + 'search' => esc_attr($query['search']), + ); + + $query = new WP_Comment_Query; + $found_comments = $query->query($args); + + $comments = array(); + foreach ($found_comments as $comment) { + + // We're returning a collection of comment in an array, + // in sync with the originator of the request on the ui side + // so, we're pulling it one by one into the array before + // returning it. + + if (!in_array($comment, $comments)) { + array_push($comments, $comment); + } + } + + return $comments; + } + + /** + * The _calculate_pages function generates and builds the pagination links + * based on the current search parameters/filters. Please see _search_comments + * for the breakdown of these parameters. + * + * @param array $query Query to generate pagination links + * @return array + */ + private function _calculate_pages($query) { + $per_page_options = array(10, 20, 30, 40, 50); + + if (!empty($query)) { + if (!empty($query['search'])) { + return array( + 'page_count' => 1, + 'page_no' => 1 + ); + } + + $pages = array(); + $page_query = new WP_Comment_Query; + + // Here, we're pulling the comments based on the + // two parameters namely type and status. + // + // The number of results/comments found will then + // be use to compute for the number of pages to be + // displayed as navigation links when browsing all + // comments from the frontend. + + $comments = $page_query->query(array( + 'type' => $query['type'], + 'status' => $query['status'] + )); + + $total_comments = count($comments); + $page_count = ceil($total_comments / $query['per_page']); + + if ($page_count > 1) { + for ($i = 0; $i < $page_count; $i++) { + if ($i + 1 == $query['page_no']) { + $paginator_item = array( + 'value' => $i+1, + 'setting' => 'disabled' + ); + } else { + $paginator_item = array( + 'value' => $i+1 + ); + } + array_push($pages, $paginator_item); + } + + if ($query['page_no'] >= $page_count) { + $page_next = array( + 'value' => $page_count, + 'setting' => 'disabled' + ); + } else { + $page_next = array( + 'value' => $query['page_no'] + 1 + ); + } + + if (1 === $query['page_no']) { + $page_prev = array( + 'value' => 1, + 'setting' => 'disabled' + ); + } else { + $page_prev = array( + 'value' => $query['page_no'] - 1 + ); + } + + return array( + 'page_no' => $query['page_no'], + 'per_page' => $query['per_page'], + 'page_count' => $page_count, + 'pages' => $pages, + 'page_next' => $page_next, + 'page_prev' => $page_prev, + 'total_results' => $total_comments, + 'per_page_options' => $per_page_options + ); + + } else { + return array( + 'page_no' => $query['page_no'], + 'per_page' => $query['per_page'], + 'page_count' => $page_count, + 'total_results' => $total_comments, + 'per_page_options' => $per_page_options + ); + } + } else { + return array( + 'per_page_options' => $per_page_options + ); + } + } + + /** + * The get_blog_sites function pulls blog sites available for the current WP instance. + * If Multisite is enabled on the server, then sites under the network will be pulled, otherwise, it will return an empty array. + * + * @return array + */ + private function get_blog_sites() { + + if (!is_multisite()) return array(); + + // Initialize array container + $sites = $network_sites = array(); + + // Check to see if latest get_sites (available on WP version >= 4.6) function is + // available to pull any available sites from the current WP instance. If not, then + // we're going to use the fallback function wp_get_sites (for older version). + + if (function_exists('get_sites') && class_exists('WP_Site_Query')) { + $network_sites = get_sites(); + } else { + if (function_exists('wp_get_sites')) { + $network_sites = wp_get_sites(); + } + } + + // We only process if sites array is not empty, otherwise, bypass + // the next block. + + if (!empty($network_sites)) { + foreach ($network_sites as $site) { + + // Here we're checking if the site type is an array, because + // we're pulling the blog_id property based on the type of + // site returned. + // get_sites returns an array of object, whereas the wp_get_sites + // function returns an array of array. + + $blog_id = (is_array($site)) ? $site['blog_id'] : $site->blog_id; + + + // We're saving the blog_id and blog name as an associative item + // into the sites array, that will be used as "Sites" option in + // the frontend. + + $sites[$blog_id] = get_blog_details($blog_id)->blogname; + } + } + + return $sites; + } + + /** + * The get_wp_option function pulls current blog options + * from the database using either following functions: + * - get_blog_option (for multisite) + * - get_option (for ordinary blog) + * + * @param array $blog_id This is the specific blog ID + * @param array $setting specifies settings + * @return array + */ + private function _get_wp_option($blog_id, $setting) { + return is_multisite() ? get_blog_option($blog_id, $setting) : get_option($setting); + } + + /** + * The get_comments function pull all the comments from the database + * based on the current search parameters/filters. Please see _search_comments + * for the breakdown of these parameters. + * + * @param array $query Specific query to pull comments + * @return array + */ + public function get_comments($query) { + + // Here, we're getting the current blog id. If blog id + // is passed along with the parameters then we override + // that current (default) value with the parameter blog id value. + + $blog_id = get_current_blog_id(); + if (isset($query['blog_id'])) $blog_id = $query['blog_id']; + + + // Here, we're switching to the actual blog that we need + // to pull comments from. + + $switched = false; + if (function_exists('switch_to_blog')) { + $switched = switch_to_blog($blog_id); + } + + if (!empty($query['search'])) { + // If a search keyword is present, then we'll call the _search_comments + // function to process the query. + + $comments = $this->_search_comments($query); + } else { + // Set default parameter values if the designated + // parameters are empty. + + if (empty($query['per_page'])) { + $query['per_page'] = 10; + } + if (empty($query['page_no'])) { + $query['page_no'] = 1; + } + if (empty($query['type'])) { + $query['type'] = ''; + } + if (empty($query['status'])) { + $query['status'] = ''; + } + + // Since WP_Comment_Query parameters doesn't have a "page" attribute, we + // need to compute for the offset to get the exact content based on the + // current page and the number of items per page. + + $offset = ((int) $query['page_no'] - 1) * (int) $query['per_page']; + $args = array( + 'orderby' => 'ID', + 'order' => 'DESC', + 'number' => $query['per_page'], + 'offset' => $offset, + 'type' => $query['type'], + 'status' => $query['status'] + ); + + $comments_query = new WP_Comment_Query; + $comments = $comments_query->query($args); + } + + // If no comments are found based on the current query then + // we return with error. + + if (empty($comments)) { + $result = array('message' => 'comments_not_found'); + return $this->_response($result); + } + + // Otherwise, we're going to process each comment + // before we return it to the one issuing the request. + // + // Process in the sense that we add additional related info + // such as the post tile where the comment belongs to, the + // comment status, a formatted date field, and to which parent comment + // does the comment was intended to be as a reply. + + foreach ($comments as &$comment) { + $comment = get_comment($comment->comment_ID, ARRAY_A); + if ($comment) { + $post = get_post($comment['comment_post_ID']); + + if ($post) $comment['in_response_to'] = $post->post_title; + if (!empty($comment['comment_parent'])) { + $parent_comment = get_comment($comment['comment_parent'], ARRAY_A); + if ($parent_comment) $comment['in_reply_to'] = $parent_comment['comment_author']; + } + + // We're formatting the comment_date to be exactly the same + // with that of WP Comments table (e.g. 2016/12/21 at 10:30 PM) + + $comment['comment_date'] = date('Y/m/d \a\t g:i a', strtotime($comment['comment_date'])); + + $status = wp_get_comment_status($comment['comment_ID']); + if ($status) { + $comment['comment_status'] = $status; + } + } + } + + // We return the following to the one issuing + // the request. + + $result = array( + 'comments' => $comments, + 'paging' => $this->_calculate_pages($query) + ); + + + // Here, we're restoring to the current (default) blog before we + // do the switched. + + if (function_exists('restore_current_blog') && $switched) { + restore_current_blog(); + } + + return $this->_response($result); + } + + /** + * The get_comment_filters function builds a array of options + * to be use as filters for the search function on the frontend. + */ + public function get_comment_filters() { + // Options for comment_types field + $comment_types = apply_filters('admin_comment_types_dropdown', array( + 'comment' => __('Comments'),// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. + 'pings' => __('Pings'),// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. + )); + + // Options for comment_status field + $comment_statuses = array( + 'approve' => __('Approve'),// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. + 'hold' => __('Hold or Unapprove', 'updraftplus'), + 'trash' => __('Trash', 'updraftplus'), + 'spam' => __('Spam', 'updraftplus'), + ); + + // Pull sites options if available. + $sites = $this->get_blog_sites(); + + $result = array( + 'sites' => $sites, + 'types' => $comment_types, + 'statuses' => $comment_statuses, + 'paging' => $this->_calculate_pages(null), + ); + + return $this->_response($result); + } + + /** + * The get_settings function pulls the current discussion settings + * option values. + * + * @param array $params Passing specific params for getting current discussion settings + * @return array + */ + public function get_settings($params) { + global $updraftcentral_main; + + // Here, we're getting the current blog id. If blog id + // is passed along with the parameters then we override + // that current (default) value with the parameter blog id value. + + $blog_id = get_current_blog_id(); + if (isset($params['blog_id'])) $blog_id = $params['blog_id']; + + + // If user does not have sufficient privileges to manage and edit + // WP options then we return with error. + + if (!current_user_can_for_blog($blog_id, 'manage_options')) { + $result = array('error' => true, 'message' => 'insufficient_permission'); + return $this->_response($result); + } + + // Pull sites options if available. + $sites = $this->get_blog_sites(); + + // Wrap current discussion settings values into an array item + // named settings. + + $result = array( + 'settings' => array( + 'default_pingback_flag' => $this->_get_wp_option($blog_id, 'default_pingback_flag'), + 'default_ping_status' => $this->_get_wp_option($blog_id, 'default_ping_status'), + 'default_comment_status' => $this->_get_wp_option($blog_id, 'default_comment_status'), + 'require_name_email' => $this->_get_wp_option($blog_id, 'require_name_email'), + 'comment_registration' => $this->_get_wp_option($blog_id, 'comment_registration'), + 'close_comments_for_old_posts' => $this->_get_wp_option($blog_id, 'close_comments_for_old_posts'), + 'close_comments_days_old' => $this->_get_wp_option($blog_id, 'close_comments_days_old'), + 'thread_comments' => $this->_get_wp_option($blog_id, 'thread_comments'), + 'thread_comments_depth' => $this->_get_wp_option($blog_id, 'thread_comments_depth'), + 'page_comments' => $this->_get_wp_option($blog_id, 'page_comments'), + 'comments_per_page' => $this->_get_wp_option($blog_id, 'comments_per_page'), + 'default_comments_page' => $this->_get_wp_option($blog_id, 'default_comments_page'), + 'comment_order' => $this->_get_wp_option($blog_id, 'comment_order'), + 'comments_notify' => $this->_get_wp_option($blog_id, 'comments_notify'), + 'moderation_notify' => $this->_get_wp_option($blog_id, 'moderation_notify'), + 'comment_moderation' => $this->_get_wp_option($blog_id, 'comment_moderation'), + 'comment_max_links' => $this->_get_wp_option($blog_id, 'comment_max_links'), + 'moderation_keys' => $this->_get_wp_option($blog_id, 'moderation_keys'), + ), + 'sites' => $sites, + ); + + $wp_version = $updraftcentral_main->get_wordpress_version(); + if (version_compare($wp_version, '5.5.0', '<')) { + $result['settings']['comment_whitelist'] = $this->_get_wp_option($blog_id, 'comment_whitelist'); + $result['settings']['blacklist_keys'] = $this->_get_wp_option($blog_id, 'blacklist_keys'); + } else { + $result['settings']['comment_previously_approved'] = $this->_get_wp_option($blog_id, 'comment_previously_approved'); + $result['settings']['disallowed_keys'] = $this->_get_wp_option($blog_id, 'disallowed_keys'); + } + + return $this->_response($result); + } + + /** + * The update_settings function updates the discussion settings + * basing on the user generated content/option from the frontend + * form. + * + * @param array $params Specific params to update settings based on discussion + * @return array + */ + public function update_settings($params) { + + // Extract settings values from passed parameters. + $settings = $params['settings']; + + // Here, we're getting the current blog id. If blog id + // is passed along with the parameters then we override + // that current (default) value with the parameter blog id value. + + $blog_id = get_current_blog_id(); + if (isset($params['blog_id'])) $blog_id = $params['blog_id']; + + + // If user does not have sufficient privileges to manage and edit + // WP options then we return with error. + + if (!current_user_can_for_blog($blog_id, 'manage_options')) { + $result = array('error' => true, 'message' => 'insufficient_permission'); + return $this->_response($result); + } + + // Here, we're sanitizing the input fields before we save them to the database + // for safety and security reason. The "explode" and "implode" functions are meant + // to maintain the line breaks associated with a textarea input/value. + + foreach ($settings as $key => $value) { + + // We're using update_blog_option and update_option altogether to update the current + // discussion settings. + + if (is_multisite()) { + update_blog_option($blog_id, $key, implode("\n", array_map('sanitize_text_field', explode("\n", $value)))); + } else { + update_option($key, implode("\n", array_map('sanitize_text_field', explode("\n", $value)))); + } + } + + // We're not checking for errors here, but instead we're directly returning a success (error = false) + // status always, because WP's update_option will return fail if values were not changed, meaning + // previous values were not changed by the user's current request, not an actual exception thrown. + // Thus, giving a false positive message or report to the frontend. + + $result = array('error' => false, 'message' => 'settings_updated', 'values' => array()); + return $this->_response($result); + } + + /** + * The get_comment function pulls a single comment based + * on a comment ID. + * + * @param array $params Specific params for getting a single comment + * @return array + */ + public function get_comment($params) { + + // Here, we're getting the current blog id. If blog id + // is passed along with the parameters then we override + // that current (default) value with the parameter blog id value. + + $blog_id = get_current_blog_id(); + if (isset($params['blog_id'])) $blog_id = $params['blog_id']; + + + // If user does not have sufficient privileges to moderate or edit + // a comment then we return with error. + + if (!current_user_can_for_blog($blog_id, 'moderate_comments')) { + $result = array('error' => true, 'message' => 'insufficient_permission'); + return $this->_response($result); + } + + // Here, we're switching to the actual blog that we need + // to pull comments from. + + $switched = false; + if (function_exists('switch_to_blog')) { + $switched = switch_to_blog($blog_id); + } + + // Get comment by comment_ID parameter and return result as an array. + $result = array( + 'comment' => get_comment($params['comment_id'], ARRAY_A) + ); + + + // Here, we're restoring to the current (default) blog before we + // do the switched. + + if (function_exists('restore_current_blog') && $switched) { + restore_current_blog(); + } + + return $this->_response($result); + } + + /** + * The reply_comment function creates a new comment as a reply + * to a certain/selected comment. + * + * @param array $params Specific params to create a new comment reply + * @return array + */ + public function reply_comment($params) { + + // Extract reply info from the passed parameters + $reply = $params['comment']; + + // Here, we're getting the current blog id. If blog id + // is passed along with the parameters then we override + // that current (default) value with the parameter blog id value. + + $blog_id = get_current_blog_id(); + if (isset($params['blog_id'])) $blog_id = $params['blog_id']; + + + // If user does not have sufficient privileges to moderate or edit + // a comment then we return with error. + + if (!current_user_can_for_blog($blog_id, 'moderate_comments')) { + $result = array('error' => true, 'message' => 'comment_reply_no_permission'); + return $this->_response($result); + } + + // Here, we're switching to the actual blog that we need + // to apply our changes. + + $switched = false; + if (function_exists('switch_to_blog')) { + $switched = switch_to_blog($blog_id); + } + + + // Get comment by comment_ID parameter. + $comment = get_comment($reply['comment_id']); + if ($comment) { + + // Get the currently logged in user + $user = wp_get_current_user(); + + // If the current comment was not approved yet then + // we need to approve it before we create a reply to + // to the comment, mimicking exactly the WP behaviour + // in terms of creating a reply to a comment. + + if (empty($comment->comment_approved)) { + $update_data = array( + 'comment_ID' => $reply['comment_id'], + 'comment_approved' => 1 + ); + wp_update_comment($update_data); + } + + // Build new comment parameters based on current user info and + // the target comment for the reply. + $data = array( + 'comment_post_ID' => $comment->comment_post_ID, + 'comment_author' => $user->display_name, + 'comment_author_email' => $user->user_email, + 'comment_author_url' => $user->user_url, + 'comment_content' => $reply['message'], + 'comment_parent' => $reply['comment_id'], + 'user_id' => $user->ID, + 'comment_date' => current_time('mysql'), + 'comment_approved' => 1 + ); + + // Create new comment based on the parameters above, and return + // the status accordingly. + + if (wp_insert_comment($data)) { + $result = array('error' => false, 'message' => 'comment_replied_with_comment_author', 'values' => array($comment->comment_author)); + } else { + $result = array('error' => true, 'message' => 'comment_reply_failed_with_error', 'values' => array($comment->comment_ID)); + } + } else { + $result = array('error' => true, 'message' => 'comment_does_not_exists_error', 'values' => array($reply['comment_id'])); + } + + + // Here, we're restoring to the current (default) blog before we + // do the switched. + + if (function_exists('restore_current_blog') && $switched) { + restore_current_blog(); + } + + return $this->_response($result); + } + + /** + * The edit_comment function saves new information for the + * currently selected comment. + * + * @param array $params Specific params for editing a comment + * @return array + */ + public function edit_comment($params) { + + // Extract new comment info from the passed parameters + $comment = $params['comment']; + + // Here, we're getting the current blog id. If blog id + // is passed along with the parameters then we override + // that current (default) value with the parameter blog id value. + + $blog_id = get_current_blog_id(); + if (isset($params['blog_id'])) $blog_id = $params['blog_id']; + + + // If user does not have sufficient privileges to moderate or edit + // a comment then we return with error. + + if (!current_user_can_for_blog($blog_id, 'moderate_comments')) { + $result = array('error' => true, 'message' => 'comment_edit_no_permission'); + return $this->_response($result); + } + + // Here, we're switching to the actual blog that we need + // to apply our changes. + + $switched = false; + if (function_exists('switch_to_blog')) { + $switched = switch_to_blog($blog_id); + } + + + // Get current comment details + $original_comment = get_comment($comment['comment_id']); + if ($original_comment) { + $data = array(); + + // Replace "comment_id" with "comment_ID" since WP does not recognize + // the small case "id". + $comment['comment_ID'] = $original_comment->comment_ID; + unset($comment['comment_id']); + + // Here, we're sanitizing the input fields before we save them to the database + // for safety and security reason. The "explode" and "implode" functions are meant + // to maintain the line breaks associated with a textarea input/value. + + foreach ($comment as $key => $value) { + $data[$key] = implode("\n", array_map('sanitize_text_field', explode("\n", $value))); + } + + // Update existing comment based on the passed parameter fields and + // return the status accordingly. + + if (wp_update_comment($data)) { + $result = array('error' => false, 'message' => 'comment_edited_with_comment_author', 'values' => array($original_comment->comment_author)); + } else { + $result = array('error' => true, 'message' => 'comment_edit_failed_with_error', 'values' => array($original_comment->comment_ID)); + } + } else { + $result = array('error' => true, 'message' => 'comment_does_not_exists_error', 'values' => array($comment['comment_id'])); + } + + // Here, we're restoring to the current (default) blog before we + // do the switched. + + if (function_exists('restore_current_blog') && $switched) { + restore_current_blog(); + } + + return $this->_response($result); + } + + /** + * The update_comment_status function is a generic handler for the following + * comment actions: + * + * - approve comment + * - unapprove comment + * - set comment as spam + * - move comment to trash + * - delete comment permanently + * - unset comment as spam + * - restore comment + * + * @param array $params Specific params to update comment status + * @return array + */ + public function update_comment_status($params) { + + // Here, we're getting the current blog id. If blog id + // is passed along with the parameters then we override + // that current (default) value with the parameter blog id value. + + $blog_id = get_current_blog_id(); + if (isset($params['blog_id'])) $blog_id = $params['blog_id']; + + + // If user does not have sufficient privileges to moderate or edit + // a comment then we return with error. + + if (!current_user_can_for_blog($blog_id, 'moderate_comments')) { + $result = array('error' => true, 'message' => 'comment_change_status_no_permission'); + return $this->_response($result); + } + + // Here, we're switching to the actual blog that we need + // to apply our changes. + + $switched = false; + if (function_exists('switch_to_blog')) { + $switched = switch_to_blog($blog_id); + } + + + // We make sure that we still have a valid comment from the server + // before we apply the currently selected action. + + $comment = get_comment($params['comment_id']); + if ($comment) { + $post = get_post($comment->comment_post_ID); + + if ($post) $comment->in_response_to = $post->post_title; + if (!empty($comment->comment_parent)) { + $parent_comment = get_comment($comment->comment_parent); + if ($parent_comment) $comment->in_reply_to = $parent_comment->comment_author; + } + + // We're formatting the comment_date to be exactly the same + // with that of WP Comments table (e.g. 2016/12/21 at 10:30 PM) + + $comment->comment_date = date('Y/m/d \a\t g:i a', strtotime($comment->comment_date)); + + $status = wp_get_comment_status($comment->comment_ID); + if ($status) { + $comment->comment_status = $status; + } + + $succeeded = false; + $message = ''; + + // Here, we're using WP's wp_set_comment_status function to change the state + // of the selected comment based on the current action, except for the "delete" action + // where we use the wp_delete_comment to delete the comment permanently by passing + // "true" to the second argument. + + switch ($params['action']) { + case 'approve': + $succeeded = wp_set_comment_status($params['comment_id'], 'approve'); + $message = 'comment_approve_with_comment_author'; + break; + case 'unapprove': + $succeeded = wp_set_comment_status($params['comment_id'], 'hold'); + $message = 'comment_unapprove_with_comment_author'; + break; + case 'spam': + $succeeded = wp_set_comment_status($params['comment_id'], 'spam'); + $message = 'comment_spam_with_comment_author'; + break; + case 'trash': + $succeeded = wp_set_comment_status($params['comment_id'], 'trash'); + $message = 'comment_trash_with_comment_author'; + break; + case 'delete': + $succeeded = wp_delete_comment($params['comment_id'], true); + $message = 'comment_delete_with_comment_author'; + break; + case 'notspam': + $succeeded = wp_set_comment_status($params['comment_id'], 'hold'); + $message = 'comment_not_spam_with_comment_author'; + break; + case 'restore': + $succeeded = wp_set_comment_status($params['comment_id'], 'hold'); + $message = 'comment_restore_with_comment_author'; + break; + } + + // If the current action succeeded, then we return a success message, otherwise, + // we return an error message to the user issuing the request. + + if ($succeeded) { + $result = array('error' => false, 'message' => $message, 'values' => array($comment->comment_author), 'status' => $comment->comment_status, 'approved' => $comment->comment_approved); + } else { + $result = array('error' => true, 'message' => 'comment_change_status_failed_with_error', 'values' => array($comment->comment_ID)); + } + } else { + $result = array('error' => true, 'message' => 'comment_does_not_exists_error', 'values' => array($params['comment_id'])); + } + + // Here, we're restoring to the current (default) blog before we + // do the switched. + + if (function_exists('restore_current_blog') && $switched) { + restore_current_blog(); + } + + return $this->_response($result); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/core.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/core.php new file mode 100755 index 00000000..99e1e276 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/core.php @@ -0,0 +1,508 @@ + (string - a code), 'data' => (mixed)); + * + * RPC commands are not allowed to begin with an underscore. So, any private methods can be prefixed with an underscore. + */ +class UpdraftCentral_Core_Commands extends UpdraftCentral_Commands { + + /** + * Retrieve site icon (favicon) + * + * @return array An array containing the site icon (favicon) byte string if available + */ + public function get_site_icon() { + + if (!function_exists('get_site_icon_url')) { + include_once(ABSPATH.'wp-includes/general-template.php'); + } + + $site_icon_url = get_site_icon_url(); + + // If none is set in WordPress, let's try to search for the default favicon + // within the site's directory + if (empty($site_icon_url)) { + + if (!function_exists('get_site_url')) { + include_once(ABSPATH.'wp-includes/link-template.php'); + } + + // Common favicon locations to check + $potential_locations = array( + '/favicon.ico', + '/favicon.png', + '/favicon.svg', + '/assets/favicon.ico', + '/assets/images/favicon.ico', + '/apple-touch-icon.png', + '/apple-touch-icon-precomposed.png', + ); + + foreach ($potential_locations as $location) { + $path = rtrim(ABSPATH, '/\\').$location; + if (file_exists($path)) { + $site_icon_url = get_site_url().$location; + break; + } + } + } + + // We are returning the site icon as byte string instead of URL in order to avoid + // any hotlink protection that might prevent us to show the icon in UpdraftCentral + // dashboard successfully. + $site_icon = ''; + if (!empty($site_icon_url)) { + $content = file_get_contents($site_icon_url); + + $mime_type = ''; + foreach ($http_response_header as $value) { + if (false !== stripos($value, 'content-type:')) { + list(, $mime_type) = explode(':', preg_replace('/\s+/', '', $value)); + break; + } + } + + if ($content && !empty($mime_type)) { + $site_icon = 'data: '.$mime_type.';base64,'.base64_encode($content); + } + } + + return $this->_response(array('site_icon' => $site_icon)); + } + + /** + * Executes a list of submitted commands (multiplexer) + * + * @param Array $query An array containing the commands to execute and a flag to indicate how to handle command execution failure. + * @return Array An array containing the results of the process. + */ + public function execute_commands($query) { + + try { + + $commands = $query['commands']; + $command_results = array(); + $error_count = 0; + + /** + * Should be one of the following options: + * 1 = Abort on first failure + * 2 = Abort if any command fails + * 3 = Abort if all command fails (default) + */ + $error_flag = isset($query['error_flag']) ? (int) $query['error_flag'] : 3; + + + foreach ($commands as $command => $params) { + $command_info = apply_filters('updraftcentral_get_command_info', false, $command); + if (!$command_info) { + list($_prefix, $_command) = explode('.', $command); + $command_results[$_prefix][$_command] = array('response' => 'rpcerror', 'data' => array('code' => 'unknown_rpc_command', 'data' => $command)); + + $error_count++; + if (1 === $error_flag) break; + } else { + + $action = $command_info['command']; + $command_php_class = $command_info['command_php_class']; + + // Instantiate the command class and execute the needed action + if (class_exists($command_php_class)) { + $instance = new $command_php_class($this->rc); + + if (method_exists($instance, $action)) { + $params = empty($params) ? array() : $params; + $call_result = call_user_func(array($instance, $action), $params); + + $command_results[$command] = $call_result; + if ('rpcerror' === $call_result['response'] || (isset($call_result['data']['error']) && $call_result['data']['error'])) { + $error_count++; + if (1 === $error_flag) break; + } + } + } + } + } + + if (0 !== $error_count) { + // N.B. These error messages should be defined in UpdraftCentral's translation file (dashboard-translations.php) + // before actually using this multiplexer function. + $message = 'general_command_execution_error'; + + switch ($error_flag) { + case 1: + $message = 'command_execution_aborted'; + break; + case 2: + $message = 'failed_to_execute_some_commands'; + break; + case 3: + if (count($commands) === $error_count) { + $message = 'failed_to_execute_all_commands'; + } + break; + default: + break; + } + + $result = array('error' => true, 'message' => $message, 'values' => $command_results); + } else { + $result = $command_results; + } + + } catch (Exception $e) { + $result = array('error' => true, 'message' => $e->getMessage()); + } + + return $this->_response($result); + } + + /** + * Validates the credentials entered by the user + * + * @param array $creds an array of filesystem credentials + * @return array An array containing the result of the validation process. + */ + public function validate_credentials($creds) { + + try { + + $entity = $creds['entity']; + if (isset($creds['filesystem_credentials'])) { + parse_str($creds['filesystem_credentials'], $filesystem_credentials); + if (is_array($filesystem_credentials)) { + foreach ($filesystem_credentials as $key => $value) { + // Put them into $_POST, which is where request_filesystem_credentials() checks for them. + $_POST[$key] = $value; + } + } + } + + // Include the needed WP Core file(s) + // template.php needed for submit_button() which is called by request_filesystem_credentials() + $this->_admin_include('file.php', 'template.php'); + + // Directory entities that we currently need permissions + // to update. + $entity_directories = array( + 'plugins' => WP_PLUGIN_DIR, + 'themes' => WP_CONTENT_DIR.'/themes', + 'core' => untrailingslashit(ABSPATH) + ); + + if ('translations' === $entity) { + // 'en_US' don't usually have the "languages" folder, thus, we + // check if there's a need to ask for filesystem credentials for that + // folder if it exists, most especially for locale other than 'en_US'. + $language_dir = WP_CONTENT_DIR.'/languages'; + if ('en_US' !== get_locale() && is_dir($language_dir)) { + $entity_directories['translations'] = $language_dir; + } + } + + $url = wp_nonce_url(site_url()); + + $passed = false; + if (isset($entity_directories[$entity])) { + $directory = $entity_directories[$entity]; + + // Check if credentials are valid and have sufficient + // privileges to create and delete (e.g. write) + ob_start(); + $credentials = request_filesystem_credentials($url, '', false, $directory); + ob_end_clean(); + + // The "WP_Filesystem" will suffice in validating the inputted credentials + // from UpdraftCentral, as it is already attempting to connect to the filesystem + // using the chosen transport (e.g. ssh, ftp, etc.) + $passed = WP_Filesystem($credentials, $directory); + } + + if ($passed) { + $result = array('error' => false, 'message' => 'credentials_ok', 'values' => array()); + } else { + // We're adding some useful error information to help troubleshooting any problems + // that may arise in the future. If the user submitted a wrong password or username + // it usually falls through here. + global $wp_filesystem; + + $errors = array(); + if (isset($wp_filesystem->errors) && is_wp_error($wp_filesystem->errors)) { + $errors = $wp_filesystem->errors->errors; + } + + $result = array('error' => true, 'message' => 'failed_credentials', 'values' => array('errors' => $errors)); + } + + } catch (Exception $e) { + $result = array('error' => true, 'message' => $e->getMessage(), 'values' => array()); + } + + return $this->_response($result); + } + + /** + * Gets the FileSystem Credentials + * + * Extract the needed filesystem credentials (permissions) to be used + * to update/upgrade the plugins, themes and the WP core. + * + * @return array $result - An array containing the creds form and some flags + * to determine whether we need to extract the creds + * manually from the user. + */ + public function get_credentials() { + + try { + + // Check whether user has enough permission to update entities + if (!current_user_can('update_plugins') && !current_user_can('update_themes') && !current_user_can('update_core')) return $this->_generic_error_response('updates_permission_denied'); + + // Include the needed WP Core file(s) + $this->_admin_include('file.php', 'template.php'); + + // A container that will hold the state (in this case, either true or false) of + // each directory entities (plugins, themes, core) that will be used to determine + // whether or not there's a need to show a form that will ask the user for their credentials + // manually. + $request_filesystem_credentials = array(); + + // A container for the filesystem credentials form if applicable. + $filesystem_form = ''; + + // Directory entities that we currently need permissions + // to update. + $check_fs = array( + 'plugins' => WP_PLUGIN_DIR, + 'themes' => WP_CONTENT_DIR.'/themes', + 'core' => untrailingslashit(ABSPATH) + ); + + // Here, we're looping through each entities and find output whether + // we have sufficient permissions to update objects belonging to them. + foreach ($check_fs as $entity => $dir) { + + // We're determining which method to use when updating + // the files in the filesystem. + $filesystem_method = get_filesystem_method(array(), $dir); + + // Buffering the output to pull the actual credentials form + // currently being used by this WP instance if no sufficient permissions + // is found. + $url = wp_nonce_url(site_url()); + + ob_start(); + $filesystem_credentials_are_stored = request_filesystem_credentials($url, $filesystem_method); + $form = strip_tags(ob_get_contents(), '

            '); + + if (!empty($form)) { + $filesystem_form = $form; + } + ob_end_clean(); + + // Save the state whether or not there's a need to show the + // credentials form to the user. + $request_filesystem_credentials[$entity] = ('direct' !== $filesystem_method && !$filesystem_credentials_are_stored); + } + + // Wrapping the credentials info before passing it back + // to the client issuing the request. + $result = array( + 'request_filesystem_credentials' => $request_filesystem_credentials, + 'filesystem_form' => $filesystem_form + ); + + } catch (Exception $e) { + $result = array('error' => true, 'message' => $e->getMessage(), 'values' => array()); + } + + return $this->_response($result); + } + + /** + * Fetches a browser-usable URL which will automatically log the user in to the site + * + * @param String $redirect_to - the URL to got to after logging in + * @param Array $extra_info - valid keys are user_id, which should be a numeric user ID to log in as. + */ + public function get_login_url($redirect_to, $extra_info) { + + if (is_array($extra_info) && !empty($extra_info['user_id']) && is_numeric($extra_info['user_id'])) { + + $user_id = $extra_info['user_id']; + + if (false == ($login_key = $this->_get_autologin_key($user_id))) return $this->_generic_error_response('user_key_failure'); + + // Default value + $redirect_url = network_admin_url(); + if (is_array($redirect_to) && !empty($redirect_to['module'])) { + switch ($redirect_to['module']) { + case 'updraftplus': + if ('initiate_restore' == $redirect_to['action'] && class_exists('UpdraftPlus_Options')) { + $redirect_url = UpdraftPlus_Options::admin_page_url().'?page=updraftplus&udaction=initiate_restore&entities='.urlencode($redirect_to['data']['entities']).'&showdata='.urlencode($redirect_to['data']['showdata']).'&backup_timestamp='.(int) $redirect_to['data']['backup_timestamp']; + + } elseif ('download_file' == $redirect_to['action']) { + $findex = empty($redirect_to['data']['findex']) ? 0 : (int) $redirect_to['data']['findex']; + // e.g. ?udcentral_action=dl&action=updraftplus_spool_file&backup_timestamp=1455101696&findex=0&what=plugins + $redirect_url = site_url().'?udcentral_action=spool_file&action=updraftplus_spool_file&findex='.$findex.'&what='.urlencode($redirect_to['data']['what']).'&backup_timestamp='.(int) $redirect_to['data']['backup_timestamp']; + } + break; + case 'direct_url': + $redirect_url = $redirect_to['url']; + break; + } + } + + $login_key = apply_filters('updraftplus_remotecontrol_login_key', array( + 'key' => $login_key, + 'created' => time(), + 'redirect_url' => $redirect_url + ), $redirect_to, $extra_info); + + // Over-write any previous value - only one can be valid at a time) + update_user_meta($user_id, 'updraftcentral_login_key', $login_key); + + return $this->_response(array( + 'login_url' => network_site_url('?udcentral_action=login&login_id='.$user_id.'&login_key='.$login_key['key']) + )); + + } else { + return $this->_generic_error_response('user_unknown'); + } + } + + /** + * Get information derived from phpinfo() + * + * @return Array + */ + public function phpinfo() { + $phpinfo = $this->_get_phpinfo_array(); + + if (!empty($phpinfo)) { + return $this->_response($phpinfo); + } + + return $this->_generic_error_response('phpinfo_fail'); + } + + /** + * The key obtained is only intended to be short-lived. Hence, there's no intention other than that it is random and only used once - only the most recent one is valid. + * + * @param Integer $user_id Specific user ID to get the autologin key + * @return Array + */ + public function _get_autologin_key($user_id) { + $secure_auth_key = defined('SECURE_AUTH_KEY') ? SECURE_AUTH_KEY : hash('sha256', DB_PASSWORD).'_'.rand(0, 999999999); + if (!defined('SECURE_AUTH_KEY')) return false; + $hash_it = $user_id.'_'.microtime(true).'_'.rand(0, 999999999).'_'.$secure_auth_key; + $hash = hash('sha256', $hash_it); + return $hash; + } + + public function site_info() { + global $wpdb; + + // THis is included so we can get $wp_version + @include(ABSPATH.WPINC.'/version.php');// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. + + $ud_version = is_a($this->ud, 'UpdraftPlus') ? $this->ud->version : 'none'; + + return $this->_response(array( + 'versions' => array( + 'ud' => $ud_version, + 'php' => PHP_VERSION, + 'wp' => $wp_version,// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- The variable is defined inside the ABSPATH.WPINC.'/version.php'. + 'mysql' => $wpdb->db_version(), + 'udrpc_php' => $this->rc->udrpc_version, + ), + 'bloginfo' => array( + 'url' => network_site_url(), + 'name' => get_bloginfo('name'), + ) + )); + } + + /** + * This calls the WP_Action within WP + * + * @param array $data Array of Data to be used within call_wp_action + * @return array + */ + public function call_wordpress_action($data) { + if (false === ($updraftplus_admin = $this->_load_ud_admin())) return $this->_generic_error_response('no_updraftplus'); + $response = $updraftplus_admin->call_wp_action($data); + + if (empty($data["wpaction"])) { + return $this->_generic_error_response("error", "no command sent"); + } + + return $this->_response(array( + "response" => $response['response'], + "status" => $response['status'], + "log" => $response['log'] + )); + } + + /** + * Get disk space used + * + * @uses UpdraftPlus_Filesystem_Functions::get_disk_space_used() + * + * @param String $entity - the entity to count (e.g. 'plugins', 'themes') + * + * @return Array - response + */ + public function count($entity) { + if (!class_exists('UpdraftPlus_Filesystem_Functions')) return $this->_generic_error_response('no_updraftplus'); + $response = UpdraftPlus_Filesystem_Functions::get_disk_space_used($entity); + + return $this->_response($response); + } + + /** + * https://secure.php.net/phpinfo + * + * @return null|array + */ + private function _get_phpinfo_array() { + if (!function_exists('phpinfo')) return null; + ob_start(); + phpinfo(INFO_GENERAL|INFO_CREDITS|INFO_MODULES); + $phpinfo = array('phpinfo' => array()); + + if (preg_match_all('#(?:

            (?:)?(.*?)(?:)?

            )|(?:(.*?)\s*(?:(.*?)\s*(?:(.*?)\s*)?)?)#s', ob_get_clean(), $matches, PREG_SET_ORDER)) { + foreach ($matches as $match) { + if (strlen($match[1])) { + $phpinfo[$match[1]] = array(); + } elseif (isset($match[3])) { + $keys1 = array_keys($phpinfo); + $phpinfo[end($keys1)][$match[2]] = isset($match[4]) ? array($match[3], $match[4]) : $match[3]; + } else { + $keys1 = array_keys($phpinfo); + $phpinfo[end($keys1)][] = $match[2]; + + } + + } + return $phpinfo; + } + return false; + } + + /** + * Return an UpdraftPlus_Admin object + * + * @return UpdraftPlus_Admin|Boolean - false in case of failure + */ + private function _load_ud_admin() { + if (!defined('UPDRAFTPLUS_DIR') || !is_file(UPDRAFTPLUS_DIR.'/admin.php')) return false; + updraft_try_include_file('admin.php', 'include_once'); + global $updraftplus_admin; + return $updraftplus_admin; + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/media.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/media.php new file mode 100755 index 00000000..6f6249f8 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/media.php @@ -0,0 +1,601 @@ +switched = switch_to_blog($blog_id); + } + } + + /** + * Function that gets called after every action + * + * @param string $command a string that corresponds to UDC command to call a certain method for this class. + * @param array $data an array of data post or get fields + * @param array $extra_info extrainfo use in the udrpc_action, e.g. user_id + * + * link to udrpc_action main function in class UpdraftCentral_Listener + */ + public function _post_action($command, $data, $extra_info) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Unused parameter is present because the caller from UpdraftCentral_Listener class uses 3 arguments. + // Here, we're restoring to the current (default) blog before we switched + if ($this->switched) restore_current_blog(); + } + + /** + * Fetch and retrieves posts based from the submitted parameters + * + * @param array $params Containing all the needed information to filter the results of the current request + * @return array + */ + public function get_media_items($params) { + $error = $this->_validate_capabilities(array('upload_files', 'edit_posts')); + if (!empty($error)) return $error; + + // check paged parameter; if empty set to defaults + $paged = !empty($params['paged']) ? (int) $params['paged'] : 1; + $numberposts = !empty($params['numberposts']) ? (int) $params['numberposts'] : 10; + $offset = ($paged - 1) * $numberposts; + + $args = array( + 'posts_per_page' => $numberposts, + 'paged' => $paged, + 'offset' => $offset, + 'post_type' => 'attachment', + 'post_status' => 'inherit', + ); + + if (!empty($params['keyword'])) { + $args['s'] = $params['keyword']; + } + + if (!empty($params['category'])) { + if (in_array($params['category'], array('detached', 'unattached'))) { + $attachment_ids = $this->get_unattached_ids(); + } else { + $attachment_ids = $this->get_type_ids($params['category']); + } + + $args['post__in'] = $attachment_ids; + } + + if (!empty($params['date'])) { + list($monthnum, $year) = explode(':', $params['date']); + + $args['monthnum'] = $monthnum; + $args['year'] = $year; + } + + $query = new WP_Query($args); + $result = $query->posts; + + $count_posts = (int) $query->found_posts; + $page_count = 0; + + if ($count_posts > 0) { + $page_count = absint($count_posts / $numberposts); + $remainder = absint($count_posts % $numberposts); + $page_count = ($remainder > 0) ? ++$page_count : $page_count; + } + + $info = array( + 'page' => $paged, + 'pages' => $page_count, + 'results' => $count_posts, + 'items_from' => (($paged * $numberposts) - $numberposts) + 1, + 'items_to' => ($paged == $page_count) ? $count_posts : $paged * $numberposts, + ); + + $media_items = array(); + if (!empty($result)) { + foreach ($result as $item) { + $media = $this->get_media_item($item, null, true); + if (!empty($media)) { + array_push($media_items, $media); + } + } + } + + $response = array( + 'items' => $media_items, + 'info' => $info, + 'options' => array( + 'date' => $this->get_date_options(), + 'type' => $this->get_type_options() + ) + ); + + return $this->_response($response); + } + + /** + * Check whether we have an image editor (e.g. GD, Imagick, etc.) set in place to handle the basic editing + * functions such as rotate, crop, etc. If not, then we hide that feature in UpdraftCentral + * + * @param object $media The media item/object to check + * @return boolean + */ + private function has_image_editor($media) { + // Most of the time image library are enabled by default in the php.ini but there's a possbility that users don't + // enable them as they have no need for them at the moment or for some other reasons. Thus, we need to confirm + // that here through the wp_get_image_editor method. + $has_image_editor = true; + if (!empty($media)) { + if (!function_exists('wp_get_image_editor')) { + require_once(ABSPATH.'wp-includes/media.php'); + } + + if (!function_exists('_load_image_to_edit_path')) { + require_once(ABSPATH.'wp-admin/includes/image.php'); + } + + $image_editor = wp_get_image_editor(_load_image_to_edit_path($media->ID)); + if (is_wp_error($image_editor)) { + $has_image_editor = false; + } + } + + return $has_image_editor; + } + + /** + * Fetch a single media item information + * + * @param array $params Containing all the needed information to filter the results of the current request + * @param array|null $extra_info Additional information from the current request + * @param boolean $raw If set, returns the result of the fetch process unwrapped by the response array + * @return array + */ + public function get_media_item($params, $extra_info = null, $raw = false) { + $error = $this->_validate_capabilities(array('upload_files', 'edit_posts')); + if (!empty($error)) return $error; + + // Raw means that we need to return the result without wrapping it + // with the "$this->_response" function which indicates that the call + // was done locally (within the class) and not directly from UpdraftCentral. + if ($raw && is_object($params) && isset($params->ID)) { + $media = $params; + } elseif (is_array($params) && !empty($params['id'])) { + $media = get_post($params['id']); + } + + if (!function_exists('get_post_mime_types')) { + global $updraftcentral_main; + + // For a much later version of WP the "get_post_mime_types" is located + // in a different folder. So, we make sure that we have it loaded before + // actually using it. + if (version_compare($updraftcentral_main->get_wordpress_version(), '3.5', '>=')) { + require_once(ABSPATH.WPINC.'/post.php'); + } else { + // For WP 3.4, the "get_post_mime_types" is located in the location provided below. + require_once(ABSPATH.'wp-admin/includes/post.php'); + } + } + + if (!function_exists('wp_image_editor')) { + require_once(ABSPATH.'wp-admin/includes/image-edit.php'); + } + + if (!function_exists('get_media_item')) { + require_once(ABSPATH.'wp-admin/includes/template.php'); + require_once(ABSPATH.'wp-admin/includes/media.php'); + } + + + if ($media) { + $thumb = wp_get_attachment_image_src($media->ID, 'thumbnail', true); + if (!empty($thumb)) $media->thumb_url = $thumb[0]; + + $media->url = wp_get_attachment_url($media->ID); + $media->parent_post_title = get_the_title($media->post_parent); + $media->author = get_the_author_meta('display_name', $media->post_author); + $media->filename = basename($media->url); + $media->date = date('Y/m/d', strtotime($media->post_date)); + $media->upload_date = mysql2date(get_option('date_format'), $media->post_date); + + $media->filesize = 0; + $file = get_attached_file($media->ID); + if (!empty($file) && file_exists($file)) { + $media->filesize = size_format(filesize($file)); + } + + $media->nonce = wp_create_nonce('image_editor-'.$media->ID); + if (false !== strpos($media->post_mime_type, 'image/')) { + $meta = wp_get_attachment_metadata($media->ID); + + $thumb = image_get_intermediate_size($media->ID, 'thumbnail'); + $sub_sizes = isset($meta['sizes']) && is_array($meta['sizes']); + + // Pulling details + $sizer = 1; + if (isset($meta['width'], $meta['height'])) { + $big = max($meta['width'], $meta['height']); + $sizer = $big > 400 ? 400 / $big : 1; + } + + $constrained_dims = array(); + if ($thumb && $sub_sizes) { + $constrained_dims = wp_constrain_dimensions($thumb['width'], $thumb['height'], 160, 120); + } + + $rotate_supported = false; + if (function_exists('imagerotate') || wp_image_editor_supports(array('mime_type' => get_post_mime_type($media->ID), 'methods' => array('rotate')))) { + $rotate_supported = true; + } + + // Check for alternative text if present + $alt = get_post_meta($media->ID, '_wp_attachment_image_alt', true); + $media->alt = !empty($alt) ? $alt : ''; + + // Check whether edited images are restorable + $backup_sizes = get_post_meta($media->ID, '_wp_attachment_backup_sizes', true); + $can_restore = !empty($backup_sizes) && isset($backup_sizes['full-orig']) && basename($meta['file']) != $backup_sizes['full-orig']['file']; + + $image_edit_overwrite = (!defined('IMAGE_EDIT_OVERWRITE') || !IMAGE_EDIT_OVERWRITE) ? 0 : 1; + $media->misc = array( + 'sizer' => $sizer, + 'rand' => rand(1, 99999), + 'constrained_dims' => $constrained_dims, + 'rotate_supported' => (int) $rotate_supported, + 'thumb' => $thumb, + 'meta' => $meta, + 'alt_text' => $alt, + 'can_restore' => $can_restore, + 'image_edit_overwrite' => $image_edit_overwrite + ); + + $media->has_image_editor = $this->has_image_editor($media); + } + } + + return $raw ? $media : $this->_response(array('item' => $media)); + } + + /** + * Fetch and retrieves posts based from the submitted parameters + * + * @param array $params Containing all the needed information to filter the results of the current request + * @return array + */ + public function get_posts($params) { + $error = $this->_validate_capabilities(array('edit_posts')); + if (!empty($error)) return $error; + + // check paged parameter; if empty set to defaults + $paged = !empty($params['paged']) ? (int) $params['paged'] : 1; + $numberposts = !empty($params['numberposts']) ? (int) $params['numberposts'] : 10; + $offset = ($paged - 1) * $numberposts; + + $args = array( + 'posts_per_page' => $numberposts, + 'paged' => $paged, + 'offset' => $offset, + 'post_type' => 'post', + 'post_status' => 'publish,private,draft,pending,future', + ); + + if (!empty($params['keyword'])) { + $args['s'] = $params['keyword']; + } + + $query = new WP_Query($args); + $result = $query->posts; + + $count_posts = (int) $query->found_posts; + $page_count = 0; + + if ($count_posts > 0) { + $page_count = absint($count_posts / $numberposts); + $remainder = absint($count_posts % $numberposts); + $page_count = ($remainder > 0) ? ++$page_count : $page_count; + } + + $info = array( + 'page' => $paged, + 'pages' => $page_count, + 'results' => $count_posts, + 'items_from' => (($paged * $numberposts) - $numberposts) + 1, + 'items_to' => ($paged == $page_count) ? $count_posts : $paged * $numberposts, + ); + + $posts = array(); + if (!empty($result)) { + foreach ($result as $post) { + array_push($posts, array('ID' => $post->ID, 'title' => $post->post_title)); + } + } + + $response = array( + 'posts' => $posts, + 'info' => $info + ); + return $this->_response($response); + } + + /** + * Saves media changes from UpdraftCentral + * + * @param array $params Containing all the needed information to filter the results of the current request + * @return array + */ + public function save_media_item($params) { + $error = $this->_validate_capabilities(array('upload_files', 'edit_posts')); + if (!empty($error)) return $error; + + $args = array( + 'post_title' => $params['image_title'], + 'post_excerpt' => $params['image_caption'], + 'post_content' => $params['image_description'] + ); + + if (!empty($params['new'])) { + $args['post_type'] = 'attachment'; + $media_id = wp_insert_post($args, true); + } else { + $args['ID'] = $params['id']; + $args['post_modified'] = date('Y-m-d H:i:s'); + $args['post_modified_gmt'] = gmdate('Y-m-d H:i:s'); + + $media_id = wp_update_post($args, true); + } + + if (!empty($media_id)) { + // Update alternative text if not empty + if (!empty($params['image_alternative_text'])) { + update_post_meta($media_id, '_wp_attachment_image_alt', $params['image_alternative_text']); + } + + $result = array( + 'status' => 'success', + 'item' => $this->get_media_item(array('id' => $media_id), null, true) + ); + } else { + $result = array('status' => 'failed'); + } + + return $this->_response($result); + } + + /** + * Executes media action (e.g. attach, detach and delete) + * + * @param array $params Containing all the needed information to filter the results of the current request + * @return array + */ + public function execute_media_action($params) { + global $updraftcentral_host_plugin; + + $error = $this->_validate_capabilities(array('upload_files', 'edit_posts')); + if (!empty($error)) return $error; + + $result = array(); + switch ($params['do']) { + case 'attach': + global $wpdb; + $query_result = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->posts} SET `post_parent` = %d WHERE `post_type` = 'attachment' AND ID = %d", $params['parent_id'], $params['id'])); + + if (false === $query_result) { + $result['error'] = $updraftcentral_host_plugin->retrieve_show_message('failed_to_attach_media'); + } else { + $result['msg'] = $updraftcentral_host_plugin->retrieve_show_message('media_attached'); + } + break; + case 'detach': + global $wpdb; + $query_result = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->posts} SET `post_parent` = 0 WHERE `post_type` = 'attachment' AND ID = %d", $params['id'])); + + if (false === $query_result) { + $result['error'] = $updraftcentral_host_plugin->retrieve_show_message('failed_to_detach_media'); + } else { + $result['msg'] = $updraftcentral_host_plugin->retrieve_show_message('media_detached'); + } + break; + case 'delete': + $failed_items = array(); + foreach ($params['ids'] as $id) { + // Delete permanently + if (false === wp_delete_attachment($id, true)) { + $failed_items[] = $id; + } + } + + if (!empty($failed_items)) { + $result['error'] = $updraftcentral_host_plugin->retrieve_show_message('failed_to_delete_media'); + $result['items'] = $failed_items; + } else { + $result['msg'] = $updraftcentral_host_plugin->retrieve_show_message('selected_media_deleted'); + } + break; + default: + break; + } + + return $this->_response($result); + } + + /** + * Retrieves a collection of formatted dates found for the given post statuses. + * It will be used as options for the date filter when managing the media items in UpdraftCentral. + * + * @return array + */ + private function get_date_options() { + global $wpdb; + $options = array(); + + $date_options = $wpdb->get_col("SELECT DATE_FORMAT(`post_date`, '%M %Y') as `formatted_post_date` FROM {$wpdb->posts} WHERE `post_type` = 'attachment' AND `post_status` = 'inherit' GROUP BY `formatted_post_date` ORDER BY `post_date` DESC"); + + if (!empty($date_options)) { + foreach ($date_options as $monthyear) { + $timestr = strtotime($monthyear); + $options[] = array('label' => date('F Y', $timestr), 'value' => date('n:Y', $timestr)); + } + } + + return $options; + } + + /** + * Retrieves mime types that will be use as filter option in UpdraftCentral + * + * @return array + */ + private function get_type_options() { + global $wpdb, $updraftcentral_host_plugin, $updraftcentral_main; + + $options = array(); + if (!function_exists('get_post_mime_types')) { + // For a much later version of WP the "get_post_mime_types" is located + // in a different folder. So, we make sure that we have it loaded before + // actually using it. + if (version_compare($updraftcentral_main->get_wordpress_version(), '3.5', '>=')) { + require_once(ABSPATH.WPINC.'/post.php'); + } else { + // For WP 3.4, the "get_post_mime_types" is located in the location provided below. + require_once(ABSPATH.'wp-admin/includes/post.php'); + } + } + + $post_mime_types = get_post_mime_types(); + $type_options = $wpdb->get_col("SELECT `post_mime_type` FROM {$wpdb->posts} WHERE `post_type` = 'attachment' AND `post_status` = 'inherit' GROUP BY `post_mime_type` ORDER BY `post_mime_type` DESC"); + + foreach ($post_mime_types as $mime_type => $label) { + if (!wp_match_mime_types($mime_type, $type_options)) continue; + $options[] = array('label' => $label[0], 'value' => esc_attr($mime_type)); + } + + $options[] = array('label' => $updraftcentral_host_plugin->retrieve_show_message('unattached'), 'value' => 'detached'); + return $options; + } + + /** + * Retrieves media items that haven't been attached to any posts + * + * @return array + */ + private function get_unattached_ids() { + global $wpdb; + return $wpdb->get_col("SELECT `ID` FROM {$wpdb->posts} WHERE `post_type` = 'attachment' AND `post_status` = 'inherit' AND `post_parent` = '0'"); + } + + /** + * Retrieves IDs of media items that has the given mime type + * + * @param string $type The mime type to search for + * @return array + */ + private function get_type_ids($type) { + global $wpdb; + return $wpdb->get_col($wpdb->prepare("SELECT `ID` FROM {$wpdb->posts} WHERE `post_type` = 'attachment' AND `post_status` = 'inherit' AND `post_mime_type` LIKE %s", $type.'/%')); + } + + /** + * Checks whether we have the required fields submitted and the user has + * the capabilities to execute the requested action + * + * @param array $capabilities The capabilities to check and validate + * + * @return array|void + */ + private function _validate_capabilities($capabilities) { + foreach ($capabilities as $capability) { + if (!current_user_can($capability)) { + return $this->_generic_error_response('insufficient_permission'); + } + } + } + + /** + * Populates the $_REQUEST global variable with the submitted data + * + * @param array $params Submitted data received from UpdraftCentral + * @return array + */ + private function populate_request($params) { + if (!empty($params)) { + foreach ($params as $key => $value) { + $_REQUEST[$key] = $value; + } + } + } + + /** + * Handles image editing requests coming from UpdraftCentral + * + * @param array $params Containing all the needed information to filter the results of the current request + * @return array + */ + public function image_editor($params) { + $error = $this->_validate_capabilities(array('edit_posts')); + if (!empty($error)) return $error; + + $attachment_id = (int) $params['postid']; + $this->populate_request($params); + + if (!function_exists('load_image_to_edit')) { + require_once(ABSPATH.'wp-admin/includes/image.php'); + } + + include_once(ABSPATH.'wp-admin/includes/image-edit.php'); + $msg = false; + switch ($params['do']) { + case 'save': + case 'scale': + $msg = wp_save_image($attachment_id); + break; + case 'restore': + $msg = wp_restore_image($attachment_id); + break; + } + + $msg = (false !== $msg) ? json_encode($msg) : $msg; + return $this->_response(array('content' => $msg)); + } + + /** + * Handles image preview requests coming from UpdraftCentral + * + * @param array $params Containing all the needed information to filter the results of the current request + * @return array + */ + public function image_preview($params) { + $error = $this->_validate_capabilities(array('edit_posts')); + if (!empty($error)) return $error; + + if (!function_exists('load_image_to_edit')) { + require_once(ABSPATH.'wp-admin/includes/image.php'); + } + + include_once(ABSPATH.'wp-admin/includes/image-edit.php'); + $this->populate_request($params); + $post_id = (int) $params['postid']; + + ob_start(); + stream_preview_image($post_id); + $content = ob_get_contents(); + ob_end_clean(); + + return $this->_response(array('content' => base64_encode($content))); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/pages.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/pages.php new file mode 100755 index 00000000..7ff769a6 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/pages.php @@ -0,0 +1,15 @@ +switched = switch_to_blog($blog_id); + } + } + + /** + * Function that gets called after every action + * + * @param string $command a string that corresponds to UDC command to call a certain method for this class. + * @param array $data an array of data post or get fields + * @param array $extra_info extrainfo use in the udrpc_action, e.g. user_id + * + * link to udrpc_action main function in class UpdraftCentral_Listener + */ + public function _post_action($command, $data, $extra_info) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Unused parameter is present because the caller from UpdraftCentral_Listener class uses 3 arguments. + // Here, we're restoring to the current (default) blog before we switched + if ($this->switched) restore_current_blog(); + } + + /** + * Constructor + */ + public function __construct() { + $this->_admin_include('plugin.php', 'file.php', 'template.php', 'class-wp-upgrader.php', 'plugin-install.php', 'update.php'); + } + + /** + * Installs and activates a plugin through upload + * + * @param array $params Parameter array containing information pertaining the currently uploaded plugin + * @return array Contains the result of the current process + */ + public function upload_plugin($params) { + return $this->process_chunk_upload($params, 'plugin'); + } + + /** + * Checks whether the plugin is currently installed and activated. + * + * @param array $query Parameter array containing the name of the plugin to check + * @return array Contains the result of the current process + */ + public function is_plugin_installed($query) { + + if (!isset($query['plugin'])) + return $this->_generic_error_response('plugin_name_required'); + + + $result = $this->_get_plugin_info($query); + return $this->_response($result); + } + + /** + * Applies currently requested action for plugin processing + * + * @param string $action The action to apply (e.g. activate or install) + * @param array $query Parameter array containing information for the currently requested action + * + * @return array + */ + private function _apply_plugin_action($action, $query) { + + $result = array(); + switch ($action) { + case 'activate': + case 'network_activate': + $info = $this->_get_plugin_info($query); + if ($info['installed']) { + $activate = activate_plugin($info['plugin_path']); + if (is_wp_error($activate)) { + $result = $this->_generic_error_response('generic_response_error', array( + 'plugin' => $query['plugin'], + 'error_code' => 'generic_response_error', + 'error_message' => $activate->get_error_message(), + 'info' => $this->_get_plugin_info($query) + )); + } else { + $result = array('activated' => true, 'info' => $this->_get_plugin_info($query), 'last_state' => $info); + } + } else { + $result = $this->_generic_error_response('plugin_not_installed', array( + 'plugin' => $query['plugin'], + 'error_code' => 'plugin_not_installed', + 'error_message' => __('The plugin you wish to activate is either not installed or has been removed recently.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'info' => $info + )); + } + break; + case 'deactivate': + case 'network_deactivate': + $info = $this->_get_plugin_info($query); + if ($info['active']) { + deactivate_plugins($info['plugin_path']); + if (!is_plugin_active($info['plugin_path'])) { + $result = array('deactivated' => true, 'info' => $this->_get_plugin_info($query), 'last_state' => $info); + } else { + $result = $this->_generic_error_response('deactivate_plugin_failed', array( + 'plugin' => $query['plugin'], + 'error_code' => 'deactivate_plugin_failed', + 'error_message' => __('There appears to be a problem deactivating the intended plugin.', UPDRAFTCENTRAL_TEXT_DOMAIN).' '.__('Please check your permissions and try again.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'info' => $this->_get_plugin_info($query) + )); + } + } else { + $result = $this->_generic_error_response('not_active', array( + 'plugin' => $query['plugin'], + 'error_code' => 'not_active', + 'error_message' => __('The plugin you wish to deactivate is currently not active or is already deactivated.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'info' => $info + )); + } + break; + case 'install': + $api = plugins_api('plugin_information', array( + 'slug' => $query['slug'], + 'fields' => array( + 'short_description' => false, + 'sections' => false, + 'requires' => false, + 'rating' => false, + 'ratings' => false, + 'downloaded' => false, + 'last_updated' => false, + 'added' => false, + 'tags' => false, + 'compatibility' => false, + 'homepage' => false, + 'donate_link' => false, + ) + )); + + $info = $this->_get_plugin_info($query); + if (is_wp_error($api)) { + $result = $this->_generic_error_response('generic_response_error', array( + 'plugin' => $query['plugin'], + 'error_code' => 'generic_response_error', + 'error_message' => $api->get_error_message(), + 'info' => $info + )); + } else { + $installed = $info['installed']; + + $error_code = $error_message = ''; + if (!$installed) { + // WP < 3.7 + if (!class_exists('Automatic_Upgrader_Skin')) include_once(dirname(dirname(__FILE__)).'/classes/class-automatic-upgrader-skin.php'); + + $skin = new Automatic_Upgrader_Skin(); + $upgrader = new Plugin_Upgrader($skin); + + $download_link = $api->download_link; + $installed = $upgrader->install($download_link); + + if (is_wp_error($installed)) { + $error_code = $installed->get_error_code(); + $error_message = $installed->get_error_message(); + } elseif (is_wp_error($skin->result)) { + $error_code = $skin->result->get_error_code(); + $error_message = $skin->result->get_error_message(); + + $error_data = $skin->result->get_error_data($error_code); + if (!empty($error_data)) { + if (is_array($error_data)) $error_data = json_encode($error_data); + $error_message .= ' '.$error_data; + } + } elseif (is_null($installed) || !$installed) { + global $wp_filesystem; + $upgrade_messages = $skin->get_upgrade_messages(); + + if (!class_exists('WP_Filesystem_Base')) include_once(ABSPATH.'/wp-admin/includes/class-wp-filesystem-base.php'); + + // Pass through the error from WP_Filesystem if one was raised. + if ($wp_filesystem instanceof WP_Filesystem_Base && is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) { + $error_code = $wp_filesystem->errors->get_error_code(); + $error_message = $wp_filesystem->errors->get_error_message(); + } elseif (!empty($upgrade_messages)) { + // We're only after for the last feedback that we received from the install process. Mostly, + // that is where the last error has been inserted. + $messages = $skin->get_upgrade_messages(); + $error_code = 'install_failed'; + $error_message = end($messages); + } else { + $error_code = 'unable_to_connect_to_filesystem'; + $error_message = __('Unable to connect to the filesystem.', UPDRAFTCENTRAL_TEXT_DOMAIN).' '.__('Please confirm your credentials.', UPDRAFTCENTRAL_TEXT_DOMAIN); + } + } + } + + if (!$installed || is_wp_error($installed)) { + $result = $this->_generic_error_response('plugin_install_failed', array( + 'plugin' => $query['plugin'], + 'error_code' => $error_code, + 'error_message' => $error_message, + 'info' => $this->_get_plugin_info($query) + )); + } else { + $result = array('installed' => true, 'info' => $this->_get_plugin_info($query), 'last_state' => $info); + } + } + break; + } + + return $result; + } + + /** + * Preloads the submitted credentials to the global $_POST variable + * + * @param array $query Parameter array containing information for the currently requested action + */ + private function _preload_credentials($query) { + if (!empty($query) && isset($query['filesystem_credentials'])) { + parse_str($query['filesystem_credentials'], $filesystem_credentials); + if (is_array($filesystem_credentials)) { + foreach ($filesystem_credentials as $key => $value) { + // Put them into $_POST, which is where request_filesystem_credentials() checks for them. + $_POST[$key] = $value; + } + } + } + } + + /** + * Checks whether we have the required fields submitted and the user has + * the capabilities to execute the requested action + * + * @param array $query The submitted information + * @param array $fields The required fields to check + * @param array $capabilities The capabilities to check and validate + * + * @return array|string + */ + private function _validate_fields_and_capabilities($query, $fields, $capabilities) { + + $error = ''; + if (!empty($fields)) { + for ($i=0; $i_generic_error_response('keyword_required'); + } else { + $error = $this->_generic_error_response('plugin_'.$query[$field].'_required'); + } + break; + } + } + } + + if (empty($error) && !empty($capabilities)) { + for ($i=0; $i_generic_error_response('plugin_insufficient_permission'); + break; + } + } + } + + return $error; + } + + /** + * Processing an action for multiple items + * + * @param array $query Parameter array containing a list of plugins to process + * @return array Contains the results of the bulk process + */ + public function process_action_in_bulk($query) { + $action = isset($query['action']) ? $query['action'] : ''; + $items = isset($query['args']) ? $query['args']['items'] : array(); + + $results = array(); + if (!empty($action) && !empty($items) && is_array($items)) { + foreach ($items as $value) { + if (method_exists($this, $action)) { + $results[] = $this->$action($value); + } + } + } + + return $this->_response($results); + } + + /** + * Activates the plugin + * + * @param array $query Parameter array containing the name of the plugin to activate + * @return array Contains the result of the current process + */ + public function activate_plugin($query) { + + $fields = array('plugin'); + $permissions = array('activate_plugins'); + + $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); + if (!empty($error)) { + return $error; + } + + $this->_preload_credentials($query); + + $result = $this->_apply_plugin_action((!empty($query['multisite']) && (bool) $query['multisite']) ? 'network_activate' : 'activate', $query); + if (empty($result['activated'])) { + return $result; + } + + return $this->_response($result); + } + + /** + * Deactivates the plugin + * + * @param array $query Parameter array containing the name of the plugin to deactivate + * @return array Contains the result of the current process + */ + public function deactivate_plugin($query) { + + $fields = array('plugin'); + $permissions = array('activate_plugins'); + + $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); + if (!empty($error)) { + return $error; + } + + $this->_preload_credentials($query); + + $result = $this->_apply_plugin_action((!empty($query['multisite']) && (bool) $query['multisite']) ? 'network_deactivate' : 'deactivate', $query); + if (empty($result['deactivated'])) { + return $result; + } + + return $this->_response($result); + } + + /** + * Download, install and activates the plugin + * + * @param array $query Parameter array containing the filesystem credentials entered by the user along with the plugin name and slug + * @return array Contains the result of the current process + */ + public function install_activate_plugin($query) { + + $fields = array('plugin', 'slug'); + $permissions = array('install_plugins', 'activate_plugins'); + + $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); + if (!empty($error)) { + return $error; + } + + $this->_preload_credentials($query); + + $result = $this->_apply_plugin_action('install', $query); + if (!empty($result['installed']) && $result['installed']) { + $result = $this->_apply_plugin_action((!empty($query['multisite']) && (bool) $query['multisite']) ? 'network_activate' : 'activate', $query); + if (empty($result['activated'])) { + return $result; + } + } else { + return $result; + } + + return $this->_response($result); + } + + /** + * Download, install the plugin + * + * @param array $query Parameter array containing the filesystem credentials entered by the user along with the plugin name and slug + * @return array Contains the result of the current process + */ + public function install_plugin($query) { + + $fields = array('plugin', 'slug'); + $permissions = array('install_plugins'); + + $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); + if (!empty($error)) { + return $error; + } + + $this->_preload_credentials($query); + + $result = $this->_apply_plugin_action('install', $query); + if (empty($result['installed'])) { + return $result; + } + + return $this->_response($result); + } + + /** + * Uninstall/delete the plugin + * + * @param array $query Parameter array containing the filesystem credentials entered by the user along with the plugin name and slug + * @return array Contains the result of the current process + */ + public function delete_plugin($query) { + + $fields = array('plugin'); + $permissions = array('delete_plugins'); + + $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); + if (!empty($error)) { + return $error; + } + + $this->_preload_credentials($query); + + $info = $this->_get_plugin_info($query); + if ($info['installed']) { + // Deactivate first before delete to invalidate the activate + // state/status prior to deleting the item. Otherwise, WordPress will keep + // that state, and as soon as you install the same plugin it will be automatically + // activated since it's previous state was kept. + deactivate_plugins($info['plugin_path']); + + $deleted = delete_plugins(array($info['plugin_path'])); + if ($deleted) { + $result = array('deleted' => true, 'info' => $this->_get_plugin_info($query), 'last_state' => $info); + } else { + return $this->_generic_error_response('delete_plugin_failed', array( + 'plugin' => $query['plugin'], + 'error_code' => 'delete_plugin_failed', + 'info' => $info + )); + } + } else { + return $this->_generic_error_response('plugin_not_installed', array( + 'plugin' => $query['plugin'], + 'error_code' => 'plugin_not_installed', + 'info' => $info + )); + } + + return $this->_response($result); + } + + /** + * Updates/upgrade the plugin + * + * @param array $query Parameter array containing the filesystem credentials entered by the user along with the plugin name and slug + * @return array Contains the result of the current process + */ + public function update_plugin($query) { + + $fields = array('plugin', 'slug'); + $permissions = array('update_plugins'); + + $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); + if (!empty($error)) { + return $error; + } + + $this->_preload_credentials($query); + + // Make sure that we still have the plugin installed before running + // the update process + $info = $this->_get_plugin_info($query); + if ($info['installed']) { + // Load the updates command class if not existed + if (!class_exists('UpdraftCentral_Updates_Commands')) include_once('updates.php'); + $update_command = new UpdraftCentral_Updates_Commands($this->rc); + + $result = $update_command->update_plugin($info['plugin_path'], $query['slug']); + if (!empty($result['error'])) { + $result['values'] = array('plugin' => $query['plugin'], 'info' => $info); + } + } else { + return $this->_generic_error_response('plugin_not_installed', array( + 'plugin' => $query['plugin'], + 'error_code' => 'plugin_not_installed', + 'info' => $info + )); + } + + return $this->_response($result); + } + + /** + * Gets the plugin information along with its active and install status + * + * @internal + * @param array $query Contains either the plugin name or slug or both to be used when retrieving information + * @return array + */ + private function _get_plugin_info($query) { + + $info = array( + 'active' => false, + 'installed' => false + ); + + // Clear plugin cache so that newly installed/downloaded plugins + // gets reflected when calling "get_plugins" + if (function_exists('wp_clean_plugins_cache')) { + wp_clean_plugins_cache(); + } + + // Gets all plugins available. + $get_plugins = get_plugins(); + + // Loops around each plugin available. + foreach ($get_plugins as $key => $value) { + $slug = $this->extract_slug_from_info($key, $value); + + // If the plugin name matches that of the specified name, it will gather details. + // In case name check isn't enough, we'll use slug to verify if the plugin being queried is actually installed. + // + // Reason for name check failure: + // Due to plugin name inconsistencies - where wordpress.org registered plugin name is different + // from the actual plugin files's metadata (found inside the plugin's PHP file itself). + if ((!empty($query['plugin']) && html_entity_decode($value['Name']) === html_entity_decode($query['plugin'])) || (!empty($query['slug']) && $slug === $query['slug'])) { + $info['installed'] = true; + $info['active'] = is_plugin_active($key); + $info['plugin_path'] = $key; + $info['data'] = $value; + $info['name'] = $value['Name']; + $info['slug'] = $slug; + break; + } + } + + return $info; + } + + /** + * Extract the slug from the plugin data + * + * @param string $key They key of the current info + * @param array $info Data pulled from the plugin file + * + * @return string + */ + private function extract_slug_from_info($key, $info) { + if (!is_array($info) || empty($info) || empty($key)) return ''; + + $temp = explode('/', $key); + + // With WP standards textdomain must always be equal to the plugin's folder name + // but for premium plugins this may not always be the case thus, we extract the folder + // name from the key as the default slug. + $slug = basename($temp[0], '.php'); + + if (!empty($info['TextDomain']) && 1 === count($temp)) { + // For plugin without folder we compare the extracted slug with the 'TextDomain' + // and if they're not equal then 'TextDomain' will assume as slug. + if ($slug != $info['TextDomain']) $slug = $info['TextDomain']; + } + + // If in case the user kept the hello-dolly plugin then we'll make sure that it gets + // the proper slug for it, otherwise, we'll end up with the wrong slug 'hello' instead of + // 'hello-dolly'. Wrong slug will produce error in UpdraftCentral when running it against + // wordpress.org for further information retrieval. + $slug = ('Hello Dolly' === $info['Name']) ? 'hello-dolly' : $slug; + + return $slug; + } + + /** + * Loads all available plugins with additional attributes and settings needed by UpdraftCentral + * + * @param array $query Parameter array Any available parameters needed for this action + * @return array Contains the result of the current process + */ + public function load_plugins($query) { + + $permissions = array('install_plugins', 'activate_plugins'); + if (is_multisite() && !is_super_admin(get_current_user_id())) $permissions = array('activate_plugins'); + + $error = $this->_validate_fields_and_capabilities($query, array(), $permissions); + if (!empty($error)) { + return $error; + } + + $website = get_bloginfo('name'); + $results = array(); + + // Load the updates command class if not existed + if (!class_exists('UpdraftCentral_Updates_Commands')) include_once('updates.php'); + $updates = new UpdraftCentral_Updates_Commands($this->rc); + + // Get plugins for update + $plugin_updates = $updates->get_item_updates('plugins'); + + // Get all plugins + $plugins = get_plugins(); + + if (is_multisite() && !is_super_admin(get_current_user_id())) { + + // If the "Plugins" menu is disabled for the subsites on a multisite + // network then we return an empty "plugins" array. + $menu_items = get_site_option('menu_items'); + if (empty($menu_items) || !isset($menu_items['plugins'])) { + $plugins = array(); + } else { + $show_network_active = apply_filters('show_network_active_plugins', current_user_can('manage_network_plugins')); + + $filtered_plugins = array(); + foreach ($plugins as $file => $data) { + if (is_network_only_plugin($file) && !is_plugin_active($file)) { + if ($show_network_active) $filtered_plugins[$file] = $data; + } elseif (is_plugin_active_for_network($file)) { + if ($show_network_active) $filtered_plugins[$file] = $data; + } else { + $filtered_plugins[$file] = $data; + } + } + + $plugins = $filtered_plugins; + } + } + + foreach ($plugins as $key => $value) { + $slug = $this->extract_slug_from_info($key, $value); + + $plugin = new stdClass(); + $plugin->name = $value['Name']; + $plugin->description = $value['Description']; + $plugin->slug = $slug; + $plugin->version = $value['Version']; + $plugin->author = $value['Author']; + $plugin->status = is_plugin_active($key) ? 'active' : 'inactive'; + $plugin->website = $website; + $plugin->multisite = is_multisite(); + $plugin->site_url = trailingslashit(get_bloginfo('url')); + + if (!empty($plugin_updates[$key])) { + $update_info = $plugin_updates[$key]; + + if (version_compare($update_info->Version, $update_info->update->new_version, '<')) { + if (!empty($update_info->update->new_version)) $plugin->latest_version = $update_info->update->new_version; + if (!empty($update_info->update->package)) $plugin->download_link = $update_info->update->package; + if (!empty($update_info->update->sections)) $plugin->sections = $update_info->update->sections; + } + } + + if (empty($plugin->short_description) && !empty($plugin->description)) { + // Only pull the first sentence as short description, it should be enough rather than displaying + // an empty description or a full blown one which the user can access anytime if they press on + // the view details link in UpdraftCentral. + $temp = explode('.', $plugin->description); + $short_description = $temp[0]; + + // Adding the second sentence wouldn't hurt, in case the first sentence is too short. + if (isset($temp[1])) $short_description .= '.'.$temp[1]; + + $plugin->short_description = $short_description.'.'; + } + + $results[] = $plugin; + } + + $result = array( + 'plugins' => $results, + 'is_super_admin' => is_super_admin(), + ); + + $result = array_merge($result, $this->_get_backup_credentials_settings(WP_PLUGIN_DIR)); + return $this->_response($result); + } + + /** + * Gets the backup and security credentials settings for this website + * + * @param array $query Parameter array Any available parameters needed for this action + * @return array Contains the result of the current process + */ + public function get_plugin_requirements() { + return $this->_response($this->_get_backup_credentials_settings(WP_PLUGIN_DIR)); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/posts.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/posts.php new file mode 100755 index 00000000..bbe3ac13 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/posts.php @@ -0,0 +1,2034 @@ +switched = switch_to_blog($blog_id); + } + } + + /** + * Function that gets called after every action + * + * @param string $command a string that corresponds to UDC command to call a certain method for this class. + * @param array $data an array of data post or get fields + * @param array $extra_info extrainfo use in the udrpc_action, e.g. user_id + * + * link to udrpc_action main function in class UpdraftCentral_Listener + */ + public function _post_action($command, $data, $extra_info) {// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found, VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable + // Here, we're restoring to the current (default) blog before we switched + if ($this->switched) restore_current_blog(); + } + + /** + * Returns the keys and fields names that are associated to a particular module type + * + * @param string $type The type of the module that the current request is processing + * + * @return array + */ + private function get_state_fields_by_type($type) { + $state_fields = array( + 'post' => array( + 'validation_fields' => array('publish_posts', 'edit_posts', 'delete_posts'), + 'items_key' => 'posts', + 'count_key' => 'posts_count', + 'list_key' => 'posts', + 'result_key' => 'get', + 'error_key' => 'post_state_change_failed' + ), + 'page' => array( + 'validation_fields' => array('publish_pages', 'edit_pages', 'delete_pages'), + 'items_key' => 'pages', + 'count_key' => 'pages_count', + 'list_key' => 'pages', + 'result_key' => 'get', + 'error_key' => 'page_state_change_failed' + ) + ); + + if (!isset($state_fields[$type])) return array(); + return $state_fields[$type]; + } + + /** + * Fetch and retrieves posts based from the submitted parameters + * + * @param array $params Containing all the needed information to filter the results of the current request + * @return array + */ + public function get($params) { + + $state_fields = $this->get_state_fields_by_type($this->post_type); + if (empty($state_fields)) return $this->_generic_error_response('unsupported_type_on_get_posts'); + + $error = $this->_validate_capabilities($state_fields['validation_fields']); + if (!empty($error)) return $error; + + // check paged parameter; if empty set to defaults + $paged = !empty($params['paged']) ? (int) $params['paged'] : 1; + $numberposts = !empty($params['numberposts']) ? (int) $params['numberposts'] : 10; + $offset = ($paged - 1) * $numberposts; + + $args = array( + 'posts_per_page' => $numberposts, + 'paged' => $paged, + 'offset' => $offset, + 'post_type' => $this->post_type, + 'post_status' => 'publish,private,draft,pending,future', + ); + + if (!empty($params['keyword'])) { + $args['s'] = $params['keyword']; + } + + if ('post' == $this->post_type) { + if (!empty($params['category'])) { + $args['cat'] = (int) $params['category']; + } + } + + if (!empty($params['date'])) { + list($monthnum, $year) = explode(':', $params['date']); + + $args['monthnum'] = $monthnum; + $args['year'] = $year; + } + + if (!empty($params['status']) && 'all' !== $params['status']) { + $args['post_status'] = $params['status']; + } + + $query = new WP_Query($args); + $result = $query->posts; + + $count_posts = (int) $query->found_posts; + $page_count = 0; + + if ($count_posts > 0) { + $page_count = absint($count_posts / $numberposts); + $remainder = absint($count_posts % $numberposts); + $page_count = ($remainder > 0) ? ++$page_count : $page_count; + } + + $info = array( + 'page' => $paged, + 'pages' => $page_count, + 'results' => $count_posts, + 'items_from' => (($paged * $numberposts) - $numberposts) + 1, + 'items_to' => ($paged == $page_count) ? $count_posts : $paged * $numberposts, + ); + + $posts = array(); + if (!empty($result)) { + foreach ($result as $post) { + // Pulling any other relevant and additional information regarding + // the post before returning it in the response. + $postdata = $this->get_postdata($post, false); + if (!empty($postdata)) { + array_push($posts, $postdata); + } + } + } + + $response = array( + $state_fields['items_key'] => $posts, + 'options' => $this->get_options($this->post_type), + 'info' => $info, + $state_fields['count_key'] => $this->get_post_status_counts($this->post_type) + ); + + // Load any additional information if preload parameter is set. Will only be + // requested on initial load of items in UpdraftCentral. + if (isset($params['preload']) && $params['preload']) { + $timeout = !empty($params['timeout']) ? $params['timeout'] : 30; + $response = array_merge($response, $this->get_preload_data($timeout, $this->post_type)); + } + + return $this->_response($response); + } + + /** + * Extracts public properties from complex object and return a simple + * object (stdClass) that contains the public properties of the original object. + * + * @param object $obj Any type of complex objects that needs converting (e.g. WP_Taxonomy, WP_Term or WP_User) + * @return stdClass + */ + protected function trim_object($obj) { + // To preserve the object's accessibility through its properties we recreate + // the object using the stdClass and fill it with the public properties + // that will be extracted from the original object ($obj). + $newObj = new stdClass(); + + if (is_object($obj)) { + // Making sure that we only extract those publicly accessible properties excluding + // the private, protected, static ones and methods. + $props = get_object_vars($obj); + if (!empty($props)) { + foreach ($props as $key => $value) { + $newObj->{$key} = $value; + } + } + } + + return $newObj; + } + + /** + * Retrieves information that will be preloaded in UC for quick and easy access + * when editing a certain page or post + * + * @param int $timeout The user-defined timeout from UpdraftCentral + * @param string $type The type of the module that the current request is processing + * + * @return array + */ + protected function get_preload_data($timeout, $type = 'post') { + global $updraftcentral_host_plugin, $updraftcentral_main; + + if (!function_exists('get_page_templates')) { + require_once(ABSPATH.'wp-admin/includes/theme.php'); + } + + $templates = ('post' == $type) ? get_page_templates(null, 'post') : get_page_templates(); + if (!empty($templates)) { + $templates = array_flip($templates); + if (!isset($templates['default'])) { + $templates['default'] = $updraftcentral_host_plugin->retrieve_show_message('default_template'); + } + } + + // Preloading elements saves time and avoid unnecessary round trips to fetch + // these information individually. + $authors = $this->get_authors(); + $parent_pages = $this->get_parent_pages(); + + $data = array( + 'authors' => $authors['data']['authors'], + 'parent_pages' => $parent_pages['data']['pages'], + 'templates' => $templates, + 'editor_styles' => $this->get_editor_styles($timeout), + 'wp_version' => $updraftcentral_main->get_wordpress_version() + ); + + if ('post' == $type) { + $categories = $this->get_categories(); + $tags = $this->get_tags(); + + $data['taxonomies'] = $this->get_taxonomies(); + $data['categories'] = $categories['data']; + $data['tags'] = $tags['data']; + } + + global $post; + $context = class_exists('WP_Block_Editor_Context') ? new WP_Block_Editor_Context(array('post' => $post)) : $post; + + // Load block patterns from w.org. + if (function_exists('_load_remote_block_patterns')) _load_remote_block_patterns(); + if (function_exists('_load_remote_featured_patterns')) _load_remote_featured_patterns(); + + $block_types = class_exists('WP_Block_Type_Registry') ? WP_Block_Type_Registry::get_instance()->get_all_registered() : array(); + $block_patterns = class_exists('WP_Block_Patterns_Registry') ? WP_Block_Patterns_Registry::get_instance()->get_all_registered() : array(); + $block_pattern_categories = class_exists('WP_Block_Pattern_Categories_Registry') ? WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered() : array(); + $block_styles = class_exists('WP_Block_Styles_Registry') ? WP_Block_Styles_Registry::get_instance()->get_all_registered() : array(); + + $block_data = array( + 'block_categories' => get_block_categories($context), + 'block_definitions' => get_block_editor_server_block_settings(), + 'block_types' => $block_types, + 'block_patterns' => $block_patterns, + 'block_pattern_categories' => $block_pattern_categories, + 'block_styles' => $block_styles + ); + $data = array_merge($data, $block_data); + + return array( + 'preloaded' => json_encode($data) + ); + } + + /** + * Extract content from the given css path + * + * @param string $style CSS file path + * @param int $timeout The user-defined timeout from UpdraftCentral + * @return array + */ + protected function extract_css_content($style, $timeout) { + + $content = ''; + if (1 === preg_match('~^(https?:)?//~i', $style)) { + $response = wp_remote_get($style, array('timeout' => $timeout)); + if (!is_wp_error($response)) { + $result = trim(wp_remote_retrieve_body($response)); + if (!empty($result)) $content = $result; + } + } else { + // Editor styles that resides in "css/dist" + if (false !== ($pos = stripos($style, 'css/dist'))) { + $file = ABSPATH.WPINC.substr_replace($style, '/', 0, $pos); + } else { + // Styles that resides in "wp-content/themes" (coming from $editor_styles global var) + $file = get_theme_file_path($style); + } + + $is_valid = (function_exists('is_file')) ? is_file($file) : file_exists($file); + if ($is_valid) { + $result = trim(file_get_contents($file)); + if (!empty($result)) $content = $result; + } + } + + return $this->extract_custom_fonts($this->filter_url($content)); + } + + /** + * Extract custom fonts defined within the css content. Basically, + * separating custom font (@font-face) rules from the Style/css content. + * + * @param string $content Style content + * @return array + */ + protected function extract_custom_fonts($content) { + $fonts = array(); + while ($start = strpos($content, '@font-face')) { + $end = strpos($content, '}', $start) + 1; + $length = $end - $start; + + $font = substr($content, $start, $length); + $fonts[]= $this->update_font_src($font); + + $content = str_replace($font, '', $content); + } + + return array( + 'content' => $content, + 'fonts' => $fonts + ); + } + + /** + * Updates the font URL to point to the UpdraftCentral "load_font" action + * + * @param string $font Font-face definition/content + * @return string + */ + protected function update_font_src($font) { + $start = strpos($font, 'src:') + 4; + $end = strpos($font, ';', $start); + $length = $end - $start; + + $src = trim(substr($font, $start, $length)); + $temp = explode(' ', $src); + preg_match('/^url\((.*)\)$/i', $temp[0], $matches); + + $url = ''; + if (!empty($matches)) { + $url = trim(trim($matches[1], "'"), '"'); + if (strlen($url)) { + $font_url = 'CENTRAL_URL/?udcentral_action=load_font&font='.urlencode($url); + $font = str_replace($url, $font_url, $font); + } + } + return $font; + } + + /** + * Convert URL entries contained in the CSS content to absolute URLs + * + * @param string $content The content of the CSS file + * @return string + */ + protected function filter_url($content) { + + // Replace with valid URL (absolute) + preg_match_all('~url\((.+?)\)~i', $content, $all_matches); + if (!empty($all_matches) && isset($all_matches[1])) { + $urls = array_unique($all_matches[1]); + foreach ($urls as $url) { + $url = str_replace('"', '', $url); + if (false !== strpos($url, 'data:')) continue; + + if (1 !== preg_match('~^(https?:)?//~i', $url)) { + if (1 === preg_match('~(plugins|themes)~i', $url, $matches)) { + if (false !== ($pos = stripos($url, $matches[1]))) { + if (!function_exists('content_url')) { + require_once ABSPATH.WPINC.'/link-template.php'; + } + + $absolute_url = rtrim(content_url(), '/').substr_replace($url, '/', 0, $pos); + $content = str_replace($url, $absolute_url, $content); + } + } else { + $path = preg_replace('~(\.+\/)~', '', $url); + $dirpath = trailingslashit(get_stylesheet_directory()); + if (!file_exists($dirpath.$url)) $path = $this->resolve_path($path); + + $absolute_url = (!empty($path)) ? trailingslashit(get_stylesheet_directory_uri()).ltrim($path, '/') : ''; + $content = str_replace($url, $absolute_url, $content); + } + } + } + } + + return $content; + } + + /** + * Resolve URL to its actual absolute path + * + * @param string $path Some relative path to check + * @return string + */ + protected function resolve_path($path) { + $dir = trailingslashit(get_stylesheet_directory()); + // Some relative paths declared within the css file (e.g. only has '../fonts/etc/', called deep down from a subfolder) where parent + // subfolder is not articulated needs to be resolve further to get its actual absolute path. Using glob will pinpoint its actual location + // rather than iterating through a series of sublevels just to find the actual file. + $result = str_replace($dir, '', glob($dir.'{,*/}{'.$path.'}', GLOB_BRACE)); + + if (!empty($result)) return $result[0]; + return false; + } + + /** + * Retrieves block editor assets for iframe. + * + * @return string + */ + protected function get_iframed_editor_assets() { + $script_handles = array(); + $style_handles = array( + 'wp-block-editor', + 'wp-block-library', + 'wp-block-library-theme', + 'wp-edit-blocks', + ); + + if (class_exists('WP_Block_Type_Registry')) { + $block_registry = WP_Block_Type_Registry::get_instance(); + foreach ($block_registry->get_all_registered() as $block_type) { + if (!empty($block_type->style)) { + if (is_array($block_type->style)) { + $style_handles = array_merge($style_handles, $block_type->style); + } else { + $style_handles[] = $block_type->style; + } + } + + if (!empty($block_type->editor_style)) { + if (is_array($block_type->editor_style)) { + $style_handles = array_merge($style_handles, $block_type->editor_style); + } else { + $style_handles[] = $block_type->editor_style; + } + } + + if (!empty($block_type->script)) { + if (is_array($block_type->script)) { + $script_handles = array_merge($script_handles, $block_type->script); + } else { + $script_handles[] = $block_type->script; + } + } + } + } + + $style_handles = array_unique($style_handles); + $done = wp_styles()->done; + + ob_start(); + // We do not need reset styles for the iframed editor. + wp_styles()->done = array('wp-reset-editor-styles'); + wp_styles()->do_items($style_handles); + wp_styles()->done = $done; + $styles = ob_get_clean(); + + $script_handles = array_unique($script_handles); + $done = wp_scripts()->done; + + ob_start(); + wp_scripts()->done = array(); + wp_scripts()->do_items($script_handles); + wp_scripts()->done = $done; + $scripts = ob_get_clean(); + + return wp_json_encode(array( + 'styles' => $styles, + 'scripts' => $scripts, + )); + } + + /** + * Retrieve the editor styles/assets to be use by UpdraftCentral when editing a post + * + * @param int $timeout The user-defined timeout from UpdraftCentral + * @return array() + */ + protected function get_editor_styles($timeout) { + global $editor_styles, $wp_styles; + $editing_styles = $loaded = array(); + $fonts = ''; + + $required = array('css/dist/editor/style.css', 'css/dist/block-library/style.css', 'css/dist/block-library/theme.css'); + foreach ($required as $style) { + $result = $this->extract_css_content($style, $timeout); + if (!empty($result['fonts'])) $fonts .= implode('', $result['fonts']); + $editing_styles[] = array('css' => $result['content'], 'inline' => ''); + }; + + do_action('enqueue_block_assets'); + do_action('enqueue_block_editor_assets'); + do_action('wp_enqueue_scripts'); + + // Checking for editor styles support since styles may vary from theme to theme + if ($editor_styles) { + foreach ($editor_styles as $style) { + if (false !== array_search($style, $loaded)) continue; + + $result = $this->extract_css_content($style, $timeout); + if (!empty($result['fonts'])) $fonts .= implode('', $result['fonts']); + $editing_styles[] = array('css' => $result['content'], 'inline' => ''); + $loaded[] = $style; + } + } + + if ($wp_styles) { + foreach ($wp_styles->queue as $handle) { + $style = $wp_styles->registered[$handle]->src; + if (false !== array_search($style, $loaded)) continue; + + $result = $this->extract_css_content($style, $timeout); + if (!empty($result['fonts'])) $fonts .= implode('', $result['fonts']); + + $inline_style = $wp_styles->print_inline_style($handle, false); + if ($inline_style) { + $inline_result = $this->extract_custom_fonts($inline_style); + if (!empty($inline_result['fonts'])) $fonts .= implode('', $inline_result['fonts']); + } + + $editing_styles[] = array( + 'css' => $result['content'], + 'inline' => (!$inline_style) ? '' : $inline_result['content'] + ); + $loaded[] = $style; + } + } + + // Introduced in 5.9.0 + if (function_exists('wp_get_global_stylesheet')) { + $result = $this->extract_custom_fonts(wp_get_global_stylesheet()); + if (!empty($result['fonts'])) $fonts .= implode('', $result['fonts']); + $editing_styles[] = array('css' => $result['content'], 'inline' => ''); + } + + // Introduced in 5.8.0 + if (function_exists('get_block_editor_settings')) { + $block_editor_context = new WP_Block_Editor_Context(); + $settings = get_block_editor_settings(array(), $block_editor_context); + + // Don't render but instead attached to the editor before load. + // We let the editor render these kind of styles as they need to be prefixed + // by the editor based on the current context. + // + // N.B. Leave the 'css' property empty. It is used for downward compatibility. + $editing_styles[] = array('editor_css' => $settings['styles'], 'inline' => '', 'css' => ''); + + // Get editor assets (e.g. styles) for iframe, mostly used for previewing blocks and patterns + $editing_styles[] = array('editor_assets' => $this->get_iframed_editor_assets(), 'inline' => '', 'css' => ''); + } + + $result = $this->extract_css_content('/style.css', $timeout); + if (!empty($result['fonts'])) $fonts .= implode('', $result['fonts']); + + $editing_styles[] = array('css' => $result['content'], 'inline' => ''); + if (strlen($fonts)) { + $editing_styles[] = array('font_css' => $fonts, 'inline' => '', 'css' => ''); + } + + // These styles are used if the "no theme styles" options is triggered or on + // themes without their own editor styles. + $default_editor_styles_file = ABSPATH.WPINC.'/css/dist/block-editor/default-editor-styles.css'; + if (file_exists($default_editor_styles_file)) { + $editing_styles[] = array('default_editor_css' => file_get_contents($default_editor_styles_file), 'inline' => '', 'css' => ''); + } + + // Extract fonts from theme.json if the current theme supports it + $resolver = ABSPATH.WPINC.'/class-wp-theme-json-resolver.php'; + if (!class_exists('WP_Theme_JSON_Resolver') && file_exists($resolver)) { + require_once($resolver); + } + + $theme_has_support = false; + if (function_exists('wp_theme_has_theme_json')) { + $theme_has_support = wp_theme_has_theme_json(); + } else { + if (class_exists('WP_Theme_JSON_Resolver')) { + $theme_has_support = WP_Theme_JSON_Resolver::theme_has_support(); + } + } + + if (class_exists('WP_Theme_JSON_Resolver') && $theme_has_support) { + $theme_json = ABSPATH.WPINC.'/class-wp-theme-json.php'; + if (!class_exists('WP_Theme_JSON') && file_exists($theme_json)) require_once($theme_json); + + $theme_json_instance = WP_Theme_JSON_Resolver::get_theme_data(); + if ($theme_json_instance) { + $settings = $theme_json_instance->get_settings(); + $theme_fonts = ''; + + if (isset($settings['typography']) && isset($settings['typography']['fontFamilies'])) { + $font_families = $settings['typography']['fontFamilies']; + if (isset($font_families['theme'])) { + foreach ($font_families['theme'] as $theme) { + if (isset($theme['fontFace'])) { + foreach ($theme['fontFace'] as $font) { + $theme_fonts .= '@font-face {'; + $keys = array_keys($font); + + foreach ($keys as $key) { + if (false !== stripos($key, 'font')) { + $prop = 'font-'.strtolower(str_replace('font', '', $key)); + $theme_fonts .= $prop.': '.$font[$key].';'; + } elseif (false !== stripos($key, 'src')) { + foreach ($font['src'] as $src_file) { + $url = trailingslashit(get_stylesheet_directory_uri()).str_replace('file:./', '', $src_file); + $theme_fonts .= 'src: url(CENTRAL_URL/?udcentral_action=load_font&font='.urlencode($url).');'; + } + } + } + $theme_fonts .= '}'; + } + } + } + } + } + $editing_styles[] = array('theme_json_fonts' => $theme_fonts, 'inline' => '', 'css' => ''); + } + } + + return $editing_styles; + } + + /** + * Retrieves the total number of items found under each post statuses + * + * @param string $type The type of the module that the current request is processing + * + * @return array + */ + protected function get_post_status_counts($type = 'post') { + $posts = wp_count_posts($type); + + $publish = (int) $posts->publish; + $private = (int) $posts->private; + $draft = (int) $posts->draft; + $pending = (int) $posts->pending; + $future = (int) $posts->future; + $trash = (int) $posts->trash; + + // We exclude "trash" from the overall total as WP doesn't actually + // consider or include it in the total count. + $all = $publish + $private + $draft + $pending + $future; + + return array( + 'all' => $all, + 'publish' => $publish, + 'private' => $private, + 'draft' => $draft, + 'pending' => $pending, + 'future' => $future, + 'trash' => $trash, + ); + } + + /** + * Retrieves a collection of formatted dates found for the given post statuses. + * It will be used as options for the date filter when managing the posts in UpdraftCentral. + * + * @param string $type The type of the module that the current request is processing + * + * @return array + */ + protected function get_date_options($type = 'post') { + global $wpdb; + + $date_options = $wpdb->get_col("SELECT DATE_FORMAT(`post_date`, '%M %Y') as `formatted_post_date` FROM {$wpdb->posts} WHERE `post_type` = '{$type}' AND `post_status` IN ('publish', 'private', 'draft', 'pending', 'future') GROUP BY `formatted_post_date` ORDER BY `post_date` DESC"); + + return $date_options; + } + + /** + * Make sure that we have the required fields to use in UpdraftCentral for + * displaying the categories and tags sections. Add if missing. + * + * @param object $item Taxonomy item to check + * @return object + */ + protected function map_tax($item) { + $taxs = array('category' => 'categories', 'post_tag' => 'tags'); + if (array_key_exists($item->name, $taxs)) { + if (!isset($item->show_in_rest)) $item->show_in_rest = true; + if (!isset($item->rest_base)) $item->rest_base = $taxs[$item->name]; + } + + return $item; + } + + /** + * Fetch and retrieves available taxonomies for this site and some capabilities specific + * to tags and categories when managing them. + * + * @return array + */ + protected function get_taxonomies() { + $taxonomies = get_taxonomies(array(), 'objects'); + $taxonomies = array_map(array($this, 'map_tax'), $taxonomies); + + $response = array( + 'taxonomies' => $taxonomies, + 'current_user_cap' => array( + 'manage_categories' => current_user_can('manage_categories'), + 'edit_categories' => current_user_can('edit_categories'), + 'delete_categories' => current_user_can('delete_categories'), + 'assign_categories' => current_user_can('assign_categories'), + 'manage_post_tags' => current_user_can('manage_post_tags'), + 'edit_post_tags' => current_user_can('edit_post_tags'), + 'delete_post_tags' => current_user_can('delete_post_tags'), + 'assign_post_tags' => current_user_can('assign_post_tags'), + ) + ); + + return $response; + } + + /** + * Fetch and retrieves categories based from the submitted parameters + * + * @param array $query Containing all the needed information to filter the results of the current request + * @return array + */ + public function get_categories($query = array()) { + $page = !empty($query['page']) ? (int) $query['page'] : 1; + $items_per_page = !empty($query['per_page']) ? (int) $query['per_page'] : 100; + $offset = ($page - 1) * $items_per_page; + $order = !empty($query['order']) ? $query['order'] : 'asc'; + $orderby = !empty($query['orderby']) ? $query['orderby'] : 'name'; + + $args = array( + 'hide_empty' => false, + 'orderby' => $orderby, + 'order' => $order, + 'number' => $items_per_page, + 'offset' => $offset + ); + + $categories = get_categories($args); + $category_options = array(); + + if (!empty($categories)) { + foreach ($categories as $key => $term) { + $parent_term = get_term((int) $term->parent, $term->taxonomy); + if (!is_wp_error($parent_term) && !is_null($parent_term)) { + $parent_term = json_encode($this->trim_object($parent_term)); + } else { + $parent_term = ''; + } + + $category_options[] = array( + 'id' => $term->term_id, + 'name' => $term->name, + 'parent' => $term->parent + ); + + $categories[$key] = array( + 'term' => json_encode($this->trim_object($term)), + 'misc' => array( + 'link' => get_term_link($term), + 'parent_term' => $parent_term, + 'taxonomy' => $term->taxonomy + ) + ); + } + } + + $categorytax = get_taxonomy('category'); + $parent_dropdown_args = array( + 'taxonomy' => 'category', + 'hide_empty' => 0, + 'name' => 'newcategory_parent', + 'orderby' => 'name', + 'hierarchical' => 1, + 'show_option_none' => '— '.$categorytax->labels->parent_item.' —', + 'echo' => false + ); + + $parent_dropdown_args = apply_filters('post_edit_category_parent_dropdown_args', $parent_dropdown_args); + $parent_dropdown = wp_dropdown_categories($parent_dropdown_args); + + if (!function_exists('wp_popular_terms_checklist')) { + require_once ABSPATH . 'wp-admin/includes/template.php'; + } + + ob_start(); + wp_popular_terms_checklist('category'); + $popular_terms_checklist = ob_get_contents(); + ob_end_clean(); + + return $this->_response(array( + 'terms' => $categories, + 'misc' => array( + 'formatted' => $category_options, + 'raw' => $categories, + 'tax' => json_encode($this->trim_object($categorytax)), + 'popular' => $popular_terms_checklist, + 'parent_dropdown' => $parent_dropdown, + 'capabilities' => array( + 'can_edit_terms' => current_user_can($categorytax->cap->edit_terms) + ) + ) + )); + } + + /** + * Fetch and retrieves tags based from the submitted parameters + * + * @param array $query Containing all the needed information to filter the results of the current request + * @return array + */ + public function get_tags($query = array()) { + $page = !empty($query['page']) ? (int) $query['page'] : 1; + $items_per_page = !empty($query['per_page']) ? (int) $query['per_page'] : 100; + $offset = ($page - 1) * $items_per_page; + $order = !empty($query['order']) ? $query['order'] : 'desc'; + $orderby = !empty($query['orderby']) ? $query['orderby'] : 'count'; + + $args = array( + 'hide_empty' => false, + 'orderby' => $orderby, + 'order' => $order, + 'number' => $items_per_page, + 'offset' => $offset + ); + + $tags = get_tags($args); + $tag_options = array(); + $tag_cloud = ''; + + if (!empty($tags)) { + $tags_for_cloud = array(); + foreach ($tags as $key => $term) { + if (!isset($term->link)) $term->link = get_tag_link($term->term_id); + array_push($tags_for_cloud, $term); + + $parent_term = get_term((int) $term->parent, $term->taxonomy); + if (!is_wp_error($parent_term) && !is_null($parent_term)) { + $parent_term = json_encode($this->trim_object($parent_term)); + } else { + $parent_term = ''; + } + + $tag_options[] = array( + 'id' => $term->term_id, + 'name' => $term->name, + ); + + $tags[$key] = array( + 'term' => json_encode($this->trim_object($term)), + 'misc' => array( + 'link' => get_term_link($term), + 'parent_term' => $parent_term, + 'taxonomy' => $term->taxonomy + ) + ); + } + + add_filter('tag_cloud_sort', array($this, 'sort_tag_cloud'), 9, 2); + + if (!function_exists('wp_generate_tag_cloud')) { + require_once ABSPATH.WPINC.'/category-template.php'; + } + + $tag_cloud = wp_generate_tag_cloud($tags_for_cloud, array( + 'smallest' => 10, + 'largest' => 22, + 'unit' => 'pt', + 'number' => 10, + 'format' => 'flat', + 'separator' => " ", + 'orderby' => 'count', + 'order' => 'DESC', + 'show_count' => 1, + 'echo' => false + )); + } + + $tagtax = get_taxonomy('post_tag'); + return $this->_response(array( + 'terms' => $tags, + 'misc' => array( + 'formatted' => $tag_options, + 'raw' => $tags, + 'tax' => json_encode($this->trim_object($tagtax)), + 'tag_cloud' => $tag_cloud, + 'capabilities' => array( + 'can_assign_terms' => current_user_can($tagtax->cap->assign_terms) + ) + ) + )); + } + + /** + * Sorts the tag items that are to be shown within the tag cloud + * + * @param array $tags The array to be sorted. Contains the tag items + * @param array $args Additional parameters needed for the sorting process + * @return array + */ + public function sort_tag_cloud($tags, $args) { + uasort($tags, array($this, '_wp_object_count_sort_cb')); + if ('DESC' === $args['order']) { + $tags = array_reverse($tags, true); + } + + return $tags; + } + + /** + * Serves as a callback for comparing objects based on count. Copied from WordPress 5.7 + * core (wp-includes/category-template.php) and tweaked to return integer instead of boolean + * because returning boolean using uasort is now DEPRECATED in PHP 8. + * + * Used with `uasort()`. + * + * @since 3.1.0 + * @access private + * + * @param object $a The first object to compare. + * @param object $b The second object to compare. + * @return bool Whether the count value for `$a` is greater than the count value for `$b`. + */ + public function _wp_object_count_sort_cb($a, $b) { + if ($a->count == $b->count) { + return 0; + } + return ( $a->count > $b->count ) ? 1 : -1; + } + + /** + * Fetch all available taxonomies and terms information for the given post object + * + * @param array $post The "Post" object to use when retrieving the information + * @return array + */ + protected function get_taxonomies_terms($post) { + $taxonomies = get_object_taxonomies($post->post_type, 'objects'); + $taxonomies = array_map(array($this, 'map_tax'), $taxonomies); + + $taxonomy_names = array(); + $taxonomy_terms = array(); + $taxonomy_caps = array(); + + foreach ($taxonomies as $taxonomy) { + $terms = get_the_terms($post->ID, $taxonomy->name); + $terms = !is_array($terms) ? (array) $terms : $terms; + + $taxonomy_terms[$taxonomy->name] = $terms; + $taxonomy_caps[$taxonomy->name] = array( + 'hierarchical' => is_taxonomy_hierarchical($taxonomy->name), + 'edit_terms' => current_user_can($taxonomy->cap->edit_terms), + 'assign_terms' => current_user_can($taxonomy->cap->assign_terms), + ); + array_push($taxonomy_names, $taxonomy->name); + } + + return array( + 'objects' => $taxonomies, + 'names' => $taxonomy_names, + 'terms' => $taxonomy_terms, + 'caps' => $taxonomy_caps, + ); + } + + /** + * Take over the current editing of the post + * + * @param array $params An array of data that serves as parameters for the given request + * @return array + */ + public function take_over($params) { + + $error = $this->_validate_capabilities(array('edit_'.$this->post_type.'s')); + if (!empty($error)) return $error; + + $result = array('lock_acquired' => false); + if (!empty($params['post_id'])) { + if (!function_exists('wp_set_post_lock')) { + require_once ABSPATH.'wp-admin/includes/post.php'; + } + $lock = wp_set_post_lock($params['post_id']); + + if (!empty($lock)) { + $result = array( + 'lock_acquired' => true, + 'details' => $lock + ); + } + } + + return $this->_response($result); + } + + /** + * Retrieves the underlying data for the given post. Some extra information are + * passed along that will be consumed by the editor in UpdraftCentral + * + * @param int|object $param Post object or a post ID + * @param boolean $encode True to encode the post object, false otherwise + * @return array + */ + public function get_postdata($param, $encode = true) { + $response = array(); + + if (is_object($param) && isset($param->ID)) { + $post = $param; + } elseif (is_numeric($param)) { + $post = get_post($param); + } + + if ($post) { + $post_type_obj = get_post_type_object($post->post_type); + + $is_post_type_viewable = false; + if (!empty($post_type_obj)) { + $is_post_type_viewable = $post_type_obj->publicly_queryable || ($post_type_obj->_builtin && $post_type_obj->public); + } + + if (!function_exists('get_sample_permalink')) { + require_once ABSPATH.'wp-admin/includes/post.php'; + } + + // Validate template exists on the current theme, otherwise, + // reset the template to default. + $template = get_page_template_slug($post->ID); + if (!empty($template)) { + $page_templates = wp_get_theme()->get_page_templates($post); + if ('default' != $template && !isset($page_templates[$template])) { + update_post_meta($post->ID, '_wp_page_template', 'default'); + } + } + + $published_date = array( + 'jj' => date('d', strtotime($post->post_date)), + 'mm' => date('m', strtotime($post->post_date)), + 'aa' => date('Y', strtotime($post->post_date)), + 'hh' => date('H', strtotime($post->post_date)), + 'mn' => date('i', strtotime($post->post_date)), + 'ss' => date('s', strtotime($post->post_date)) + ); + + $sample_permalink = get_sample_permalink($post->ID, $post->post_title, ''); + $permalink = get_permalink($post->ID); + $slug = $post->post_name; + + if (!empty($sample_permalink) && !empty($slug)) { + if (isset($sample_permalink[0])) { + if (false !== stripos($sample_permalink[0], '%pagename%/') || false !== stripos($sample_permalink[0], '%postname%/')) { + $token = (false !== stripos($sample_permalink[0], '%pagename%/')) ? '%pagename%/' : '%postname%/'; + $permalink = str_replace($token, '', $sample_permalink[0]).$slug; + } + } + } + + $editor = null; + $editor_id = wp_check_post_lock($post->ID); + if ($editor_id) { + $editor = get_userdata($editor_id); + if (!$editor) { + // The user with lock does not exist. This can happen if you created a backup or clone + // where you excluded the users table during the process and you restore this backup to + // a different site or the user was deleted or removed more recently. Thus, we will + // release the lock so that other users with the right permission can edit the post. + delete_post_meta($post->ID, '_edit_lock'); + } + } + + $response = array( + 'post' => $encode ? json_encode($post) : $post, + 'misc' => array( + 'guid_rendered' => apply_filters('get_the_guid', $post->guid, $post->ID), + 'link' => $permalink, + 'slug' => $slug, + 'site_url' => site_url('/'), + 'title_rendered' => get_the_title($post->ID), + 'content_rendered' => apply_filters('the_content', $post->post_content), + 'excerpt' => $post->post_excerpt, + 'featured_media' => 0, + 'sticky' => is_sticky($post->ID), + 'template' => get_page_template_slug($post->ID), + 'permalink_template' => get_permalink($post->ID, true), + 'author_name' => get_the_author_meta('display_name', $post->post_author), + 'publish_month_year' => date('F Y', strtotime($post->post_date)), + 'publish_month_year_date' => date('d F Y', strtotime($post->post_date)), + 'post_status_object' => get_post_status_object(get_post_status($post->ID)), + 'published_date' => $published_date, + 'format' => get_post_format($post->ID), + 'post_type_name' => $post_type_obj->name, + 'post_type_viewable' => $is_post_type_viewable, + 'post_type_public' => $post_type_obj->public, + 'post_type_hierarchical' => $post_type_obj->hierarchical, + 'sample_permalink' => get_sample_permalink($post->ID, $post->post_title, ''), + 'post_password_required' => post_password_required($post), + 'post_type_supports_authors' => post_type_supports($post->post_type, 'author'), + 'post_type_supports_comments' => post_type_supports($post->post_type, 'comments'), + 'post_type_supports_revisions' => post_type_supports($post->post_type, 'revisions'), + 'post_revisions' => array(), // N.B. We're not going to allow revisions editing for now + 'post_thumbnail_id' => get_post_thumbnail_id($post->ID), + 'can_publish_posts' => current_user_can($post_type_obj->cap->publish_posts), + 'can_edit_others_posts' => current_user_can($post_type_obj->cap->edit_others_posts), + 'can_unfiltered_html' => current_user_can('unfiltered_html'), + 'is_edited' => $editor ? 1 : 0, + 'editor_id' => $editor_id, + 'editor' => $editor, + 'edited_by_id' => $editor ? $editor->ID : 0, + 'edited_by_display_name' => $editor ? $editor->display_name : '', + ) + ); + + if ('post' == $post->post_type) { + $taxonomies = $this->get_taxonomies_terms($post); + $response['misc']['taxonomy_objects'] = $taxonomies['objects']; + $response['misc']['taxonomy_names'] = $taxonomies['names']; + $response['misc']['taxonomy_terms'] = $taxonomies['terms']; + $response['misc']['taxonomy_caps'] = $taxonomies['caps']; + + if (!function_exists('wp_popular_terms_checklist') || !function_exists('get_terms_to_edit')) { + require_once ABSPATH . 'wp-admin/includes/template.php'; + require_once ABSPATH . 'wp-admin/includes/taxonomy.php'; + } + + if (!function_exists('wp_get_post_categories')) { + require_once(ABSPATH.WPINC.'/post.php'); + } + + $categories = wp_get_post_categories($post->ID, array('fields' => 'ids')); + if (!is_wp_error($categories)) { + $response['misc']['categories'] = empty($categories) ? array() : $categories; + $terms_to_edit = get_terms_to_edit($post->ID, 'category'); + if (!empty($terms_to_edit)) { + $response['misc']['categories_list'] = str_replace(',', ', ', $terms_to_edit); + } + + $popular_ids = wp_popular_terms_checklist('category', 0, 10, false); + // On WP 3.4 the "wp_terms_checklist" doesn't have an "echo" parameter and will automatically + // display the rendered checklist. Therefore, we're going to pull the terms so that all + // versions starting from WP 3.4 will pull the content instead of displaying them. + + ob_start(); + // In this call we'll have to set the "echo" parameter to true so that later version of WP + // will be able to catch and process it. + wp_terms_checklist($post->ID, array('taxonomy' => 'category', 'popular_cats' => $popular_ids, 'echo' => true)); + $popular_checklist = ob_get_contents(); + ob_end_clean(); + + $response['misc']['categories_checklist'] = $popular_checklist; + + ob_start(); + wp_terms_checklist($post->ID, array('taxonomy' => 'category', 'checked_ontop' => 0, 'echo' => true)); + $quickedit_checklist = ob_get_contents(); + ob_end_clean(); + + $response['misc']['categories_quickedit_checklist'] = $quickedit_checklist; + } + + $tags = wp_get_post_tags($post->ID, array('fields' => 'ids')); + if (!is_wp_error($tags)) { + $response['misc']['tags'] = empty($tags) ? array() : $tags; + $terms_to_edit = get_terms_to_edit($post->ID, 'post_tag'); + if (!empty($terms_to_edit)) { + $response['misc']['tags_list'] = str_replace(',', ', ', $terms_to_edit); + } + } + } + + // Naturally, the "featured_media" will suffice when loading the image (media) in + // UpdraftCentral since the value in this field is the actual image id of the featured + // media used in UC. If we currently don't have an entry in the "featured_media_updraftcentral" meta, + // then UC will need to download the featured media (image) for this current post/page + // using the "featured_media_url" field (below) if not empty. + $featured_media = get_post_meta($post->ID, 'featured_media_updraftcentral', true); + if (!empty($featured_media)) { + $response['misc']['featured_media'] = $featured_media; + } + + // Retrieve featured media if currently present for the given post/page. + // If present, we pull the image (media) URL in case there's a need for + // UpdraftCentral to download the image upon loading the editor (e.g. the featured_media id + // above no longer exists). + $media_id = (int) get_post_thumbnail_id($post->ID); + if (!empty($media_id)) { + $response['misc']['featured_media_url'] = wp_get_attachment_url($media_id); + } else { + // The post/page no longer has a "featured_media" or doesn't have one currently, therefore, + // we're going to set the "featured_media" and "featured_media_url" fields to both empty to + // to avoid any further actions (e.g. download media). + $response['misc']['featured_media'] = 0; + $response['misc']['featured_media_url'] = ''; + } + } + + return $response; + } + + /** + * Changes the state/status of the submitted post(s) + * + * @param array $params An array of data that serves as parameters for the given request + * @return array + */ + public function set_state($params) { + + $state_fields = $this->get_state_fields_by_type($this->post_type); + if (empty($state_fields)) return $this->_generic_error_response('unsupported_type_on_set_state'); + + $error = $this->_validate_capabilities($state_fields['validation_fields']); + if (!empty($error)) return $error; + + $result = array(); + if (!empty($params['list'])) { + $posts = array(); + foreach ($params['list'] as $id) { + $post = $this->apply_state($id, $params['action'], $this->post_type); + if (!empty($post)) { + array_push($posts, $post); + } + } + + if (!empty($posts)) { + $result = array($state_fields['list_key'] => $posts); + } + } elseif (!empty($params['id'])) { + $post = $this->apply_state($params['id'], $params['action'], $this->post_type); + if (!empty($post)) $result = $post; + } + + if (!empty($result)) { + $response = $this->get($params); + if (!empty($response['response']) && 'rpcok' === $response['response']) { + $result[$state_fields['result_key']] = $response['data']; + } + + return $this->_response($result); + } else { + return $this->_generic_error_response($state_fields['error_key'], array('action' => $params['action'])); + } + } + + /** + * Creates new category + * + * @param array $params An array of data that serves as parameters for the given request + * @param boolean $wrap_response Indicates whether to wrap the response based on local or UpdraftCentral calls. Default true. + * @return array + */ + public function add_category($params, $wrap_response = true) { + $error = $this->_validate_capabilities(array('manage_categories')); + if (!empty($error)) return $error; + + $name = sanitize_text_field($params['name']); + $args = array(); + if (!empty($params['parent'])) { + $args['parent'] = $params['parent']; + } + + $result = wp_insert_term($name, 'category', $args); + if (!is_wp_error($result)) { + $term_id = $result['term_id']; + $term = get_term($term_id, 'category'); + + $data = array(); + if (!is_wp_error($term)) { + $data = array( + 'id' => $term->term_id, + 'count' => $term->count, + 'description' => $term->description, + 'link' => get_term_link($term->term_id, 'category'), + 'name' => $term->name, + 'slug' => $term->slug, + 'taxonomy' => $term->taxonomy, + 'parent' => $term->parent, + 'meta' => array() + ); + + $categories = $this->get_categories(); + if ($wrap_response) $data['categories'] = json_encode($categories['data']); + } + + return $wrap_response ? $this->_response($data) : $data; + } else { + $error = array( + 'message' => $result->get_error_message() + ); + + return $wrap_response ? $this->_generic_error_response('post_add_category_failed', $error) : $error; + } + } + + /** + * Assigns categories to a certain post object + * + * @param int $post_id The ID of the post object + * @param array $category_ids A collection of category IDs to assign to the post object + * @return void + */ + protected function assign_category_to_post($post_id, $category_ids) { + if (!empty($category_ids)) { + // Making sure that we have the correct type to use and we + // don't have any redundant IDs before saving. + $category_ids = array_unique(array_map('intval', $category_ids)); + + // Attach (new) categories to post + wp_set_object_terms($post_id, $category_ids, 'category'); + } else { + wp_set_object_terms($post_id, get_option('default_category'), 'category'); + } + } + + /** + * Creates new tag + * + * @param array $params An array of data that serves as parameters for the given request + * @param boolean $wrap_response Indicates whether to wrap the response based on local or UpdraftCentral calls. Default true. + * @return array + */ + public function add_tag($params, $wrap_response = true) { + // N.B. Since the "manage_post_tags" capability does not exist in WP 3.4. We'll use the "manage_categories" instead. Besides, the "manage_post_tags" along with the other tag-related capabilities in the latest versions are actually mapped to the "manage_categories" capability (refer to wp-includes/capabilities.php under the "map_meta_cap" function). + $error = $this->_validate_capabilities(array('manage_categories')); + if (!empty($error)) return $error; + + $name = sanitize_text_field($params['name']); + $result = wp_insert_term($name, 'post_tag'); + if (!is_wp_error($result)) { + $term_id = $result['term_id']; + $term = get_term($term_id, 'post_tag'); + + $data = array(); + if (!is_wp_error($term)) { + $data = array( + 'id' => $term->term_id, + 'count' => $term->count, + 'description' => $term->description, + 'link' => get_term_link($term->term_id, 'post_tag'), + 'name' => $term->name, + 'slug' => $term->slug, + 'taxonomy' => $term->taxonomy, + 'meta' => array() + ); + + $tags = $this->get_tags(); + if ($wrap_response) $data['tags'] = json_encode($tags['data']); + } + + return $wrap_response ? $this->_response($data) : $data; + } else { + $error = array( + 'message' => $result->get_error_message() + ); + + return $wrap_response ? $this->_generic_error_response('post_add_tag_failed', $error) : $error; + } + } + + /** + * Assigns tags to a certain post object + * + * @param int $post_id The ID of the post object + * @param array $tag_ids A collection of tag IDs to assign to the post object + * @return void + */ + protected function assign_tag_to_post($post_id, $tag_ids) { + if (!empty($tag_ids)) { + // Making sure that we have the correct type to use and we + // don't have any redundant IDs before saving. + $tag_ids = array_unique(array_map('intval', $tag_ids)); + + // Attach (new) tags to post + wp_set_object_terms($post_id, $tag_ids, 'post_tag'); + } else { + wp_set_object_terms($post_id, null, 'post_tag'); + } + } + + /** + * Pre-validates data before running the save process + * + * @param WP_Post $post The post object to validate + * @param array $params An array of data that serves as parameters for the given request + * + * @return array|void + */ + private function pre_validation($post, $params) { + if (empty($post) || empty($params)) return; + + if (!empty($params['password'])) { + if (!empty($params['sticky'])) { + return $this->_generic_error_response('post_save_failed', array( + 'message' => __('A post can not be sticky and have a password.'),// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. + 'args' => $params + )); + } + + if (!isset($params['sticky']) && is_sticky($post->ID)) { + return $this->_generic_error_response('post_save_failed', array( + 'message' => __('A sticky post can not be password protected.'),// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. + 'args' => $params + )); + } + } + + if (!empty($params['sticky'])) { + if (!isset($params['password']) && post_password_required($post->ID)) { + return $this->_generic_error_response('post_save_failed', array( + 'message' => __('A password protected post can not be set to sticky.'),// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. + 'args' => $params + )); + } + } + } + + /** + * Saves or updates post/page information based from the submitted data + * + * @param array $params An array of data that serves as parameters for the given request + * @return array + */ + public function save($params) { + global $updraftcentral_host_plugin; + + $validation_fields = array( + 'post' => array('publish_posts', 'edit_posts', 'delete_posts'), + 'page' => array('publish_pages', 'edit_pages', 'delete_pages') + ); + + if (!isset($validation_fields[$this->post_type])) return $this->_generic_error_response('unsupported_type_on_save_post'); + + $error = $this->_validate_capabilities($validation_fields[$this->post_type]); + if (!empty($error)) return $error; + + if (!empty($params['id']) || !empty($params['new'])) { + $args = array(); + + if (!empty($params['id'])) { + $post = get_post($params['id']); + if (!empty($post)) { + $result = $this->pre_validation($post, $params); + if (isset($result['response']) && 'rpcerror' == $result['response']) { + return $result; + } + } + } + + // post_content + if (!empty($params['content'])) + $args['post_content'] = $params['content']; + + // post_excerpt + if (!empty($params['excerpt'])) + $args['post_excerpt'] = $params['excerpt']; + + // menu_order + if (isset($params['order'])) + $args['menu_order'] = (int) $params['order']; + + // post_parent + if (isset($params['parent'])) { + $args['post_parent'] = empty($params['parent']) ? 0 : $params['parent']; + } + + // post_name + if (!empty($params['slug'])) + $args['post_name'] = $params['slug']; + + // post_status + if (!empty($params['status'])) { + $args['post_status'] = $params['status']; + } + + // post_title + if (!empty($params['title'])) + $args['post_title'] = $params['title']; + + // post_author + if (!empty($params['author'])) + $args['post_author'] = $params['author']; + + // comment_status + if (!empty($params['comment_status'])) + $args['comment_status'] = $params['comment_status']; + + // ping_status + if (!empty($params['ping_status'])) + $args['ping_status'] = $params['ping_status']; + + // visibility + if (!empty($params['visibility'])) { + switch ($params['visibility']) { + case 'public': + $args['post_status'] = 'publish'; + $args['post_password'] = ''; + break; + case 'password': + $args['post_status'] = 'publish'; + $args['post_password'] = $params['password']; + break; + case 'private': + $args['post_status'] = 'private'; + $args['post_password'] = ''; + break; + default: + break; + } + } else { + if (!empty($params['password'])) { + $args['post_status'] = 'publish'; + $args['post_password'] = $params['password']; + } elseif (isset($params['password']) && '' == $params['password']) { + $args['post_status'] = 'publish'; + $args['post_password'] = ''; + } + } + + // post/publish date + if (!empty($params['date'])) { + $datetime = strtotime($params['date']); + $post_date = date('Y-m-d H:i:s', $datetime); + + $args['post_date'] = $post_date; + $args['post_date_gmt'] = gmdate('Y-m-d H:i:s', $datetime); + + // We only change the status to "future" based from the submitted date if the post status + // is not empty and equal to 'publish' and the date is for the coming future. + if (!empty($params['status']) && 'publish' == $params['status']) { + if (strtotime($post_date) > strtotime(date('Y-m-d H:i:s'))) $args['post_status'] = 'future'; + } + } + + // Make sure we have a slug/post_name generated before insert/update + if (empty($params['slug']) && !empty($params['title'])) { + $args['post_name'] = sanitize_title_with_dashes($params['title']); + } + + if (!empty($params['new'])) { + $args['post_type'] = $this->post_type; + $post_id = wp_insert_post($args, true); + } else { + $args['ID'] = $params['id']; + $args['post_modified'] = date('Y-m-d H:i:s'); + $args['post_modified_gmt'] = gmdate('Y-m-d H:i:s'); + + $post_id = wp_update_post($args, true); + } + + // We have successfully created/updated a post at this point, thus, we'll continue + // with implementing the other requested processes and return the result. + if (!is_wp_error($post_id)) { + // sticky post + if (isset($params['sticky'])) { + $sticky = (bool) $params['sticky']; + if ($sticky) { + stick_post($post_id); + } else { + if (is_sticky($post_id)) { + unstick_post($post_id); + } + } + } + + // template + if (!empty($params['template'])) { + update_post_meta($post_id, '_wp_page_template', $params['template']); + } + + // featured_media + if (isset($params['featured_media'])) { + if (!empty($params['featured_media'])) { + $featured_media = (int) $params['featured_media']; + $attach_continue = true; + + $url = wp_get_attachment_url($featured_media); + if (!empty($url) && !empty($params['featured_media_url']) && $url == $params['featured_media_url']) { + set_post_thumbnail($post_id, $featured_media); + update_post_meta($post_id, 'featured_media_updraftcentral', $params['featured_media']); + $attach_continue = false; + } + + if ($attach_continue) { + $featured_media_data = !empty($params['featured_media_data']) ? $params['featured_media_data'] : null; + $media_id = $this->attach_remote_image($params['featured_media_url'], $featured_media_data, $post_id); + if (!empty($media_id)) { + // If we have a successful attachment then add reference to UC's media id + update_post_meta($post_id, 'featured_media_updraftcentral', $params['featured_media']); + } + } + } else { + // Remove featured image. + delete_post_meta($post_id, '_thumbnail_id'); + delete_post_meta($post_id, 'featured_media_updraftcentral'); + } + } + + // categories + $categories_updated = false; + if (!empty($params['categories'])) { + $term_ids = array(); + foreach ($params['categories'] as $value) { + $category = sanitize_text_field($value); + $parent = 0; + + if (false !== strpos($category, ':')) { + list($parent, $category) = explode(':', $category); + $result = $this->add_category(array('name' => $category, 'parent' => $parent), false); + + if (!empty($result)) { + array_push($term_ids, $result['id']); + } + } else { + $term = get_term_by('id', $category, 'category'); + if (!empty($term)) { + $term_id = $term->term_id; + array_push($term_ids, $term_id); + } + } + } + + $this->assign_category_to_post($post_id, $term_ids); + $categories_updated = true; + } + + // tags + $tags_updated = false; + if (!empty($params['tags'])) { + $term_ids = array(); + foreach ($params['tags'] as $value) { + $tag = sanitize_text_field($value); + $field = is_numeric($tag) ? 'id' : 'name'; + + $term = get_term_by($field, $tag, 'post_tag'); + if (!empty($term)) { + $term_id = $term->term_id; + array_push($term_ids, $term_id); + } else { + $result = $this->add_tag(array('name' => $tag), false); + if (!empty($result)) { + array_push($term_ids, $result['id']); + } + } + } + + $this->assign_tag_to_post($post_id, $term_ids); + $tags_updated = true; + } + + // Pulling any other relevant and additional information regarding + // the post before returning it in the response. + $postdata = $this->get_postdata($post_id); + + if (!empty($params['new'])) { + $timeout = !empty($params['timeout']) ? $params['timeout'] : 30; + $postdata = array_merge($postdata, $this->get_preload_data($timeout, $this->post_type)); + } else { + if ($categories_updated || $tags_updated) { + $categories = $this->get_categories(); + $tags = $this->get_tags(); + + $postdata['preloaded'] = json_encode(array( + 'categories' => $categories['data'], + 'tags' => $tags['data'] + )); + } + } + + $postdata['options'] = $this->get_options($this->post_type); + return $this->_response($postdata); + } else { + // ERROR: error creating or updating post + return $this->_generic_error_response('post_save_failed', array( + 'message' => $post_id->get_error_message(), + 'args' => $args + )); + } + } else { + // ERROR: no id parameter, invalid request + return $this->_generic_error_response('post_invalid_request', array('message' => $updraftcentral_host_plugin->retrieve_show_message('parameters_missing'))); + } + } + + /** + * Fetch and retrieves authors based from the submitted parameters + * + * @param array $params Containing all the needed information to filter the results of the current request + * @return array + */ + public function get_authors($params = array()) { + global $updraftcentral_main; + + // If expected parameters are empty or does not exists then set them to some default values + $page = !empty($params['page']) ? (int) $params['page'] : 1; + $per_page = !empty($params['per_page']) ? (int) $params['per_page'] : 15; + $offset = ($page - 1) * $per_page; + $who = !empty($params['who']) ? $params['who'] : 'authors'; + $order = !empty($params['order']) ? strtoupper($params['order']) : 'ASC'; + $orderby = !empty($params['orderby']) ? $params['orderby'] : 'display_name'; + + $get_user_params = array( + 'number' => $per_page, + 'paged' => $page, + 'offset' => $offset, + 'order' => $order, + 'orderby' => $orderby, + ); + + // WP 5.9 deprecated the 'who' parameter and introduces the 'capability' + // parameter, thus we'll be replacing the 'who' parameter in 5.9 or higher + if (version_compare($updraftcentral_main->get_wordpress_version(), '5.9', '<')) { + $get_user_params['who'] = $who; + } else { + $get_user_params['capability'] = array('edit_posts'); + } + + $users = get_users($get_user_params); + + $authors = array(); + $locale = get_locale(); + + foreach ($users as $user) { + $data = array( + 'user' => json_encode($this->trim_object($user)), + 'misc' => array( + 'link' => get_author_posts_url($user->ID, $user->user_nicename), + 'locale' => function_exists('get_user_locale') ? get_user_locale($user) : $locale, + 'registered_date' => date('c', strtotime($user->user_registered)), + ) + ); + + array_push($authors, $data); + } + + return $this->_response(array( + 'authors' => $authors + )); + } + + /** + * Fetch and retrieves parent pages based from the submitted parameters + * + * @param array $params Containing all the needed information to filter the results of the current request + * @return array + */ + public function get_parent_pages($params = array()) { + // If expected parameters are empty or does not exists then set them to some default values + $page = !empty($params['page']) ? (int) $params['page'] : 1; + $per_page = !empty($params['per_page']) ? (int) $params['per_page'] : 100; + $offset = ($page - 1) * $per_page; + $exclude = !empty($params['exclude']) ? $params['exclude'] : array(); + $order = !empty($params['order']) ? strtoupper($params['order']) : 'ASC'; + $orderby = !empty($params['orderby']) ? $params['orderby'] : 'menu_order'; + $status = !empty($params['status']) ? $params['status'] : 'publish'; + + $args = array( + 'posts_per_page' => $per_page, + 'paged' => $page, + 'offset' => $offset, + 'post__not_in' => $exclude, + 'order' => $order, + 'orderby' => $orderby, + 'post_type' => 'page', + 'post_status' => $status, + ); + + $query = new WP_Query($args); + $posts = $query->posts; + + $pages = array(); + if (!empty($posts)) { + foreach ($posts as $post) { + // Get additional information and merge with the response + $postdata = $this->get_postdata($post, true); + if (!empty($postdata)) array_push($pages, $this->trim_parent_info($postdata)); + } + } + + return $this->_response(array( + 'pages' => $pages + )); + } + + /** + * Trim down return data for parent pages + * + * @param array $postdata The array containing the data to process + * @return array + */ + protected function trim_parent_info($postdata) { + + if (isset($postdata['post'])) { + $post = json_decode($postdata['post']); + + $page = new stdClass(); + $page->ID = $post->ID; + $page->post_title = $post->post_title; + $page->post_parent = $post->post_parent; + $page->post_type = $post->post_type; + $page->post_status = $post->post_status; + + $postdata['post'] = json_encode($page); + } + + return $postdata; + } + + /** + * Retrieves pages, templates, authors, categories and tags data that will be + * used as options when displayed on the editor in UpdraftCentral + * + * @param string $type The type of the module that the current request is processing + * + * @return array + */ + protected function get_options($type = 'post') { + // Primarily used for editor consumption so we don't include trash here. Besides, + // trash posts/pages aren't included as parent options. + $parent_pages = $this->get_parent_pages(); + $pages = $parent_pages['data']['pages']; + + // Add flexibility by letting users filter the default roles and add their own + // custom page/post "author" role(s) if need be. + $author_roles = apply_filters('updraftcentral_author_roles', array('administrator', 'editor', 'author', 'contributor')); + $authors = get_users(array('role__in' => $author_roles)); + + if (!function_exists('get_page_templates')) { + require_once(ABSPATH.'wp-admin/includes/theme.php'); + } + + $templates = ('post' == $type) ? get_page_templates(null, 'post') : get_page_templates(); + $template_options = array(); + foreach ($templates as $template => $filename) { + $item = array( + 'filename' => $filename, + 'template' => $template, + ); + $template_options[] = $item; + } + + $page_options = array(); + foreach ($pages as $page_item) { + if (isset($page_item['post'])) { + $page = json_decode($page_item['post']); + $item = array( + 'id' => $page->ID, + 'title' => $page->post_title, + 'parent' => $page->post_parent + ); + $page_options[] = $item; + } + } + + $author_options = array(); + foreach ($authors as $user) { + $item = array( + 'id' => $user->ID, + 'name' => $user->display_name, + ); + $author_options[] = $item; + } + + $response = array( + 'page' => $page_options, + 'author' => $author_options, + 'template' => $template_options, + 'date' => $this->get_date_options($type), + ); + + if ('post' == $type) { + $categories = get_categories(array('hide_empty' => false, 'orderby' => 'name', 'order' => 'ASC')); + $tags = get_tags(array('hide_empty' => false)); + + $category_options = array(); + foreach ($categories as $category) { + $item = array( + 'id' => $category->term_id, + 'name' => $category->name, + 'parent' => $category->parent + ); + $category_options[] = $item; + } + + $tag_options = array(); + foreach ($tags as $tag) { + $item = array( + 'id' => $tag->term_id, + 'name' => $tag->name, + ); + $tag_options[] = $item; + } + + $response['category'] = $category_options; + $response['tag'] = $tag_options; + } + + return $response; + } + + /** + * Changes the state/status of the given post based from the submitted action/request + * + * @param int $id The ID of the current page to work on + * @param string $action The type of change that the current request is going to apply + * @param string $type The type of the module that the current request is processing + * + * @return array + */ + protected function apply_state($id, $action, $type = 'post') { + if (empty($id)) return false; + + $post = get_post($id); + if (!empty($post)) { + $previous_status = $post->post_status; + $deleted = false; + + switch ($action) { + case 'draft': + $args = array('ID' => $id, 'post_status' => 'draft'); + wp_update_post($args); + break; + case 'trash': + wp_trash_post($id); + break; + case 'publish': + $args = array('ID' => $id, 'post_status' => 'publish'); + wp_update_post($args); + break; + case 'restore': + $args = array('ID' => $id, 'post_status' => 'pending'); + wp_update_post($args); + break; + case 'delete': + $result = wp_delete_post($id, true); + if (!empty($result)) $deleted = true; + break; + default: + break; + } + + $postdata = $this->get_postdata($post); + if (!empty($postdata) || $deleted) { + $data = $deleted ? $id : $postdata; + $result = array( + 'id' => $id, + 'previous_status' => $previous_status + ); + + $result[$type] = $data; + return $result; + } + } + + return false; + } + + /** + * Imports image from UpdraftCentral's page/post editor + * + * @param string $image_url The URL of the image to import + * @param string $image_data The image data to save. If empty, image_url will be used to download the image + * @param int $post_id The ID of the page where this image is to be attached + * + * @return integer + */ + protected function attach_remote_image($image_url, $image_data, $post_id) { + if (empty($image_url) || empty($post_id)) return; + + $image = pathinfo($image_url); + $image_name = $image['basename']; + $upload_dir = wp_upload_dir(); + + if (empty($image_data)) { + $response = wp_remote_get($image_url); + if (!is_wp_error($response)) { + $image_data = wp_remote_retrieve_body($response); + } + } else { + $image_data = base64_decode($image_data); + } + + $media_id = 0; + if (!empty($image_data)) { + $unique_file_name = wp_unique_filename($upload_dir['path'], $image_name); + $filename = basename($unique_file_name); + + if (wp_mkdir_p($upload_dir['path'])) { + $file = $upload_dir['path'] . '/' . $filename; + } else { + $file = $upload_dir['basedir'] . '/' . $filename; + } + + file_put_contents($file, $image_data); + $wp_filetype = wp_check_filetype($filename, null); + + $attachment = array( + 'post_mime_type' => $wp_filetype['type'], + 'post_title' => sanitize_file_name($filename), + 'post_content' => '', + 'post_status' => 'inherit' + ); + + $media_id = wp_insert_attachment($attachment, $file, $post_id); + require_once(ABSPATH . 'wp-admin/includes/image.php'); + + $attach_data = wp_generate_attachment_metadata($media_id, $file); + wp_update_attachment_metadata($media_id, $attach_data); + set_post_thumbnail($post_id, $media_id); + } + + return $media_id; + } + + /** + * Checks whether we have the required fields submitted and the user has + * the capabilities to execute the requested action + * + * @param array $capabilities The capabilities to check and validate + * + * @return array|void + */ + protected function _validate_capabilities($capabilities) { + foreach ($capabilities as $capability) { + if (!current_user_can($capability)) return $this->_generic_error_response('insufficient_permission'); + } + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/theme.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/theme.php new file mode 100755 index 00000000..50ce4286 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/theme.php @@ -0,0 +1,721 @@ +switched = switch_to_blog($blog_id); + } + } + + /** + * Function that gets called after every action + * + * @param string $command a string that corresponds to UDC command to call a certain method for this class. + * @param array $data an array of data post or get fields + * @param array $extra_info extrainfo use in the udrpc_action, e.g. user_id + * + * link to udrpc_action main function in class UpdraftCentral_Listener + */ + public function _post_action($command, $data, $extra_info) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Unused parameter is present because the caller from UpdraftCentral_Listener class uses 3 arguments. + // Here, we're restoring to the current (default) blog before we switched + if ($this->switched) restore_current_blog(); + } + + /** + * Constructor + */ + public function __construct() { + $this->_admin_include('theme.php', 'file.php', 'template.php', 'class-wp-upgrader.php', 'theme-install.php', 'update.php'); + } + + /** + * Installs and activates a theme through upload + * + * @param array $params Parameter array containing information pertaining the currently uploaded theme + * @return array Contains the result of the current process + */ + public function upload_theme($params) { + return $this->process_chunk_upload($params, 'theme'); + } + + /** + * Checks whether the theme is currently installed and activated. + * + * @param array $query Parameter array containing the name of the theme to check + * @return array Contains the result of the current process + */ + public function is_theme_installed($query) { + + if (!isset($query['theme'])) + return $this->_generic_error_response('theme_name_required'); + + + $result = $this->_get_theme_info($query['theme']); + return $this->_response($result); + } + + /** + * Applies currently requested action for theme processing + * + * @param string $action The action to apply (e.g. activate or install) + * @param array $query Parameter array containing information for the currently requested action + * + * @return array + */ + private function _apply_theme_action($action, $query) { + + $result = array(); + switch ($action) { + case 'activate': + $info = $this->_get_theme_info($query['theme']); + if ($info['installed']) { + switch_theme($info['slug']); + if (wp_get_theme()->get_stylesheet() === $info['slug']) { + $result = array('activated' => true, 'info' => $this->_get_theme_info($query['theme']), 'last_state' => $info); + } else { + $result = $this->_generic_error_response('theme_not_activated', array( + 'theme' => $query['theme'], + 'error_code' => 'theme_not_activated', + 'error_message' => __('There appears to be a problem activating or switching to the intended theme.', UPDRAFTCENTRAL_TEXT_DOMAIN).' '.__('Please check your permissions and try again.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'info' => $this->_get_theme_info($query['theme']) + )); + } + } else { + $result = $this->_generic_error_response('theme_not_installed', array( + 'theme' => $query['theme'], + 'error_code' => 'theme_not_installed', + 'error_message' => __('The theme you wish to activate is either not installed or has been removed recently.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'info' => $info + )); + } + break; + case 'network_enable': + $info = $this->_get_theme_info($query['theme']); + if ($info['installed']) { + if (current_user_can('manage_network_themes')) { + // Make sure that network_enable_theme is present and callable since + // it is only available at 4.6. If not, we'll do things the old fashion way + if (is_callable(array('WP_Theme', 'network_enable_theme'))) { + WP_Theme::network_enable_theme($info['slug']); + } else { + $allowed_themes = get_site_option('allowedthemes'); + $allowed_themes[$info['slug']] = true; + + update_site_option('allowedthemes', $allowed_themes); + } + } + + $allowed = WP_Theme::get_allowed_on_network(); + if (is_array($allowed) && !empty($allowed[$info['slug']])) { + $result = array('enabled' => true, 'info' => $this->_get_theme_info($query['theme']), 'last_state' => $info); + } else { + $result = $this->_generic_error_response('theme_not_enabled', array( + 'theme' => $query['theme'], + 'error_code' => 'theme_not_enabled', + 'error_message' => __('There appears to be a problem enabling the intended theme on your network.', UPDRAFTCENTRAL_TEXT_DOMAIN).' '.__('Please kindly check your permission and try again.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'info' => $this->_get_theme_info($query['theme']) + )); + } + } else { + $result = $this->_generic_error_response('theme_not_installed', array( + 'theme' => $query['theme'], + 'error_code' => 'theme_not_installed', + 'error_message' => __('The theme you wish to enable on your network is either not installed or has been removed recently.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'info' => $info + )); + } + break; + case 'network_disable': + $info = $this->_get_theme_info($query['theme']); + if ($info['installed']) { + if (current_user_can('manage_network_themes')) { + // Make sure that network_disable_theme is present and callable since + // it is only available at 4.6. If not, we'll do things the old fashion way + if (is_callable(array('WP_Theme', 'network_disable_theme'))) { + WP_Theme::network_disable_theme($info['slug']); + } else { + $allowed_themes = get_site_option('allowedthemes'); + if (isset($allowed_themes[$info['slug']])) { + unset($allowed_themes[$info['slug']]); + } + + update_site_option('allowedthemes', $allowed_themes); + } + } + + $allowed = WP_Theme::get_allowed_on_network(); + if (is_array($allowed) && empty($allowed[$info['slug']])) { + $result = array('disabled' => true, 'info' => $this->_get_theme_info($query['theme']), 'last_state' => $info); + } else { + $result = $this->_generic_error_response('theme_not_disabled', array( + 'theme' => $query['theme'], + 'error_code' => 'theme_not_disabled', + 'error_message' => __('There appears to be a problem disabling the intended theme from your network.', UPDRAFTCENTRAL_TEXT_DOMAIN).' '.__('Please kindly check your permission and try again.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'info' => $this->_get_theme_info($query['theme']) + )); + } + } else { + $result = $this->_generic_error_response('theme_not_installed', array( + 'theme' => $query['theme'], + 'error_code' => 'theme_not_installed', + 'error_message' => __('The theme you wish to disable from your network is either not installed or has been removed recently.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'info' => $info + )); + } + break; + case 'install': + $api = themes_api('theme_information', array( + 'slug' => $query['slug'], + 'fields' => array( + 'description' => true, + 'sections' => false, + 'rating' => true, + 'ratings' => true, + 'downloaded' => true, + 'downloadlink' => true, + 'last_updated' => true, + 'screenshot_url' => true, + 'parent' => true, + ) + )); + + $info = $this->_get_theme_info($query['theme']); + if (is_wp_error($api)) { + $result = $this->_generic_error_response('generic_response_error', array( + 'theme' => $query['theme'], + 'error_code' => 'theme_not_installed', + 'error_message' => $api->get_error_message(), + 'info' => $info + )); + } else { + $installed = $info['installed']; + + $error_code = $error_message = ''; + if (!$installed) { + // WP < 3.7 + if (!class_exists('Automatic_Upgrader_Skin')) include_once(dirname(dirname(__FILE__)).'/classes/class-automatic-upgrader-skin.php'); + + $skin = new Automatic_Upgrader_Skin(); + $upgrader = new Theme_Upgrader($skin); + + $download_link = $api->download_link; + $installed = $upgrader->install($download_link); + + if (is_wp_error($installed)) { + $error_code = $installed->get_error_code(); + $error_message = $installed->get_error_message(); + } elseif (is_wp_error($skin->result)) { + $error_code = $skin->result->get_error_code(); + $error_message = $skin->result->get_error_message(); + + $error_data = $skin->result->get_error_data($error_code); + if (!empty($error_data)) { + if (is_array($error_data)) $error_data = json_encode($error_data); + $error_message .= ' '.$error_data; + } + } elseif (is_null($installed) || !$installed) { + global $wp_filesystem; + $upgrade_messages = $skin->get_upgrade_messages(); + + if (!class_exists('WP_Filesystem_Base')) include_once(ABSPATH.'/wp-admin/includes/class-wp-filesystem-base.php'); + + // Pass through the error from WP_Filesystem if one was raised. + if ($wp_filesystem instanceof WP_Filesystem_Base && is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) { + $error_code = $wp_filesystem->errors->get_error_code(); + $error_message = $wp_filesystem->errors->get_error_message(); + } elseif (!empty($upgrade_messages)) { + // We're only after for the last feedback that we received from the install process. Mostly, + // that is where the last error has been inserted. + $messages = $skin->get_upgrade_messages(); + $error_code = 'install_failed'; + $error_message = end($messages); + } else { + $error_code = 'unable_to_connect_to_filesystem'; + $error_message = __('Unable to connect to the filesystem.', UPDRAFTCENTRAL_TEXT_DOMAIN).' '.__('Please confirm your credentials.', UPDRAFTCENTRAL_TEXT_DOMAIN); + } + } + } + + if (!$installed || is_wp_error($installed)) { + $result = $this->_generic_error_response('theme_install_failed', array( + 'theme' => $query['theme'], + 'error_code' => $error_code, + 'error_message' => $error_message, + 'info' => $this->_get_theme_info($query['theme']) + )); + } else { + $result = array('installed' => true, 'info' => $this->_get_theme_info($query['theme']), 'last_state' => $info); + } + } + break; + } + + return $result; + } + + /** + * Preloads the submitted credentials to the global $_POST variable + * + * @param array $query Parameter array containing information for the currently requested action + */ + private function _preload_credentials($query) { + if (!empty($query) && isset($query['filesystem_credentials'])) { + parse_str($query['filesystem_credentials'], $filesystem_credentials); + if (is_array($filesystem_credentials)) { + foreach ($filesystem_credentials as $key => $value) { + // Put them into $_POST, which is where request_filesystem_credentials() checks for them. + $_POST[$key] = $value; + } + } + } + } + + /** + * Checks whether we have the required fields submitted and the user has + * the capabilities to execute the requested action + * + * @param array $query The submitted information + * @param array $fields The required fields to check + * @param array $capabilities The capabilities to check and validate + * + * @return array|string + */ + private function _validate_fields_and_capabilities($query, $fields, $capabilities) { + + $error = ''; + if (!empty($fields)) { + for ($i=0; $i_generic_error_response('keyword_required'); + } else { + $error = $this->_generic_error_response('theme_'.$query[$field].'_required'); + } + break; + } + } + } + + if (empty($error) && !empty($capabilities)) { + for ($i=0; $i_generic_error_response('theme_insufficient_permission'); + break; + } + } + } + + return $error; + } + + /** + * Processing an action for multiple items + * + * @param array $query Parameter array containing a list of themes to process + * @return array Contains the results of the bulk process + */ + public function process_action_in_bulk($query) { + $action = isset($query['action']) ? $query['action'] : ''; + $items = isset($query['args']) ? $query['args']['items'] : array(); + + $results = array(); + if (!empty($action) && !empty($items) && is_array($items)) { + foreach ($items as $value) { + if (method_exists($this, $action)) { + $results[] = $this->$action($value); + } + } + } + + return $this->_response($results); + } + + /** + * Activates the theme + * + * @param array $query Parameter array containing the name of the theme to activate + * @return array Contains the result of the current process + */ + public function activate_theme($query) { + + $fields = array('theme'); + $permissions = array('switch_themes'); + + $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); + if (!empty($error)) { + return $error; + } + + $this->_preload_credentials($query); + + $result = $this->_apply_theme_action('activate', $query); + if (empty($result['activated'])) { + return $result; + } + + return $this->_response($result); + } + + /** + * Enables theme for network + * + * @param array $query Parameter array containing the name of the theme to activate + * @return array Contains the result of the current process + */ + public function network_enable_theme($query) { + + $fields = array('theme'); + $permissions = array('switch_themes'); + + $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); + if (!empty($error)) { + return $error; + } + + $this->_preload_credentials($query); + + $result = $this->_apply_theme_action('network_enable', $query); + if (empty($result['enabled'])) { + return $result; + } + + return $this->_response($result); + } + + /** + * Disables theme from network + * + * @param array $query Parameter array containing the name of the theme to activate + * @return array Contains the result of the current process + */ + public function network_disable_theme($query) { + + $fields = array('theme'); + $permissions = array('switch_themes'); + + $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); + if (!empty($error)) { + return $error; + } + + $this->_preload_credentials($query); + + $result = $this->_apply_theme_action('network_disable', $query); + if (empty($result['disabled'])) { + return $result; + } + + return $this->_response($result); + } + + /** + * Download, install and activates the theme + * + * @param array $query Parameter array containing the filesystem credentials entered by the user along with the theme name and slug + * @return array Contains the result of the current process + */ + public function install_activate_theme($query) { + + $fields = array('theme', 'slug'); + $permissions = array('install_themes', 'switch_themes'); + + $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); + if (!empty($error)) { + return $error; + } + + $this->_preload_credentials($query); + + $result = $this->_apply_theme_action('install', $query); + if (!empty($result['installed']) && $result['installed']) { + $result = $this->_apply_theme_action('activate', $query); + if (empty($result['activated'])) { + return $result; + } + } else { + return $result; + } + + return $this->_response($result); + } + + /** + * Download, install the theme + * + * @param array $query Parameter array containing the filesystem credentials entered by the user along with the theme name and slug + * @return array Contains the result of the current process + */ + public function install_theme($query) { + + $fields = array('theme', 'slug'); + $permissions = array('install_themes'); + + $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); + if (!empty($error)) { + return $error; + } + + $this->_preload_credentials($query); + + $result = $this->_apply_theme_action('install', $query); + if (empty($result['installed'])) { + return $result; + } + + return $this->_response($result); + } + + /** + * Uninstall/delete the theme + * + * @param array $query Parameter array containing the filesystem credentials entered by the user along with the theme name and slug + * @return array Contains the result of the current process + */ + public function delete_theme($query) { + + $fields = array('theme'); + $permissions = array('delete_themes'); + + $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); + if (!empty($error)) { + return $error; + } + + $this->_preload_credentials($query); + + $info = $this->_get_theme_info($query['theme']); + if ($info['installed']) { + $deleted = delete_theme($info['slug']); + + if ($deleted) { + $result = array('deleted' => true, 'info' => $this->_get_theme_info($query['theme']), 'last_state' => $info); + } else { + return $this->_generic_error_response('delete_theme_failed', array( + 'theme' => $query['theme'], + 'error_code' => 'delete_theme_failed', + 'info' => $info + )); + } + } else { + return $this->_generic_error_response('theme_not_installed', array( + 'theme' => $query['theme'], + 'error_code' => 'theme_not_installed', + 'info' => $info + )); + } + + return $this->_response($result); + } + + /** + * Updates/upgrade the theme + * + * @param array $query Parameter array containing the filesystem credentials entered by the user along with the theme name and slug + * @return array Contains the result of the current process + */ + public function update_theme($query) { + + $fields = array('theme'); + $permissions = array('update_themes'); + + $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); + if (!empty($error)) { + return $error; + } + + $this->_preload_credentials($query); + + // Make sure that we still have the theme installed before running + // the update process + $info = $this->_get_theme_info($query['theme']); + if ($info['installed']) { + // Load the updates command class if not existed + if (!class_exists('UpdraftCentral_Updates_Commands')) include_once('updates.php'); + $update_command = new UpdraftCentral_Updates_Commands($this->rc); + + $result = $update_command->update_theme($info['slug']); + if (!empty($result['error'])) { + $result['values'] = array('theme' => $query['theme'], 'info' => $info); + } + } else { + return $this->_generic_error_response('theme_not_installed', array( + 'theme' => $query['theme'], + 'error_code' => 'theme_not_installed', + 'info' => $info + )); + } + + return $this->_response($result); + } + + /** + * Gets the theme information along with its active and install status + * + * @internal + * @param array $theme The name of the theme to pull the information from + * @return array Contains the theme information + */ + private function _get_theme_info($theme) { + + $info = array( + 'active' => false, + 'installed' => false + ); + + // Clear theme cache so that newly installed/downloaded themes + // gets reflected when calling "get_themes" + if (function_exists('wp_clean_themes_cache')) { + wp_clean_themes_cache(); + } + + // Gets all themes available. + $themes = wp_get_themes(); + $current_theme_slug = basename(get_stylesheet_directory()); + + // Loops around each theme available. + foreach ($themes as $slug => $value) { + $name = $value->get('Name'); + $theme_name = !empty($name) ? $name : $slug; + + // If the theme name matches that of the specified name, it will gather details. + if ($theme_name === $theme) { + $info['installed'] = true; + $info['active'] = ($slug === $current_theme_slug) ? true : false; + $info['slug'] = $slug; + $info['data'] = $value; + $info['name'] = $theme_name; + break; + } + } + + return $info; + } + + /** + * Loads all available themes with additional attributes and settings needed by UpdraftCentral + * + * @param array $query Parameter array Any available parameters needed for this action + * @return array Contains the result of the current process + */ + public function load_themes($query) { + + $permissions = array('install_themes', 'switch_themes'); + $args = array(); + if (is_multisite() && !is_super_admin(get_current_user_id())) { + $permissions = array('switch_themes'); + $args = array('allowed' => true, 'blog_id' => get_current_blog_id()); + } + + $error = $this->_validate_fields_and_capabilities($query, array(), $permissions); + if (!empty($error)) { + return $error; + } + + $website = get_bloginfo('name'); + $results = array(); + + // Load the updates command class if not existed + if (!class_exists('UpdraftCentral_Updates_Commands')) include_once('updates.php'); + $updates = new UpdraftCentral_Updates_Commands($this->rc); + + // Get themes for update + $theme_updates = (array) $updates->get_item_updates('themes'); + + // Get all themes + $themes = wp_get_themes($args); + $current_theme_slug = basename(get_stylesheet_directory()); + + foreach ($themes as $slug => $value) { + $name = $value->get('Name'); + $theme_name = !empty($name) ? $name : $slug; + + $theme = new stdClass(); + $theme->name = $theme_name; + $theme->description = $value->get('Description'); + $theme->slug = $slug; + $theme->version = $value->get('Version'); + $theme->author = $value->get('Author'); + $theme->status = ($slug === $current_theme_slug) ? 'active' : 'inactive'; + + $template = $value->get('Template'); + $theme->child_theme = !empty($template) ? true : false; + $theme->website = $website; + $theme->multisite = is_multisite(); + $theme->site_url = trailingslashit(get_bloginfo('url')); + + if ($theme->child_theme) { + $parent_theme = wp_get_theme($template); + $parent_name = $parent_theme->get('Name'); + + $theme->parent = !empty($parent_name) ? $parent_name : $parent_theme->get_stylesheet(); + } + + if (!empty($theme_updates[$slug])) { + $update_info = $theme_updates[$slug]; + + if (version_compare($theme->version, $update_info->update['new_version'], '<')) { + if (!empty($update_info->update['new_version'])) $theme->latest_version = $update_info->update['new_version']; + if (!empty($update_info->update['package'])) $theme->download_link = $update_info->update['package']; + } + } + + if (empty($theme->short_description) && !empty($theme->description)) { + // Only pull the first sentence as short description, it should be enough rather than displaying + // an empty description or a full blown one which the user can access anytime if they press on + // the view details link in UpdraftCentral. + $temp = explode('.', $theme->description); + $short_description = $temp[0]; + + // Adding the second sentence wouldn't hurt, in case the first sentence is too short. + if (isset($temp[1])) $short_description .= '.'.$temp[1]; + + $theme->short_description = $short_description.'.'; + } + + $results[] = $theme; + } + + $result = array( + 'themes' => $results, + 'theme_updates' => $theme_updates, + 'is_super_admin' => is_super_admin(), + ); + + $result = array_merge($result, $this->_get_backup_credentials_settings(get_theme_root())); + return $this->_response($result); + } + + /** + * Gets the backup and security credentials settings for this website + * + * @param array $query Parameter array Any available parameters needed for this action + * @return array Contains the result of the current process + */ + public function get_theme_requirements() { + return $this->_response($this->_get_backup_credentials_settings(get_theme_root())); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/updates.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/updates.php new file mode 100755 index 00000000..947c3562 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/updates.php @@ -0,0 +1,1028 @@ +_generic_error_response('invalid_data'); + + if (!empty($updates['plugins']) && !current_user_can('update_plugins')) return $this->_generic_error_response('updates_permission_denied', 'update_plugins'); + + if (!empty($updates['themes']) && !current_user_can('update_themes')) return $this->_generic_error_response('updates_permission_denied', 'update_themes'); + + if (!empty($updates['core']) && !current_user_can('update_core')) return $this->_generic_error_response('updates_permission_denied', 'update_core'); + + if (!empty($updates['translations']) && !$this->user_can_update_translations()) return $this->_generic_error_response('updates_permission_denied', 'update_translations'); + + $this->_admin_include('plugin.php', 'update.php', 'file.php', 'template.php'); + $this->_frontend_include('update.php'); + + if (!empty($updates['meta']) && isset($updates['meta']['filesystem_credentials'])) { + parse_str($updates['meta']['filesystem_credentials'], $filesystem_credentials); + if (is_array($filesystem_credentials)) { + foreach ($filesystem_credentials as $key => $value) { + // Put them into $_POST, which is where request_filesystem_credentials() checks for them. + $_POST[$key] = $value; + } + } + } + + $plugins = empty($updates['plugins']) ? array() : $updates['plugins']; + $plugin_updates = array(); + foreach ($plugins as $plugin_info) { + $plugin_updates[] = $this->_update_plugin($plugin_info['plugin'], $plugin_info['slug']); + } + + $themes = empty($updates['themes']) ? array() : $updates['themes']; + $theme_updates = array(); + foreach ($themes as $theme_info) { + $theme = $theme_info['theme']; + $theme_updates[] = $this->_update_theme($theme); + } + + $cores = empty($updates['core']) ? array() : $updates['core']; + $core_updates = array(); + foreach ($cores as $core) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- We dont use $core but we need the AS in the foreach so it needs to stay + $core_updates[] = $this->_update_core(null); + // Only one (and always we go to the latest version) - i.e. we ignore the passed parameters + break; + } + + $translation_updates = array(); + if (!empty($updates['translations'])) { + $translation_updates[] = $this->_update_translation(); + } + + return $this->_response(array( + 'plugins' => $plugin_updates, + 'themes' => $theme_updates, + 'core' => $core_updates, + 'translations' => $translation_updates, + )); + + } + + /** + * Updates a plugin. A facade method that exposes a private updates + * feature for other modules to consume. + * + * @param string $plugin Specific plugin to be updated + * @param string $slug Unique key passed for updates + * + * @return array + */ + public function update_plugin($plugin, $slug) { + return $this->_update_plugin($plugin, $slug); + } + + /** + * Updates a theme. A facade method that exposes a private updates + * feature for other modules to consume. + * + * @param string $theme Specific theme to be updated + * + * @return array + */ + public function update_theme($theme) { + return $this->_update_theme($theme); + } + + /** + * Gets available updates for a certain entity (e.g. plugin or theme). A facade method that + * exposes a private updates feature for other modules to consume. + * + * @param string $entity The name of the entity that this request is intended for (e.g. themes or plugins) + * + * @return array + */ + public function get_item_updates($entity) { + $updates = array(); + switch ($entity) { + case 'themes': + wp_update_themes(); + $updates = $this->maybe_add_third_party_items(get_theme_updates(), 'theme'); + break; + case 'plugins': + wp_update_plugins(); + $updates = $this->maybe_add_third_party_items(get_plugin_updates(), 'plugin'); + break; + } + + return $updates; + } + + /** + * Mostly from wp_ajax_update_plugin() in wp-admin/includes/ajax-actions.php (WP 4.5.2) + * Code-formatting style has been retained from the original, for ease of comparison/updating + * + * @param string $plugin Specific plugin to be updated + * @param string $slug Unique key passed for updates + * @return array + */ + private function _update_plugin($plugin, $slug) { + + $status = array( + 'update' => 'plugin', + 'plugin' => $plugin, + 'slug' => sanitize_key($slug), + 'oldVersion' => '', + 'newVersion' => '', + ); + + if (false !== strpos($plugin, '..') || false !== strpos($plugin, ':') || !preg_match('#^[^\/]#i', $plugin)) { + $status['error'] = 'not_found'; + return $status; + } + + $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin); + if (!isset($plugin_data['Name']) || !isset($plugin_data['Author']) || ('' == $plugin_data['Name'] && '' == $plugin_data['Author'])) { + $status['error'] = 'not_found'; + return $status; + } + + if ($plugin_data['Version']) { + $status['oldVersion'] = $plugin_data['Version']; + } + + if (!current_user_can('update_plugins')) { + $status['error'] = 'updates_permission_denied'; + return $status; + } + + include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'); + + wp_update_plugins(); + + // WP < 3.7 + if (!class_exists('Automatic_Upgrader_Skin')) include_once(UPDRAFTCENTRAL_CLIENT_DIR.'/classes/class-automatic-upgrader-skin.php'); + + $skin = new Automatic_Upgrader_Skin(); + $upgrader = new Plugin_Upgrader($skin); + $result = $upgrader->bulk_upgrade(array($plugin)); + + if (is_array($result) && empty($result[$plugin]) && is_wp_error($skin->result)) { + $result = $skin->result; + } + + $status['messages'] = $upgrader->skin->get_upgrade_messages(); + + if (is_array($result) && !empty($result[$plugin])) { + $plugin_update_data = current($result); + + /* + * If the `update_plugins` site transient is empty (e.g. when you update + * two plugins in quick succession before the transient repopulates), + * this may be the return. + * + * Preferably something can be done to ensure `update_plugins` isn't empty. + * For now, surface some sort of error here. + */ + if (true === $plugin_update_data) { + $status['error'] = 'update_failed'; + return $status; + } + + if (is_wp_error($result[$plugin])) { + $status['error'] = $result[$plugin]->get_error_code(); + $status['error_message'] = $result[$plugin]->get_error_message(); + return $status; + } + + $plugin_data = get_plugins('/' . $result[$plugin]['destination_name']); + $plugin_data = reset($plugin_data); + + if ($plugin_data['Version']) { + $status['newVersion'] = $plugin_data['Version']; + } + return $status; + + } elseif (is_wp_error($result)) { + $status['error'] = $result->get_error_code(); + $status['error_message'] = $result->get_error_message(); + return $status; + + } elseif (is_bool($result) && !$result) { + $status['error'] = 'unable_to_connect_to_filesystem'; + + global $wp_filesystem; + + // Pass through the error from WP_Filesystem if one was raised + if (isset($wp_filesystem->errors) && is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) { + $status['error'] = $wp_filesystem->errors->get_error_code(); + $status['error_message'] = $wp_filesystem->errors->get_error_message(); + } + + return $status; + + } else { + // An unhandled error occurred + $status['error'] = 'update_failed'; + return $status; + } + } + + /** + * Adapted from _update_theme (above) + * + * @param string $core + * @return array + */ + private function _update_core($core) { + + global $wp_filesystem; + + $status = array( + 'update' => 'core', + 'core' => $core, + 'oldVersion' => '', + 'newVersion' => '', + ); + + // THis is included so we can get $wp_version + include(ABSPATH.WPINC.'/version.php'); + + $status['oldVersion'] = $wp_version;// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- The variable is defined inside the ABSPATH.WPINC.'/version.php'. + + if (!current_user_can('update_core')) { + $status['error'] = 'updates_permission_denied'; + return $status; + } + + include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'); + + wp_version_check(); + + $locale = get_locale();// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Unused variable is for future use. + + $core_update_key = false; + $core_update_latest_version = false; + + $get_core_updates = get_core_updates(); + + // THis is included so we can get $wp_version + @include(ABSPATH.WPINC.'/version.php');// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. + + foreach ($get_core_updates as $k => $core_update) { + if (isset($core_update->version) && version_compare($core_update->version, $wp_version, '>') && version_compare($core_update->version, $core_update_latest_version, '>')) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- The variable is defined inside the ABSPATH.WPINC.'/version.php'. + $core_update_latest_version = $core_update->version; + $core_update_key = $k; + } + } + + if (false === $core_update_key) { + $status['error'] = 'no_update_found'; + return $status; + } + + $update = $get_core_updates[$core_update_key]; + + // WP < 3.7 + if (!class_exists('Automatic_Upgrader_Skin')) include_once(UPDRAFTCENTRAL_CLIENT_DIR.'/classes/class-automatic-upgrader-skin.php'); + + $skin = new Automatic_Upgrader_Skin(); + $upgrader = new Core_Upgrader($skin); + + $result = $upgrader->upgrade($update); + + $status['messages'] = $upgrader->skin->get_upgrade_messages(); + + if (is_wp_error($result)) { + $status['error'] = $result->get_error_code(); + $status['error_message'] = $result->get_error_message(); + return $status; + + } elseif (is_bool($result) && !$result) { + $status['error'] = 'unable_to_connect_to_filesystem'; + + // Pass through the error from WP_Filesystem if one was raised + if (is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) { + $status['error'] = $wp_filesystem->errors->get_error_code(); + $status['error_message'] = $wp_filesystem->errors->get_error_message(); + } + + return $status; + + + } elseif (preg_match('/^[0-9]/', $result)) { + + $status['newVersion'] = $result; + + return $status; + + } else { + // An unhandled error occurred + $status['error'] = 'update_failed'; + return $status; + } + + } + + private function _update_theme($theme) { + + global $wp_filesystem; + + $status = array( + 'update' => 'theme', + 'theme' => $theme, + 'oldVersion' => '', + 'newVersion' => '', + ); + + if (false !== strpos($theme, '/') || false !== strpos($theme, '\\')) { + $status['error'] = 'not_found'; + return $status; + } + + $theme_version = $this->get_theme_version($theme); + if (false === $theme_version) { + $status['error'] = 'not_found'; + return $status; + } + $status['oldVersion'] = $theme_version; + + if (!current_user_can('update_themes')) { + $status['error'] = 'updates_permission_denied'; + return $status; + } + + include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'); + + wp_update_themes(); + + // WP < 3.7 + if (!class_exists('Automatic_Upgrader_Skin')) include_once(UPDRAFTCENTRAL_CLIENT_DIR.'/classes/class-automatic-upgrader-skin.php'); + + $skin = new Automatic_Upgrader_Skin(); + $upgrader = new Theme_Upgrader($skin); + $upgrader->init(); + $result = $upgrader->bulk_upgrade(array($theme)); + + if (is_array($result) && empty($result[$theme]) && is_wp_error($skin->result)) { + $result = $skin->result; + } + + $status['messages'] = $upgrader->skin->get_upgrade_messages(); + + if (is_array($result) && !empty($result[$theme])) { + $theme_update_data = current($result); + + /* + * If the `update_themes` site transient is empty (e.g. when you update + * two plugins in quick succession before the transient repopulates), + * this may be the return. + * + * Preferably something can be done to ensure `update_themes` isn't empty. + * For now, surface some sort of error here. + */ + if (true === $theme_update_data) { + $status['error'] = 'update_failed'; + return $status; + } + + $new_theme_version = $this->get_theme_version($theme); + if (false === $new_theme_version) { + $status['error'] = 'update_failed'; + return $status; + } + + $status['newVersion'] = $new_theme_version; + + return $status; + + } elseif (is_wp_error($result)) { + $status['error'] = $result->get_error_code(); + $status['error_message'] = $result->get_error_message(); + return $status; + + } elseif (is_bool($result) && !$result) { + $status['error'] = 'unable_to_connect_to_filesystem'; + + // Pass through the error from WP_Filesystem if one was raised + if (is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) { + $status['error'] = $wp_filesystem->errors->get_error_code(); + $status['error_message'] = $wp_filesystem->errors->get_error_message(); + } + + return $status; + + } else { + // An unhandled error occurred + $status['error'] = 'update_failed'; + return $status; + } + + } + + /** + * Updates available translations for this website + * + * @return Array + */ + private function _update_translation() { + global $wp_filesystem; + + $status = array(); + + include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'); + if (!class_exists('Automatic_Upgrader_Skin')) include_once(UPDRAFTCENTRAL_CLIENT_DIR.'/classes/class-automatic-upgrader-skin.php'); + + $skin = new Automatic_Upgrader_Skin(); + $upgrader = new Language_Pack_Upgrader($skin); + $result = $upgrader->bulk_upgrade(); + + if (is_array($result) && !empty($result)) { + $status['success'] = true; + } elseif (is_wp_error($result)) { + $status['error'] = $result->get_error_code(); + $status['error_message'] = $result->get_error_message(); + } elseif (is_bool($result) && !$result) { + $status['error'] = 'unable_to_connect_to_filesystem'; + + // Pass through the error from WP_Filesystem if one was raised + if (is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) { + $status['error'] = $wp_filesystem->errors->get_error_code(); + $status['error_message'] = $wp_filesystem->errors->get_error_message(); + } + } elseif (is_bool($result) && $result) { + $status['error'] = 'up_to_date'; + } else { + // An unhandled error occurred + $status['error'] = 'update_failed'; + } + + return $status; + } + + private function get_theme_version($theme) { + + if (function_exists('wp_get_theme')) { + // Since WP 3.4.0 + $theme = wp_get_theme($theme); + + if (is_a($theme, 'WP_Theme')) { + return $theme->Version; + } else { + return false; + } + + } else { + $theme_data = get_theme_data(WP_CONTENT_DIR . '/themes/'.$theme.'/style.css'); + + if (isset($theme_data['Version'])) { + return $theme_data['Version']; + } else { + return false; + } + } + } + + /** + * Adding third-party plugins/theme for UDC automatic updates, for some updaters which store their information when the transient is set, instead of (like most) when it is fetched + * + * @param Array $items A collection of plugins or themes for updates + * @param String $type A string indicating which type of collection to process (e.g. 'plugin' or 'theme') + * @return Array An updated collection of plugins or themes for updates + */ + private function maybe_add_third_party_items($items, $type) { + + // Here we're preparing a dummy transient object that will be pass to the filter + // and gets populated by those plugins or themes that hooked into the "pre_set_site_transient_*" filter. + // + // We're setting some default properties so that plugins and themes won't be able to bypass populating them, + // because most of the plugins and themes updater scripts checks whether or not these properties are set and + // non-empty or passed the 12 hour period (where WordPress re-starts the process of checking updates for + // these plugins and themes), otherwise, they bypass populating the update/upgrade info for these items. + $transient = (object) array( + 'last_checked' => time() - (13 * 3600), /* Making sure that we passed the 12 hour period check */ + 'checked' => array('default' => 'none'), + 'response' => array('default' => 'none') + ); + + // Most of the premium plugin developers are hooking into the "pre_set_site_transient_update_plugins" and + // "pre_set_site_transient_update_themes" filters if they want their plugins or themes to support automatic + // updates. Thus, we're making sure here that if for some reason, those plugins or themes didn't get through + // and added to the "update_plugins" or "update_themes" transients when calling the get_site_transient('update_plugins') + // or get_site_transient('update_themes') we add them here manually. + $filters = apply_filters("pre_set_site_transient_update_{$type}s", $transient, "update_{$type}s"); + + + $all_items = array(); + switch ($type) { + case 'plugin': + $all_items = get_plugins(); + break; + case 'theme': + $this->_frontend_include('theme.php'); + if (function_exists('wp_get_themes')) { + $themes = wp_get_themes(); + if (!empty($themes)) { + // We make sure that the return key matched the previous + // key from "get_themes", otherwise, no updates will be found + // even if it does have one. "get_themes" returns the name of the + // theme as the key while "wp_get_themes" returns the slug. + foreach ($themes as $theme) { + $all_items[$theme->Name] = $theme; + } + } + } else { + $all_items = get_themes(); + } + break; + default: + break; + } + + + if (!empty($all_items)) { + $all_items = (array) $all_items; + foreach ($all_items as $key => $data) { + if (!isset($items[$key]) && isset($filters->response[$key])) { + + $update_info = ('plugin' === $type) ? $filters->response[$key] : $data; + + // If "package" is empty, it means that this plugin or theme does not support automatic updates + // currently, since the "package" field is the one holding the download link of these plugins/themes + // and WordPress is using this field to download the latest version of these items. + // + // Most of the time, this "package" field is not empty, but for premium plugins/themes this can be + // conditional, only then if the user provides a legit access or api key can this field be populated or available. + // + // We set this variable to "false" by default, as plugins/themes hosted in wordpress.org always sets this + // to the downloadable zip file of the plugin/theme. + // + // N.B. We only add premium plugins/themes that has this "package" field set and non-empty, otherwise, it + // does not support automatic updates as explained above. + $is_package_empty = false; + + if (is_object($update_info)) { + if (!isset($update_info->package) || empty($update_info->package)) { + $is_package_empty = true; + } + + } elseif (is_array($update_info)) { + if (!isset($update_info['package']) || empty($update_info['package'])) { + $is_package_empty = true; + } + } + + // Add this plugin/theme to the current updates collection + if (!$is_package_empty) { + $items[$key] = ('plugin' === $type) ? (object) $data : $this->get_theme_info($key); + $items[$key]->update = $update_info; + } + + } + } + } + + return $this->prep_items_for_updates($items, $type); + } + + /** + * Extracts theme's data or information + * + * @param string $theme A string representing a theme's name or slug. + * @return object|boolean If successful, an object containing the theme data or information, "false" otherwise. + */ + private function get_theme_info($theme) { + + if (function_exists('wp_get_theme')) { + $theme = wp_get_theme($theme); + if (is_a($theme, 'WP_Theme')) { + return $theme; + } + } else { + $theme_data = get_theme_data(WP_CONTENT_DIR.'/themes/'.$theme.'/style.css'); + if (isset($theme_data['Version'])) { + if (!isset($theme_data['ThemeURI'])) $theme_data['ThemeURI'] = $theme_data['URI']; + return (object) $theme_data; + } + } + + return false; + } + + /** + * Fix items for update with missing "plugin" or "theme" field if applicable + * + * @param Array $items A collection of plugins or themes for updates + * @param String $type A string indicating which type of collection to process (e.g. 'plugin' or 'theme') + * @return Array An updated collection of plugins or themes for updates + */ + private function prep_items_for_updates($items, $type) { + + foreach ($items as $key => $data) { + $update_info = $data->update; + + // Some plugins and/or themes does not adhere to the standard WordPress updates meta + // properties/fields. Thus, missing some fields such as "plugin" or "theme" + // in their update information results in "Automatic updates is unavailable for this item" + // in UDC since we're using these fields to process the updates. + // + // As a workaround, we're filling these missing fields in order to solve the above issue + // in case the developer of these plugins/themes forgot to include them. + if (is_object($update_info)) { + $update_info = (array) $update_info; + if (!isset($update_info[$type])) { + $update_info[$type] = $key; + } + + $update_info = (object) $update_info; + + } elseif (is_array($update_info)) { + if (!isset($update_info[$type])) { + $update_info[$type] = $key; + } + } + + // Re-assign the updated info to the original "update" property + $items[$key]->update = $update_info; + } + + return $items; + } + + /** + * Custom validation for translation permission. Since the 'install_languages' capability insn't available until 4.9 + * therefore, we wrapped the validation check in this block to support older version of WP. + * + * @return Boolean + */ + private function user_can_update_translations() { + global $updraftcentral_main; + $wp_version = $updraftcentral_main->get_wordpress_version(); + + if (version_compare($wp_version, '4.9', '<')) { + if (current_user_can('update_core') || current_user_can('update_plugins') || current_user_can('update_themes')) return true; + } else { + if (current_user_can('install_languages')) return true; + } + + return false; + } + + /** + * Checks basic WP and PHP compatibility for plugins and themes + * + * @param string $type The type of the entity to check (e.g. 'plugin' or 'theme') + * @param array $info Data or information to check + * @return array + */ + private function is_compatible($type, $info) { + global $updraftcentral_main; + $wp_version = $updraftcentral_main->get_wordpress_version(); + + $is_compatible = null; + $message = ''; + + if (isset($info['update'])) { + + // Check for WP Compatibility based from the update information + if (!empty($info['update']['requires'])) { + if (version_compare($wp_version, $info['update']['requires'], '<')) { + $is_compatible = false; + + /* translators: %s: Plugin/theme type */ + $message1 = sprintf( + __('The latest update for this %s is not compatible with the WordPress version installed on the remote site.', 'updraftplus'), + $type + ); + + /* translators: 1: Plugin/theme type, 2: Required WordPress version */ + $message2 = sprintf( + __('The minimum WordPress version supported by this %1$s is %2$s.', 'updraftplus'), + $type, + $info['update']['requires'] + ); + + $message = esc_attr($message1 . ' ' . $message2); + } else { + $is_compatible = true; + } + } + + // Check for PHP Compatibility based from the update information + if (!empty($info['update']['requires_php'])) { + if (version_compare(PHP_VERSION, $info['update']['requires_php'], '<')) { + $is_compatible = false; + + /* translators: %s: Plugin/theme type */ + $message1 = sprintf( + __('The latest update for this %s is not compatible with the PHP version installed on the remote site.', 'updraftplus'), + $type + ); + + /* translators: 1: Plugin/theme type, 2: Required PHP version */ + $message2 = sprintf( + __('The minimum PHP version supported by this %1$s is %2$s.', 'updraftplus'), + $type, + $info['update']['requires_php'] + ); + + $message = esc_attr($message1 . ' ' . $message2); + } else { + $is_compatible = true; + } + } + + // Check whether Plugin/Theme has been tested based from the update information + if (!empty($info['update']['tested'])) { + if (version_compare($wp_version, $info['update']['tested'], '>')) { + $is_compatible = false; + // translators: %s: Plugin/theme type + $message = esc_attr(sprintf(__('The latest update for this %s has not been tested with the WordPress version installed on the remote site and may have compatibility issues when used.', 'updraftplus'), $type)); + } else { + $is_compatible = true; + } + } + } + + if (is_null($is_compatible)) { + $is_compatible = false; + $message = esc_attr(sprintf(__('This % does not provide information to allow determining whether the latest version is compatible with your WordPress or PHP installation.', 'updraftplus'), $type).' '.__('If installing, then proceed with caution by first doing a backup.', 'updraftplus')); + } + + return array( + 'compatible' => $is_compatible, + 'compatible_message' => $message, + ); + } + + /** + * Retrieve icons for plugin and screenshot for theme + * + * @param string $type The type of the entity to process (e.g. 'plugin' or 'theme') + * @param string $slug The entity slug + * @return string + */ + private function get_icons_screenshot($type, $slug) { + if (!in_array($type, array('plugin', 'theme'))) return ''; + + if ('plugin' == $type) { + if (!function_exists('plugins_api') && file_exists(ABSPATH.'wp-admin/includes/plugin-install.php')) { + include_once(ABSPATH.'wp-admin/includes/plugin-install.php'); + } + + // We make sure that the function now exists before we use it because + // the definition of this function maybe located in other places given + // the varying versions and changes to the WordPress platform. + if (function_exists('plugins_api')) { + $api = plugins_api('plugin_information', array( + 'slug' => $slug, + 'fields' => array('icons' => true), + )); + + if (!is_wp_error($api) && property_exists($api, 'icons')) { + return $api->icons; + } + } + + } elseif ('theme' == $type) { + if (!function_exists('themes_api') && file_exists(ABSPATH.'wp-admin/includes/theme.php')) { + include_once(ABSPATH.'wp-admin/includes/theme.php'); + } + + // We make sure that the function now exists before we use it because + // the definition of this function maybe located in other places given + // the varying versions and changes to the WordPress platform. + if (function_exists('themes_api')) { + $api = themes_api('theme_information', array( + 'slug' => $slug, + 'fields' => array('screenshot_url' => true), + )); + + if (!is_wp_error($api) && property_exists($api, 'screenshot_url')) { + return $api->screenshot_url; + } + } + } + + return ''; + } + + public function get_updates($options) { + + // Forcing Elegant Themes (Divi) updates component to load if it exist. + if (function_exists('et_register_updates_component')) et_register_updates_component(); + + if (!current_user_can('update_plugins') && !current_user_can('update_themes') && !current_user_can('update_core')) return $this->_generic_error_response('updates_permission_denied'); + + $this->_admin_include('plugin.php', 'update.php', 'file.php', 'template.php'); + $this->_frontend_include('update.php'); + + if (!is_array($options)) $options = array(); + + // Normalise it + $plugin_updates = array(); + if (current_user_can('update_plugins')) { + + // Detect if refresh needed + $transient = get_site_transient('update_plugins'); + if (!empty($options['force_refresh']) || false === $transient) { + delete_site_transient('update_plugins'); + wp_update_plugins(); + } + + $get_plugin_updates = $this->maybe_add_third_party_items(get_plugin_updates(), 'plugin'); + if (is_array($get_plugin_updates)) { + foreach ($get_plugin_updates as $update) { + + // For some reason, some 3rd-party (premium) plugins are returning the same version + // with that of the currently installed version in WordPress. Thus, we're making sure here to + // only return those items for update that has new versions greater than the currently installed version. + if (version_compare($update->Version, $update->update->new_version, '>=')) continue; + + $info = array( + 'name' => $update->Name, + 'plugin_uri' => $update->PluginURI, + 'version' => $update->Version, + 'description' => $update->Description, + 'author' => $update->Author, + 'author_uri' => $update->AuthorURI, + 'title' => $update->Title, + 'author_name' => $update->AuthorName, + 'update' => array( + // With Affiliates-WP, if you have not connected, this is null. + 'plugin' => isset($update->update->plugin) ? $update->update->plugin : null, + 'slug' => $update->update->slug, + 'new_version' => $update->update->new_version, + 'package' => $update->update->package, + 'tested' => isset($update->update->tested) ? $update->update->tested : null, + 'compatibility' => isset($update->update->compatibility) ? (array) $update->update->compatibility : null, + 'sections' => isset($update->update->sections) ? (array) $update->update->sections : null, + 'requires' => isset($update->update->requires) ? $update->update->requires : null, + 'requires_php' => isset($update->update->requires_php) ? $update->update->requires_php : null, + 'icons' => isset($update->update->icons) ? $update->update->icons : $this->get_icons_screenshot('plugin', $update->update->slug), + ), + ); + + // Check for compatibility and merge result into info + $result = $this->is_compatible('plugin', $info); + $plugin_updates[] = array_merge($info, $result); + } + } + } + + $theme_updates = array(); + if (current_user_can('update_themes')) { + + // Detect if refresh needed + $transient = get_site_transient('update_themes'); + if (!empty($options['force_refresh']) || false === $transient) { + delete_site_transient('update_themes'); + wp_update_themes(); + } + $get_theme_updates = $this->maybe_add_third_party_items(get_theme_updates(), 'theme'); + if (is_array($get_theme_updates)) { + foreach ($get_theme_updates as $update) { + + // We're making sure here to only return those items for update that has new + // versions greater than the currently installed version. + if (version_compare($update->Version, $update->update['new_version'], '>=')) continue; + + $name = $update->Name; + $theme_name = !empty($name) ? $name : $update->update['theme']; + + $info = array( + 'name' => $theme_name, + 'theme_uri' => $update->ThemeURI, + 'version' => $update->Version, + 'description' => $update->Description, + 'author' => $update->Author, + 'author_uri' => $update->AuthorURI, + 'update' => array( + 'theme' => $update->update['theme'], + 'new_version' => $update->update['new_version'], + 'package' => $update->update['package'], + 'url' => $update->update['url'], + 'tested' => isset($update->update['tested']) ? $update->update['tested'] : null, + 'requires' => $update->update['requires'], + 'requires_php' => $update->update['requires_php'], + 'screenshot_url' => isset($update->update['screenshot_url']) ? $update->update['screenshot_url'] : $this->get_icons_screenshot('theme', $update->update['theme']), + ), + ); + + // Check for compatibility and merge result into info + $result = $this->is_compatible('theme', $info); + $theme_updates[] = array_merge($info, $result); + } + } + } + + $core_updates = array(); + if (current_user_can('update_core')) { + + // Detect if refresh needed + $transient = get_site_transient('update_core'); + if (!empty($options['force_refresh']) || false === $transient) { + // The next line is only needed for older WP versions - otherwise, the parameter to wp_version_check forces a check. + delete_site_transient('update_core'); + wp_version_check(array(), true); + } + + $get_core_updates = get_core_updates(); + + if (is_array($get_core_updates)) { + + $core_update_key = false; + $core_update_latest_version = false; + + // THis is included so we can get $wp_version + @include(ABSPATH.WPINC.'/version.php');// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. + + foreach ($get_core_updates as $k => $core_update) { + if (isset($core_update->version) && version_compare($core_update->version, $wp_version, '>') && version_compare($core_update->version, $core_update_latest_version, '>')) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- The variable is defined inside the ABSPATH.WPINC.'/version.php'. + $core_update_latest_version = $core_update->version; + $core_update_key = $k; + } + } + + if (false !== $core_update_key) { + + $update = $get_core_updates[$core_update_key]; + + global $wpdb; + + $mysql_version = $wpdb->db_version(); + + $is_mysql = (file_exists(WP_CONTENT_DIR . '/db.php') && empty($wpdb->is_mysql)) ? false : true; + + // We're making sure here to only return those items for update that has new + // versions greater than the currently installed version. + if (version_compare($wp_version, $update->version, '<')) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- The variable is defined inside the ABSPATH.WPINC.'/version.php'. + $core_updates[] = array( + 'download' => $update->download, + 'version' => $update->version, + 'php_version' => $update->php_version, + 'mysql_version' => $update->mysql_version, + 'installed' => array( + 'version' => $wp_version,// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- The variable is defined inside the ABSPATH.WPINC.'/version.php'. + 'mysql' => $mysql_version, + 'php' => PHP_VERSION, + 'is_mysql' => $is_mysql, + ), + 'sufficient' => array( + 'mysql' => version_compare($mysql_version, $update->mysql_version, '>='), + 'php' => version_compare(PHP_VERSION, $update->php_version, '>='), + ), + ); + } + + } + } + + } + + $translation_updates = array(); + if (function_exists('wp_get_translation_updates') && $this->user_can_update_translations()) { + $translations = wp_get_translation_updates(); + + $translation_updates = array( + 'items' => $translations + ); + } + + // Do we need to ask the user for filesystem credentials? + $request_filesystem_credentials = array(); + $check_fs = array( + 'plugins' => WP_PLUGIN_DIR, + 'themes' => WP_CONTENT_DIR.'/themes', + 'core' => untrailingslashit(ABSPATH) + ); + + if (!empty($translation_updates)) { + // 'en_US' don't usually have the "languages" folder, thus, we + // check if there's a need to ask for filesystem credentials for that + // folder if it exists, most especially for locale other than 'en_US'. + $language_dir = WP_CONTENT_DIR.'/languages'; + if ('en_US' !== get_locale() && is_dir($language_dir)) { + $check_fs['translations'] = $language_dir; + } + } + + foreach ($check_fs as $entity => $dir) { + $filesystem_method = get_filesystem_method(array(), $dir); + ob_start(); + $filesystem_credentials_are_stored = request_filesystem_credentials(site_url()); + $filesystem_form = strip_tags(ob_get_contents(), '

            '); + ob_end_clean(); + $request_filesystem_credentials[$entity] = ('direct' != $filesystem_method && !$filesystem_credentials_are_stored); + } + + $automatic_backups = (class_exists('UpdraftPlus_Options') && class_exists('UpdraftPlus_Addon_Autobackup') && UpdraftPlus_Options::get_updraft_option('updraft_autobackup_default')) ? true : false; + + return $this->_response(array( + 'plugins' => $plugin_updates, + 'themes' => $theme_updates, + 'core' => $core_updates, + 'translations' => $translation_updates, + 'meta' => array( + 'request_filesystem_credentials' => $request_filesystem_credentials, + 'filesystem_form' => $filesystem_form, + 'automatic_backups' => $automatic_backups + ), + )); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/users.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/users.php new file mode 100755 index 00000000..2679eb18 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/modules/users.php @@ -0,0 +1,632 @@ +ID === $b->ID) { + return 0; + } + + return ($a->ID < $b->ID) ? -1 : 1; + } + + /** + * Searches users based from the keyword submitted + * + * @internal + * @param array $query Parameter array containing the filter and keyword fields + * @return array Contains the list of users found as well as the total users count + */ + private function _search_users($query) { + $this->_admin_include('user.php'); + $query1 = new WP_User_Query(array( + 'orderby' => 'ID', + 'order' => 'ASC', + 'role'=> $query["role"], + 'search' => '*' . esc_attr($query["search"]) . '*', + 'search_columns' => array('user_login', 'user_email') + )); + $query2 = new WP_User_Query(array( + 'orderby' => 'ID', + 'order' => 'ASC', + 'role'=> $query["role"], + 'meta_query'=>array( + 'relation' => 'OR', + array( + 'key' => 'first_name', + 'value' => $query["search"], + 'compare' => 'LIKE' + ), + array( + 'key' => 'last_name', + 'value' => $query["search"], + 'compare' => 'LIKE' + ), + ) + )); + + if (empty($query1->results) && empty($query2->results)) { + return array("message" => "users_not_found"); + } else { + $found_users = array_merge($query1->results, $query2->results); + $temp = array(); + foreach ($found_users as $new_user) { + if (!isset($temp[$new_user->ID])) { + $temp[$new_user->ID] = $new_user; + } + }; + + $users = array_values($temp); + + // Sort users: + usort($users, array($this, 'compare_user_id')); + $offset = ((int) $query['page_no'] * (int) $query['per_page']) - (int) $query['per_page']; + $user_list = array_slice($users, $offset, $query['per_page']); + + return array( + 'users' => $user_list, + 'total_users' => count($users) + ); + } + } + + /** + * Calculates the number of pages needed to construct the pagination links + * + * @internal + * @param array $query + * @param array $total_users The total number of users found from the WP_User_Query query + * @return array Contains information needed to construct the pagination links + */ + private function _calculate_pages($query, $total_users) { + + $per_page_options = array(10, 20, 30, 40, 50); + + if (!empty($query)) { + + $pages = array(); + $page_count = ceil($total_users / $query["per_page"]); + if ($page_count > 1) { + + for ($i = 0; $i < $page_count; $i++) { + if ($i + 1 == $query['page_no']) { + $paginator_item = array( + "value"=>$i+1, + "setting"=>"disabled" + ); + } else { + $paginator_item = array( + "value"=>$i+1 + ); + } + array_push($pages, $paginator_item); + }; + + if ($query['page_no'] >= $page_count) { + $page_next = array( + "value"=>$page_count, + "setting"=>"disabled" + ); + } else { + $page_next = array( + "value"=>$query['page_no'] + 1 + ); + }; + if (1 === $query['page_no']) { + $page_prev = array( + "value"=>1, + "setting"=>"disabled" + ); + } else { + $page_prev = array( + "value"=>$query['page_no'] - 1 + ); + }; + + return array( + "page_no" => $query['page_no'], + "per_page" => $query["per_page"], + "page_count" => $page_count, + "pages" => $pages, + "page_next" => $page_next, + "page_prev" => $page_prev, + "total_results" => $total_users, + "per_page_options" => $per_page_options + ); + + } else { + return array( + "page_no" => $query['page_no'], + "per_page" => $query["per_page"], + "page_count" => $page_count, + "total_results" => $total_users, + "per_page_options" => $per_page_options + ); + } + } else { + return array( + "per_page_options" => $per_page_options + ); + } + } + + /** + * Validates whether the username exists + * + * @param array $params Contains the user name to check and validate + * @return array An array containing the result of the current process + */ + public function check_username($params) { + $this->_admin_include('user.php'); + $username = $params['user_name']; + + $blog_id = get_current_blog_id(); + if (!empty($params['site_id'])) { + $blog_id = $params['site_id']; + } + + + // Here, we're switching to the actual blog that we need + // to pull users from. + + $switched = function_exists('switch_to_blog') ? switch_to_blog($blog_id) : false; + + if (username_exists($username) && is_user_member_of_blog(username_exists($username), $blog_id)) { + $result = array("valid" => false, "message" => 'username_exists'); + return $this->_response($result); + } + if (!validate_username($username)) { + $result = array("valid" => false, "message" => 'username_invalid'); + return $this->_response($result); + } + + + // Here, we're restoring to the current (default) blog before we + // do the switched. + + if (function_exists('restore_current_blog') && $switched) { + restore_current_blog(); + } + + $result = array("valid" => true, "message" => 'username_valid'); + return $this->_response($result); + } + + /** + * Pulls blog sites available + * for the current WP instance. + * If the site is a multisite, then sites under the network + * will be pulled, otherwise, it will return an empty array. + * + * @return Array - an array of sites + */ + private function _get_blog_sites() { + + if (!is_multisite()) return array(); + + // Initialize array container + $sites = $network_sites = array(); + + // Check to see if latest get_sites (available on WP version >= 4.6) function is + // available to pull any available sites from the current WP instance. If not, then + // we're going to use the fallback function wp_get_sites (for older version). + if (function_exists('get_sites') && class_exists('WP_Site_Query')) { + $network_sites = get_sites(); + } else { + if (function_exists('wp_get_sites')) { + $network_sites = wp_get_sites(); + } + } + + // We only process if sites array is not empty, otherwise, bypass + // the next block. + if (!empty($network_sites)) { + foreach ($network_sites as $site) { + + // Here we're checking if the site type is an array, because + // we're pulling the blog_id property based on the type of + // site returned. + // get_sites returns an array of object, whereas the wp_get_sites + // function returns an array of array. + $blog_id = is_array($site) ? $site['blog_id'] : $site->blog_id; + + + // We're saving the blog_id and blog name as an associative item + // into the sites array, that will be used as "Sites" option in + // the frontend. + $sites[$blog_id] = get_blog_details($blog_id)->blogname; + } + } + + return $sites; + } + + /** + * Validates whether the email exists + * + * @param array $params Contains the email to check and validate + * @return array An array containing the result of the current process + */ + public function check_email($params) { + $this->_admin_include('user.php'); + $email = $params['email']; + + $blog_id = get_current_blog_id(); + if (isset($params['site_id']) && 0 !== $params['site_id']) { + $blog_id = $params['site_id']; + } + + + // Here, we're switching to the actual blog that we need + // to pull users from. + + $switched = false; + if (function_exists('switch_to_blog')) { + $switched = switch_to_blog($blog_id); + } + + if (is_email($email) === false) { + $result = array("valid" => false, "message" => 'email_invalid'); + return $this->_response($result); + } + + if (email_exists($email) && is_user_member_of_blog(email_exists($email), $blog_id)) { + $result = array("valid" => false, "message" => 'email_exists'); + return $this->_response($result); + } + + // Here, we're restoring to the current (default) blog before we + // do the switched. + + if (function_exists('restore_current_blog') && $switched) { + restore_current_blog(); + } + + $result = array("valid" => true, "message" => 'email_valid'); + return $this->_response($result); + } + + /** + * The get_users function pull all the users from the database + * based on the current search parameters/filters. Please see _search_users + * for the breakdown of these parameters. + * + * @param array $query Parameter array containing the filter and keyword fields + * @return array An array containing the result of the current process + */ + public function get_users($query) { + $this->_admin_include('user.php'); + + // Here, we're getting the current blog id. If blog id + // is passed along with the parameters then we override + // that current (default) value with the parameter blog id value. + $blog_id = get_current_blog_id(); + if (isset($query['site_id']) && 0 !== $query['site_id']) $blog_id = $query['site_id']; + + + // Here, we're switching to the actual blog that we need + // to pull users from. + + $switched = false; + if (function_exists('switch_to_blog')) { + $switched = switch_to_blog($blog_id); + } + + // Set default: + if (empty($query["per_page"])) { + $query["per_page"] = 10; + } + if (empty($query['page_no'])) { + $query['page_no'] = 1; + } + if (empty($query["role"])) { + $query["role"] = ""; + } + + $users = array(); + $total_users = 0; + + if (!empty($query["search"])) { + $search_results = $this->_search_users($query); + + if (isset($search_results['users'])) { + $users = $search_results['users']; + $total_users = $search_results['total_users']; + } + } else { + $user_query = new WP_User_Query(array( + 'orderby' => 'ID', + 'order' => 'ASC', + 'number' => $query["per_page"], + 'paged'=> $query['page_no'], + 'role'=> $query["role"] + )); + + if (empty($user_query->results)) { + $result = array("message" => 'users_not_found'); + return $this->_response($result); + } + + $users = $user_query->results; + $total_users = $user_query->get_total(); + } + + foreach ($users as &$user) { + $user_object = get_userdata($user->ID); + if (method_exists($user_object, 'to_array')) { + $user = $user_object->to_array(); + $user["roles"] = $user_object->roles; + $user["first_name"] = $user_object->first_name; + $user["last_name"] = $user_object->last_name; + $user["description"] = $user_object->description; + } else { + $user = $user_object; + } + } + + $result = array( + "users"=>$users, + "paging" => $this->_calculate_pages($query, $total_users) + ); + + // Here, we're restoring to the current (default) blog before we + // do the switched. + + if (function_exists('restore_current_blog') && $switched) { + restore_current_blog(); + } + return $this->_response($result); + } + + /** + * Creates new user for the current blog + * + * @param array $user User information to add + * @return array An array containing the result of the current process + */ + public function add_user($user) { + $this->_admin_include('user.php'); + // Here, we're getting the current blog id. If blog id + // is passed along with the parameters then we override + // that current (default) value with the parameter blog id value. + + + $blog_id = get_current_blog_id(); + if (isset($user['site_id']) && 0 !== $user['site_id']) $blog_id = $user['site_id']; + + + // Here, we're switching to the actual blog that we need + // to pull users from. + + $switched = false; + if (function_exists('switch_to_blog')) { + $switched = switch_to_blog($blog_id); + } + + if (!current_user_can('create_users') && !is_super_admin()) { + $result = array('error' => true, 'message' => 'user_create_no_permission', 'data' => array('multisite' => is_multisite())); + return $this->_response($result); + } + if (is_email($user["user_email"]) === false) { + $result = array("error" => true, "message" => "email_invalid"); + return $this->_response($result); + } + if (email_exists($user["user_email"]) && is_user_member_of_blog(email_exists($user["user_email"]), $blog_id)) { + $result = array("error" => true, "message" => "email_exists"); + return $this->_response($result); + } + if (username_exists($user["user_login"]) && is_user_member_of_blog(username_exists($user["user_login"]), $blog_id)) { + $result = array("error" => true, "message" => "username_exists"); + return $this->_response($result); + } + if (!validate_username($user["user_login"])) { + $result = array("error" => true, "message" => 'username_invalid'); + return $this->_response($result); + } + if (isset($user['site_id']) && !current_user_can('manage_network_users')) { + $result = array("error" => true, "message" => 'user_create_no_permission'); + return $this->_response($result); + } + + if (email_exists($user["user_email"]) && !is_user_member_of_blog(email_exists($user["user_email"]), $blog_id)) { + $user_id = email_exists($user["user_email"]); + } else { + $user_id = wp_insert_user($user); + } + $role = $user['role']; + if (is_multisite()) { + add_existing_user_to_blog(array('user_id' => $user_id, 'role' => $role)); + } + + // Here, we're restoring to the current (default) blog before we + // do the switched. + + if (function_exists('restore_current_blog') && $switched) { + restore_current_blog(); + } + + if ($user_id > 0) { + $result = array("error" => false, "message" => "user_created_with_user_name", "values" => array($user['user_login'])); + return $this->_response($result); + } else { + $result = array("error" => true, "message" => "user_create_failed", "values" => array($user)); + } + + + return $this->_response($result); + } + + /** + * [delete_user - UCP: users.delete_user] + * + * This function is used to check to make sure the user_id is valid and that it has has user delete permissions. + * If there are no issues, the user is deleted. + * + * current_user_can: This check the user permissions from UCP + * get_userdata: This get the user data on the data from user_id in the $user_id array + * wp_delete_user: Deleting users on the User ID (user_id) and, IF Specified, the Assigner ID (assign_user_id). + * + * @param [type] $params [description] THis is an Array of params sent over from UpdraftCentral + * @return [type] Array [description] This will send back an error array along with message if there are any issues with the user_id + */ + public function delete_user($params) { + $this->_admin_include('user.php'); + $user_id = $params['user_id']; + $assign_user_id = $params["assign_user_id"]; + // Here, we're getting the current blog id. If blog id + // is passed along with the parameters then we override + // that current (default) value with the parameter blog id value. + + $blog_id = get_current_blog_id(); + if (isset($params['site_id']) && 0 !== $params['site_id']) $blog_id = $params['site_id']; + + $switched = false; + if (function_exists('switch_to_blog')) { + $switched = switch_to_blog($blog_id); + } + + if (!current_user_can('delete_users') && !is_super_admin()) { + $result = array('error' => true, 'message' => 'user_delete_no_permission', 'data' => array('multisite' => is_multisite())); + return $this->_response($result); + } + if (get_userdata($user_id) === false) { + $result = array("error" => true, "message" => "user_not_found"); + return $this->_response($result); + } + + if (wp_delete_user($user_id, $assign_user_id)) { + $result = array("error" => false, "message" => "user_deleted"); + } else { + $result = array("error" => true, "message" => "user_delete_failed"); + } + + // Here, we're restoring to the current (default) blog before we + // do the switched. + + if (function_exists('restore_current_blog') && $switched) { + restore_current_blog(); + } + + return $this->_response($result); + } + + /** + * Edits existing user information + * + * @param array $user User information to save + * @return array An array containing the result of the current process + */ + public function edit_user($user) { + $this->_admin_include('user.php'); + + // Here, we're getting the current blog id. If blog id + // is passed along with the parameters then we override + // that current (default) value with the parameter blog id value. + + $blog_id = get_current_blog_id(); + if (isset($user['site_id']) && 0 !== $user['site_id']) $blog_id = $user['site_id']; + + // Here, we're switching to the actual blog that we need + // to apply our changes. + + $switched = false; + if (function_exists('switch_to_blog')) { + $switched = switch_to_blog($blog_id); + } + + if (!current_user_can('edit_users') && !is_super_admin() && get_current_user_id() !== $user["ID"]) { + $result = array('error' => true, 'message' => 'user_edit_no_permission', 'data' => array('multisite' => is_multisite())); + return $this->_response($result); + } + + if (false === get_userdata($user["ID"])) { + $result = array("error" => true, "message" => "user_not_found"); + return $this->_response($result); + } + if (get_current_user_id() == $user["ID"]) { + unset($user["role"]); + } + + /* Validate Username*/ + if (!validate_username($user["user_login"])) { + $result = array("error" => true, "message" => 'username_invalid'); + return $this->_response($result); + } + /* Validate Email if not the same*/ + + $remote_user = get_userdata($user["ID"]); + $old_email = $remote_user->user_email; + + if ($user['user_email'] !== $old_email) { + if (is_email($user['user_email']) === false) { + $result = array("error" => true, "message" => 'email_invalid'); + return $this->_response($result); + } + + if (email_exists($user['user_email'])) { + $result = array("error" => true, "message" => 'email_exists'); + return $this->_response($result); + } + } + + + $user_id = wp_update_user($user); + if (is_wp_error($user_id)) { + $result = array("error" => true, "message" => "user_edit_failed_with_error", "values" => array($user_id)); + } else { + $result = array("error" => false, "message" => "user_edited_with_user_name", "values" => array($user["user_login"])); + } + + // Here, we're restoring to the current (default) blog before we + // do the switched. + + if (function_exists('restore_current_blog') && $switched) { + restore_current_blog(); + } + + return $this->_response($result); + } + + /** + * Retrieves available roles to be used as filter options + * + * @return array An array containing all available roles + */ + public function get_roles() { + $this->_admin_include('user.php'); + $roles = array_reverse(get_editable_roles()); + return $this->_response($roles); + } + + /** + * Retrieves information to be use as filters + * + * @return array An array containing the filter fields and their data + */ + public function get_user_filters() { + $this->_admin_include('user.php'); + + // Pull sites options if available. + $sites = $this->_get_blog_sites(); + + $result = array( + "sites" => $sites, + "roles" => array_reverse(get_editable_roles()), + "paging" => $this->_calculate_pages(null, 0), + ); + return $this->_response($result); + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/translations-central.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/translations-central.php new file mode 100755 index 00000000..4d13db86 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/translations-central.php @@ -0,0 +1,99 @@ + __('UpdraftCentral Connection', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'updraftcentral_connection_successful' => __('An UpdraftCentral connection has been made successfully.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'updraftcentral_connection_failed' => __('A new UpdraftCentral connection has not been made.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'unknown_key' => __('The key referred to was unknown.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'not_logged_in' => __('You are not logged into this WordPress site in your web browser.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'must_visit_url' => __('You must visit this URL in the same browser and login session as you created the key in.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'security_check' => __('Security check.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'must_visit_link' => __('You must visit this link in the same browser and login session as you created the key in.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'connection_already_made' => __('This connection appears to already have been made.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'close' => __('Close', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'nothing_yet_logged' => __('(Nothing yet logged)', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'invalid_url' => __('An invalid URL was entered', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'updraftcentral_key_created' => __('UpdraftCentral key created successfully', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'need_to_copy_key' => __('You now need to copy the key below and enter it at your %s.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'press_add_site_button' => __('At your UpdraftCentral dashboard you should press the "Add Site" button then paste the key in the input box.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'detailed_instructions' => __('Detailed instructions for this can be found at %s', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'control_this_site' => __('You can now control this site via your UpdraftCentral dashboard at %s.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'attempt_to_register_failed' => __('A key was created, but the attempt to register it with %1$s was unsuccessful.', UPDRAFTCENTRAL_TEXT_DOMAIN).' '.__('You can try again, or try using the alternative connection method if the problem persists.', UPDRAFTCENTRAL_TEXT_DOMAIN).' '.__('For more information visit %2$s', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'key_created_successfully' => __('Key created successfully.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'copy_paste_key' => __('You must copy and paste this key now - it cannot be shown again.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'no_updraftcentral_dashboards' => __('There are no UpdraftCentral dashboards that can currently control this site.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'unknown' => __('Unknown', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'access_as_user' => __('Access this site as user:', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'public_key_sent' => __('Public key was sent to:', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'created' => __('Created:', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'key_size' => __('Key size: %d bits', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'delete' => __('Delete...', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'manage_keys' => __('Manage existing keys (%d)...', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'key_description' => __('Key description', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'details' => __('Details', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'connect_to_updraftcentral_dashboard' => __('Connect this site to an UpdraftCentral dashboard found at...', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'in_example' => __('i.e. if you have %s there', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'an_account' => __('an account', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'self_hosted_dashboard' => __('Self-hosted dashboard', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'website_installed' => __('A website where you have installed %s', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'enter_url' => __('Enter the URL where your self-hosted install of UpdraftCentral is located:', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'updraftcentral_dashboard_url' => __('URL for the site of your UpdraftCentral dashboard', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'next' => __('Next', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'updraftcentral_connection_details' => __('UpdraftCentral dashboard connection details', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'description' => __('Description', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'enter_description' => __('Enter any description', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'encryption_key_size' => __('Encryption key size:', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'bits' => __('%s bits', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'bytes' => __('%s bytes', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'easy_to_break' => __('easy to break, fastest', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'faster' => __('faster (possibility for slow PHP installs)', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'recommended' => __('recommended', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'slower' => __('slower, strongest', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'use_alternative_method' => __('Use the alternative method for making a connection with the dashboard.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'more_information' => __('More information...', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'this_is_useful' => __('This is useful if the dashboard webserver cannot be contacted with incoming traffic by this website (for example, this is the case if this website is hosted on the public Internet, but the UpdraftCentral dashboard is on localhost, or on an Intranet, or if this website has an outgoing firewall), or if the dashboard website does not have a SSL certificate.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'create' => __('Create', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'back' => __('Back...', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'view_log_events' => __('View recent UpdraftCentral log events', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'updraftcentral_remote_control' => __('UpdraftCentral (Remote Control)', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'updraftcentral_description' => __('UpdraftCentral enables control of your WordPress sites %s from a central dashboard.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'including_description' => array( + 'wp_optimize_desc' => __('(including management of WP-Optimize)', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'updraftplus_desc' => __('(including management of backups and updates)', UPDRAFTCENTRAL_TEXT_DOMAIN), + ), + 'read_more' => __('Read more about it here.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'create_another_key' => __('Create another key', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'unable_to_connect' => __('Unable to connect to the filesystem', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'unable_to_activate' => __('Unable to activate %s successfully.', UPDRAFTCENTRAL_TEXT_DOMAIN).' '.__('Make sure that this %s is compatible with your remote WordPress version.', UPDRAFTCENTRAL_TEXT_DOMAIN).' '.__('WordPress version currently installed in your remote website is %s.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'unable_to_install' => __('Unable to install %s.', UPDRAFTCENTRAL_TEXT_DOMAIN).' '.__('Make sure you upload the correct file and that the zip file is a valid %s file (not corrupted) and try uploading the file again.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'failed_to_attach_media' => __('Failed to attach media.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'media_attached' => __('Media has been attached to post.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'failed_to_detach_media' => __('Failed to detach media.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'media_detached' => __('Media has been detached from post.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'failed_to_delete_media' => __('Failed to delete selected media.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'selected_media_deleted' => __('Selected media has been deleted successfully.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'unattached' => __('Unattached', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'default_template' => __('Default template', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'parameters_missing' => __('Expected parameter(s) missing.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'fetching' => __('Fetching...', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'deleting' => __('Deleting...', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'enter_mothership_url' => __('Please enter a valid URL', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'creating_please_allow' => __('Creating...', UPDRAFTCENTRAL_TEXT_DOMAIN).(function_exists('openssl_encrypt') ? '' : ' ('.__('your PHP install lacks the openssl module; as a result, this can take minutes; if nothing has happened by then, then you should either try a smaller key size, or ask your web hosting company how to enable this PHP module on your setup.', UPDRAFTCENTRAL_TEXT_DOMAIN).')'), + 'unexpectedresponse' => __('Unexpected response:', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'updraftcentral_wizard_empty_url' => __('Please enter the URL where your UpdraftCentral dashboard is hosted.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'updraftcentral_wizard_invalid_url' => __('Please enter a valid URL e.g http://example.com', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'insufficient_privilege' => __('Sorry, you do not have enough privilege to execute the requested action.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'copy_to_clipboard' => __('Copy to clipboard', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'key_copied' => __('The key was copied to the clipboard.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'unable_to_copy' => __('The attempt to copy to the clipboard failed.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'wpo_not_active' => __('WP_Optimize is not installed or active.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'log_file_not_exist' => __('Log file does not exist or could not be read.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'security_check_failed' => __('Security check failed; try refreshing the page.', UPDRAFTCENTRAL_TEXT_DOMAIN).' '.__('If refreshing the page does not help then perhaps you do not have sufficient privilege to manage WP-Optimize.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'no_such_command' => __('No such command found.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'command_not_allowed' => __('You are not allowed to run this command.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'command_not_found' => __('The command is either not found or not allowed.', UPDRAFTCENTRAL_TEXT_DOMAIN), + 'network_admin_only' => __('The command can only be executed by a network admin.', UPDRAFTCENTRAL_TEXT_DOMAIN), +); diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/updraftplus.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/updraftplus.php new file mode 100755 index 00000000..d460053e --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/updraftplus.php @@ -0,0 +1,282 @@ +maybe_initialize_required_objects(); + } + + /** + * Loads the UpdraftCentral_Main instance + * + * @return void + */ + public function load_updraftcentral() { + $central_path = $this->is_host_dir_set() ? trailingslashit(UPDRAFTPLUS_DIR) : ''; + + if (file_exists($central_path.'central/bootstrap.php')) { + include_once($central_path.'central/bootstrap.php'); + } + } + + /** + * Whether the current user can perform key control AJAX actions + * + * @return Boolean + */ + public function current_user_can_ajax() { + return UpdraftPlus_Options::user_can_manage(); + } + + /** + * Below are interface methods' implementations that are required by UpdraftCentral to function properly. Please + * see the "interface.php" to check all the required interface methods. + */ + + /** + * Checks whether the plugin's DIR constant is currently define or not + * + * @return bool + */ + public function is_host_dir_set() { + return defined('UPDRAFTPLUS_DIR') ? true : false; + } + + /** + * Get the host plugin's dir path + * + * @return string + */ + public function get_host_dir() { + return defined('UPDRAFTPLUS_DIR') ? UPDRAFTPLUS_DIR : dirname(dirname(__FILE__)); + } + + /** + * Retrieves the filter used by UpdraftPlus to log errors or certain events + * + * @return string + */ + public function get_logline_filter() { + return 'updraftplus_logline'; + } + + /** + * Checks whether debug mod is set + * + * @return bool + */ + public function get_debug_mode() { + if (class_exists('UpdraftPlus_Options')) { + return UpdraftPlus_Options::get_updraft_option('updraft_debug_mode'); + } + return false; + } + + /** + * Used as a central location (to avoid repetition) to register or de-register hooks into the WP HTTP API + * + * @param bool $register True to register, false to de-register + * @return void + */ + public function register_wp_http_option_hooks($register = true) { + global $updraftplus; + + if ($updraftplus) { + $updraftplus->register_wp_http_option_hooks($register); + } + } + + /** + * Retrieves the class name of the host plugin + * + * @return string|bool + */ + public function get_class_name() { + global $updraftplus; + + if ($updraftplus) { + return get_class($updraftplus); + } + + return false; + } + + /** + * Returns the instance of the host plugin + * + * @return object|bool + */ + public function get_instance() { + global $updraftplus; + + if ($updraftplus) { + return $updraftplus; + } + + return false; + } + + /** + * Returns the admin instance of the host plugin + * + * @return object|bool + */ + public function get_admin_instance() { + global $updraftplus_admin; + + if ($updraftplus_admin) { + return $updraftplus_admin; + } else { + if (defined('UPDRAFTPLUS_DIR') && file_exists(UPDRAFTPLUS_DIR.'/admin.php')) { + updraft_try_include_file('admin.php', 'include_once'); + $updraftplus_admin = new UpdraftPlus_Admin(); + return $updraftplus_admin; + } + } + + return false; + } + + /** + * Logs the given line + * + * @param string $line The log line + * @param string $level The log level: notice, warning, error, etc. + * @param boolean|string $uniq_id Each of these will only be logged once + * + * @return void + */ + public function log($line, $level = 'notice', $uniq_id = false) { + global $updraftplus; + + if ($updraftplus) { + if (is_callable(array($updraftplus, 'log'))) { + call_user_func(array($updraftplus, 'log'), $line, $level, $uniq_id); + } + } + } + + /** + * Returns the current version of the host plugin + * + * @return string|bool + */ + public function get_version() { + global $updraftplus; + + if ($updraftplus) { + return $updraftplus->version; + } + + return false; + } + + /** + * Returns the filesystem class of the host's plugin + * + * @return class|bool + */ + public function get_filesystem_functions() { + if ($this->has_filesystem_functions()) { + return UpdraftPlus_Filesystem_Functions; + } + + return false; + } + + /** + * Checks whether the filesystem class of the host plugin exists + * + * @return bool + */ + public function has_filesystem_functions() { + return class_exists('UpdraftPlus_Filesystem_Functions'); + } + + /** + * Checks whether force debugging is set + * + * @return bool + */ + public function is_force_debug() { + return (defined('UPDRAFTPLUS_UDRPC_FORCE_DEBUG') && UPDRAFTPLUS_UDRPC_FORCE_DEBUG) ? true : false; + } + + /** + * Initializes required objects (if not yet initialized) for UpdraftCentral usage + * + * @return void + */ + private function maybe_initialize_required_objects() { + global $updraftplus; + + if (!class_exists('UpdraftPlus')) { + if (defined('UPDRAFTPLUS_DIR') && file_exists(UPDRAFTPLUS_DIR.'/class-updraftplus.php')) { + updraft_try_include_file('class-updraftplus.php', 'include_once'); + if (empty($updraftplus) || !is_a($updraftplus, 'UpdraftPlus')) { + $updraftplus = new UpdraftPlus(); + } + } + } + + if (!class_exists('UpdraftPlus_Options')) { + if (defined('UPDRAFTPLUS_DIR') && file_exists(UPDRAFTPLUS_DIR.'/options.php')) { + updraft_try_include_file('options.php', 'require_once'); + } + } + + if (!class_exists('UpdraftPlus_Filesystem_Functions')) { + if (defined('UPDRAFTPLUS_DIR') && file_exists(UPDRAFTPLUS_DIR.'/includes/class-filesystem-functions.php')) { + updraft_try_include_file('includes/class-filesystem-functions.php', 'require_once'); + } + } + } + + /** + * Load translations which are based on UpdraftPlus domain text + */ + public function load_updraftplus_translations() { + // Load updraftplus translations + if (defined('UPDRAFTCENTRAL_CLIENT_DIR') && file_exists(UPDRAFTCENTRAL_CLIENT_DIR.'/translations-central.php')) { + $this->translations = include(UPDRAFTCENTRAL_CLIENT_DIR.'/translations-central.php'); + } + } +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/wp-optimize.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/wp-optimize.php new file mode 100755 index 00000000..7d4f4d3b --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/central/wp-optimize.php @@ -0,0 +1,156 @@ +capability_required()); + } + + /** + * Loads the UpdraftCentral_Main instance + * + * @return void + */ + public function load_updraftcentral() { + $central_path = $this->is_host_dir_set() ? trailingslashit(WPO_PLUGIN_MAIN_PATH) : ''; + + if (!empty($central_path) && file_exists($central_path.'central/bootstrap.php')) { + include_once($central_path.'central/bootstrap.php'); + } + } + + /** + * Checks whether the plugin's DIR constant is currently define or not + * + * @return bool + */ + public function is_host_dir_set() { + return defined('WPO_PLUGIN_MAIN_PATH') ? true : false; + } + + /** + * Get the host plugin's dir path + * + * @return string + */ + public function get_host_dir() { + return defined('WPO_PLUGIN_MAIN_PATH') ? WPO_PLUGIN_MAIN_PATH : dirname(dirname(__FILE__)); + } + + /** + * Returns the current version of the host plugin + * + * @return string|bool + */ + public function get_version() { + return defined('WPO_VERSION') ? WPO_VERSION : false; + } + + /** + * Returns the instance of the host plugin + * + * @return object|bool + */ + public function get_instance() { + global $wp_optimize; + + if ($wp_optimize) { + return $wp_optimize; + } + + return false; + } + + /** + * Checks whether debug mod is set + * + * @return bool + */ + public function get_debug_mode() { + return (defined('WP_OPTIMIZE_DEBUG_OPTIMIZATIONS') && WP_OPTIMIZE_DEBUG_OPTIMIZATIONS); + } + + /** + * Logs the given line + * + * @param string $line The log line + * @param string $level The log level: notice, warning, error, etc. + * @param boolean|string $uniq_id Each of these will only be logged once + * + * @return void + */ + public function log($line, $level = 'notice', $uniq_id = false) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Unused parameter is present because the the abstract UpdraftCentral_Host class uses 3 arguments. + global $wp_optimize; + + if ($wp_optimize) { + if (is_callable(array($wp_optimize, 'log'))) { + call_user_func(array($wp_optimize, 'log'), $line); + } + } + } + + /** + * Load translations which are based on UpdraftPlus domain text + */ + public function load_updraftplus_translations() { + // Load wp-optimize translations + if (defined('UPDRAFTCENTRAL_CLIENT_DIR') && file_exists(UPDRAFTCENTRAL_CLIENT_DIR.'/translations-central.php')) { + $this->translations = include(UPDRAFTCENTRAL_CLIENT_DIR.'/translations-central.php'); + } + } + + /** + * Developer Note: + * + * You can add your class methods below if ever you want to extend or modify + * the module handlers of UpdraftCentral located at central/modules. Just be + * sure to use this class to abstract any functionality that would link to the + * wp-optimize plugin. + * + * N.B. All custom methods added here will then be available from the global + * variable $updraftcentral_host_plugin (e.g. $updraftcentral_host_plugin->YOUR_METHOD) + */ +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/composer.json b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/composer.json new file mode 100755 index 00000000..a9d15c97 --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/vendor/team-updraft/lib-central/composer.json @@ -0,0 +1,4 @@ +{ + "name": "team-updraft/lib-central", + "type": "library" +} diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/wp-security-core.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/wp-security-core.php new file mode 100755 index 00000000..678c417f --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/wp-security-core.php @@ -0,0 +1,699 @@ +define_constants(); + $this->load_configs(); + $this->includes(); + $this->loader_operations(); + + add_action('init', array($this, 'wp_security_plugin_init'), 0); + add_action('init', array($this, 'load_plugin_textdomain')); + add_action('wp_loaded', array($this, 'aiowps_wp_loaded_handler')); + + $add_update_action_prefixes = array( + 'add_option_', + 'update_option_', + ); + foreach ($add_update_action_prefixes as $add_update_action_prefix) { + add_action($add_update_action_prefix . '_updraft_interval_database', array($this, 'udp_schedule_db_option_add_update_action_handler'), 10, 2); + } + + if ('1' == $this->configs->get_site_value('aiowps_enable_salt_postfix')) { + add_filter('salt', array($this, 'salt'), 10, 2); + } + + do_action('aiowpsecurity_loaded'); + + } + + /** + * Return the URL for the plugin directory + * + * @return String + */ + public function plugin_url() { + if ($this->plugin_url) return $this->plugin_url; + return $this->plugin_url = plugins_url('', __FILE__); + } + + public function plugin_path() { + if ($this->plugin_path) return $this->plugin_path; + return $this->plugin_path = untrailingslashit(plugin_dir_path(__FILE__)); + } + + public function load_configs() { + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-config.php'); + $this->configs = AIOWPSecurity_Config::get_instance(); + } + + public function define_constants() { + define('AIO_WP_SECURITY_VERSION', $this->version); + define('AIO_WP_SECURITY_DB_VERSION', $this->db_version); + define('AIO_WP_SECURITY_FIREWALL_VERSION', $this->firewall_version); + define('AIOWPSEC_WP_HOME_URL', home_url()); + define('AIOWPSEC_WP_SITE_URL', site_url()); + define('AIOWPSEC_WP_URL', AIOWPSEC_WP_SITE_URL); // for backwards compatibility + define('AIO_WP_SECURITY_URL', $this->plugin_url()); + define('AIO_WP_SECURITY_PATH', $this->plugin_path()); + define('AIO_WP_SECURITY_BACKUPS_DIR_NAME', 'aiowps_backups'); + define('AIO_WP_SECURITY_BACKUPS_PATH', AIO_WP_SECURITY_PATH.'/backups'); + define('AIO_WP_SECURITY_LIB_PATH', AIO_WP_SECURITY_PATH.'/lib'); + if (!defined('AIOWPSEC_MANAGEMENT_PERMISSION')) { // This will allow the user to define custom capability for this constant in wp-config file + define('AIOWPSEC_MANAGEMENT_PERMISSION', 'manage_options'); + } + define('AIOWPSEC_MENU_SLUG_PREFIX', 'aiowpsec'); + define('AIOWPSEC_MAIN_MENU_SLUG', 'aiowpsec'); + define('AIOWPSEC_SETTINGS_MENU_SLUG', 'aiowpsec_settings'); + define('AIOWPSEC_USER_SECURITY_MENU_SLUG', 'aiowpsec_usersec'); + define('AIOWPSEC_DB_SEC_MENU_SLUG', 'aiowpsec_database'); + define('AIOWPSEC_FILESYSTEM_MENU_SLUG', 'aiowpsec_filesystem'); + define('AIOWPSEC_FIREWALL_MENU_SLUG', 'aiowpsec_firewall'); + define('AIOWPSEC_SPAM_MENU_SLUG', 'aiowpsec_spam'); + define('AIOWPSEC_FILESCAN_MENU_SLUG', 'aiowpsec_filescan'); + define('AIOWPSEC_BRUTE_FORCE_MENU_SLUG', 'aiowpsec_brute_force'); + define('AIOWPSEC_TWO_FACTOR_AUTH_MENU_SLUG', 'aiowpsec_two_factor_auth_user'); + define('AIOWPSEC_TOOLS_MENU_SLUG', 'aiowpsec_tools'); + define('AIOWPSEC_CAPTCHA_SHORTCODE', 'aios_captcha'); + + if (!defined('AIOS_TFA_PREMIUM_LATEST_INCOMPATIBLE_VERSION')) define('AIOS_TFA_PREMIUM_LATEST_INCOMPATIBLE_VERSION', '1.14.7'); + + if (!defined('AIOWPSEC_PURGE_FAILED_LOGIN_RECORDS_AFTER_DAYS')) define('AIOWPSEC_PURGE_FAILED_LOGIN_RECORDS_AFTER_DAYS', 90); + if (!defined('AIOS_PURGE_EVENTS_RECORDS_AFTER_DAYS')) define('AIOS_PURGE_EVENTS_RECORDS_AFTER_DAYS', 90); + if (!defined('AIOS_PURGE_LOGIN_LOCKOUT_RECORDS_AFTER_DAYS')) define('AIOS_PURGE_LOGIN_LOCKOUT_RECORDS_AFTER_DAYS', 90); + if (!defined('AIOS_PURGE_LOGIN_ACTIVITY_RECORDS_AFTER_DAYS')) define('AIOS_PURGE_LOGIN_ACTIVITY_RECORDS_AFTER_DAYS', 90); + if (!defined('AIOS_PURGE_GLOBAL_META_DATA_RECORDS_AFTER_DAYS')) define('AIOS_PURGE_GLOBAL_META_DATA_RECORDS_AFTER_DAYS', 90); + if (!defined('AIOS_DEFAULT_BRUTE_FORCE_FEATURE_SECRET_WORD')) define('AIOS_DEFAULT_BRUTE_FORCE_FEATURE_SECRET_WORD', 'aiossecret'); + if (!defined('AIOS_FIREWALL_MAX_FILE_UPLOAD_LIMIT_MB')) define('AIOS_FIREWALL_MAX_FILE_UPLOAD_LIMIT_MB', 100); + if (!defined('AIOS_UPDATE_ANTIBOT_KEYS_AFTER_DAYS')) define('AIOS_UPDATE_ANTIBOT_KEYS_AFTER_DAYS', 5); + + global $wpdb; + define('AIOWPSEC_TBL_LOGIN_LOCKOUT', $wpdb->prefix . 'aiowps_login_lockdown'); + define('AIOWPSEC_TBL_FAILED_LOGINS', $wpdb->prefix . 'aiowps_failed_logins'); + define('AIOWPSEC_TBL_USER_LOGIN_ACTIVITY', $wpdb->prefix . 'aiowps_login_activity'); + define('AIOWPSEC_TBL_GLOBAL_META_DATA', $wpdb->prefix . 'aiowps_global_meta'); + define('AIOWPSEC_TBL_EVENTS', $wpdb->prefix . 'aiowps_events'); + define('AIOWPSEC_TBL_PERM_BLOCK', $wpdb->prefix . 'aiowps_permanent_block'); + + $base_prefix = $this->get_table_prefix(); + define('AIOWPSEC_TBL_AUDIT_LOG', $base_prefix . 'aiowps_audit_log'); + define('AIOWPSEC_TBL_DEBUG_LOG', $base_prefix . 'aiowps_debug_log'); + define('AIOWPSEC_TBL_LOGGED_IN_USERS', $base_prefix . 'aiowps_logged_in_users'); + define('AIOWPSEC_TBL_MESSAGE_STORE', $base_prefix . 'aiowps_message_store'); + } + + /** + * Includes required files. + * + * @return void + */ + public function includes() { + // Load firewall, if it has not yet been loaded by this point + if (!defined('AIOWPSEC_FIREWALL_DONE')) { + $this->load_aio_firewall(); + } + + // Load common files for everywhere + if (!class_exists('Updraft_Semaphore_3_0')) { + include_once AIO_WP_SECURITY_PATH.'/vendor/team-updraft/common-libs/src/updraft-semaphore/class-updraft-semaphore.php'; + } + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-firewall-resource-unavailable.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-firewall-resource.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-audit-event-handler.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-debug-logger.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-abstract-ids.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-helper.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-utility.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-utility-htaccess.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-utility-ip-address.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-utility-file.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-utility-permissions.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-utility-ui.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-utility-api.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-general-init-tasks.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-wp-loaded-tasks.php'); + + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-user-login.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-user-registration.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-captcha.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-cleanup.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-file-scan.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-comment.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-cronjob-handler.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/grade-system/wp-security-feature-item.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/grade-system/wp-security-feature-item-manager.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-wp-footer-content.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-blocking.php'); + include_once(AIO_WP_SECURITY_PATH .'/classes/wp-security-two-factor-login.php'); + + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-utility-firewall.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-block-file.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-block-bootstrap.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-block-htaccess.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-block-litespeed.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-block-userini.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-block-wpconfig.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-block-muplugin.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-hibp.php'); + + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-reporting.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-debug.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-sender-service.php'); + + // At this time, sometimes is_admin() can't be populated, It gives the error PHP Fatal error: Uncaught Error: Class 'AIOWPSecurity_Admin_Init' not found. + // so we should not use is_admin() condition. + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-settings-tasks.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-configure-settings.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-notices.php'); + require_once(AIO_WP_SECURITY_PATH.'/admin/wp-security-admin-init.php'); + include_once(AIO_WP_SECURITY_PATH.'/admin/general/wp-security-list-table.php'); + include_once(AIO_WP_SECURITY_PATH.'/admin/general/wp-security-ajax-data-table.php'); + include_once(AIO_WP_SECURITY_PATH.'/admin/wp-security-firewall-setup-notice.php'); + include_once(AIO_WP_SECURITY_PATH.'/classes/updraftcentral.php'); + } + + public function loader_operations() { + add_action('plugins_loaded', array($this, 'plugins_loaded_handler'));//plugins loaded hook + add_action('plugins_loaded', array($this, 'set_pagenow_for_renamed_loginpage')); + + $debug_config = $this->configs->get_value('aiowps_enable_debug'); + $debug_enabled = empty($debug_config) ? false : true; + $this->debug_logger = new AIOWPSecurity_Logger($debug_enabled); + + $this->load_ajax_handler(); + } + + /** + * A filter function to get the management permission for AIOS + * + * @param string $permission - the management permission + * + * @return string - the filtered permission + */ + public function aios_management_permission($permission) { + if (defined('AIOWPSEC_MANAGEMENT_PERMISSION') && AIOWPSEC_MANAGEMENT_PERMISSION) return AIOWPSEC_MANAGEMENT_PERMISSION; + return $permission; + } + + /** + * Activation handler function. + * + * @return void + */ + public static function activate_handler() { + // Only runs when the plugin activates + global $wpdb;// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Used for the include below + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-installer.php'); + AIOWPSecurity_Installer::run_installer(); + AIOWPSecurity_Installer::set_cron_tasks_upon_activation(); + } + + /** + * Delete automated backup configs + * + * @return void + */ + public function delete_automated_backup_configs() { + $automated_config_keys = array( + 'aiowps_enable_automated_backups', + 'aiowps_db_backup_frequency', + 'aiowps_backup_files_stored', + 'aiowps_send_backup_email_address', + 'aiowps_backup_email_address', + ); + foreach ($automated_config_keys as $automated_config_key) { + $this->configs->delete_value($automated_config_key); + } + } + + /** + * UpdraftPlus schedule option add/update action handler. + * + * @param String $option Option name. + * @param String $value Option value. + * @return Void + */ + public function udp_schedule_db_option_add_update_action_handler($option, $value) { + // For extra caution + if ('updraft_interval_database' != $option) { + return; + } + + if (empty($value) || 'manual' == $value) { + return; + } + + $this->delete_automated_backup_configs(); + $this->configs->save_config(); + } + + /** + * Output, or return, the results of running a template (from the 'templates' directory, unless a filter over-rides it). Templates are run with $aio_wp_security and $wpdb set. + * + * @param String $path - path to the template + * @param Boolean $return_instead_of_echo - by default, the template is echo-ed; set this to instead return it + * @param Array $extract_these - variables to inject into the template's run context + * + * @return Void|String + */ + public function include_template($path, $return_instead_of_echo = false, $extract_these = array()) { + if ($return_instead_of_echo) ob_start(); + + if (!isset($template_file)) $template_file = AIO_WP_SECURITY_PATH.'/templates/'.$path; + + $template_file = apply_filters('aio_wp_security_template', $template_file, $path); + + do_action('aio_wp_security_before_template', $path, $template_file, $return_instead_of_echo, $extract_these); + + if (!file_exists($template_file)) { + error_log("All-In-One Security: template not found: $template_file"); + echo __('Error:', 'all-in-one-wp-security-and-firewall').' '.__('template not found', 'all-in-one-wp-security-and-firewall')." ($template_file)"; + } else { + extract($extract_these); + global $wpdb;// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Bring variable into the included template's scope + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Bring variable into the included template's scope + global $aiowps_feature_mgr; // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Bring variable into the included template's scope + $aio_wp_security = $this;// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Bring variable into the included template's scope + include $template_file; + } + + do_action('aio_wp_security_after_template', $path, $template_file, $return_instead_of_echo, $extract_these); + + if ($return_instead_of_echo) return ob_get_clean(); + } + + /** + * Deactivation AIOS plugin. + * + * @return void + */ + public static function deactivation_handler() { + require_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-deactivation-tasks.php'); + AIOWPSecurity_Deactivation_Tasks::run(); + do_action('aiowps_deactivation_complete'); + } + + /** + * Unintall AIOS plugin. + * + * @return void + */ + public static function uninstall_handler() { + require_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-uninstallation-tasks.php'); + AIOWPSecurity_Uninstallation_Tasks::run(); + do_action('aiowps_uninstallation_complete'); + } + + /** + * Firewall configs upgrade. + * + * @return void. + */ + public function firewall_upgrade_handler() { + if (get_option('aiowpsec_firewall_version') != AIO_WP_SECURITY_FIREWALL_VERSION) { + AIOWPSecurity_Configure_Settings::set_firewall_configs(); + AIOWPSecurity_Utility_Htaccess::write_to_htaccess(false); + } + } + + /** + * Upgrades the database. + * + * @return void + */ + public function db_upgrade_handler() { + $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); + + if (get_option('aiowpsec_db_version') != AIO_WP_SECURITY_DB_VERSION) { + require_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-installer.php'); + AIOWPSecurity_Installer::run_installer(); + AIOWPSecurity_Utility_Htaccess::write_to_htaccess(false); + + /** + * Update our config file's header if needed. + */ + if (is_main_site()) { + $aiowps_firewall_config->update_prefix(); + } + } + } + + + /** + * Loads our firewall + * + * @return void + */ + public function load_aio_firewall() { + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-utility-firewall.php'); + $firewall_path = AIOWPSecurity_Utility_Firewall::get_firewall_path(); + + if (!(@include_once($firewall_path))) { + error_log('AIOS firewall error: failed to load the firewall. Unable to include wp-security-firewall.php.'); + } + } + + /** + * Runs when plugins_loaded hook is fired + * + * @return void + */ + public function plugins_loaded_handler() { + //Runs when plugins_loaded action gets fired + // DB upgrade handler - run outside admin interface + $this->db_upgrade_handler(); + $this->firewall_upgrade_handler(); + if (is_admin()) { + //Do plugins_loaded operations for admin side + $this->admin_init = new AIOWPSecurity_Admin_Init(); + $this->notices = new AIOWPSecurity_Notices(); + } + AIOWPSecurity_Audit_Event_Handler::instance(); + } + + /** + * Load plugin text domain + * + * @return void + */ + public function load_plugin_textdomain() { + load_plugin_textdomain('all-in-one-wp-security-and-firewall', false, dirname(plugin_basename(__FILE__)) . '/languages/'); + } + + /** + * Initializes the plugin. This is hooked into the inbuilt 'init' action. + * + * @return Void + */ + public function wp_security_plugin_init() { + //Actions, filters, shortcodes goes here + // AIOWPSecurity_Cronjob_Handler __construct runs filter 'cron_schedules' so the object should be initialized here because it uses translations. + $this->cron_handler = new AIOWPSecurity_Cronjob_Handler(); + $this->user_login_obj = new AIOWPSecurity_User_Login();//Do the user login operation tasks + $this->user_registration_obj = new AIOWPSecurity_User_Registration();//Do the user login operation tasks + $this->captcha_obj = new AIOWPSecurity_Captcha(); // Do the CAPTCHA tasks + $this->cleanup_obj = new AIOWPSecurity_Cleanup(); // Object to handle cleanup tasks + $this->scan_obj = new AIOWPSecurity_Scan();//Object to handle scan tasks + $this->sender_obj = new AIOWPSecurity_Sender_Service();//Object to handle sending emails + $this->debug_obj =new AIOWPSecurity_Debug();//Object to handle debug tasks + add_action('wp_footer', array($this, 'aiowps_footer_content')); + + add_action('wp_login', array('AIOWPSecurity_User_Login', 'wp_login_action_handler'), 10, 2); + // For admin side force log out. + add_action('admin_init', array($this, 'do_action_force_logout_check')); + // For front side force log out. + add_action('template_redirect', array($this, 'do_action_force_logout_check')); + + new AIOWPSecurity_General_Init_Tasks(); + new AIOWPSecurity_Comment(); + new AIOWPSecurity_Reporting(); + + $this->redirect_user_after_force_logout(); + } + + public function aiowps_wp_loaded_handler() { + new AIOWPSecurity_WP_Loaded_Tasks(); + } + + public function aiowps_footer_content() { + new AIOWPSecurity_WP_Footer_Content(); + } + + /** + * Get the installation's base table prefix, optionally allowing the result to be filtered + * + * @return String + */ + public function get_table_prefix() { + global $wpdb; + if (is_multisite() && !defined('MULTISITE')) { + // In this case (which should only be possible on installs upgraded from pre WP 3.0 WPMU), $wpdb->get_blog_prefix() cannot be made to return the right thing. $wpdb->base_prefix is not explicitly marked as public, so we prefer to use get_blog_prefix if we can, for future compatibility. + $prefix = $wpdb->base_prefix; + } else { + $prefix = $wpdb->get_blog_prefix(0); + } + return $prefix; + } + + /** + * Redirect user to proper login page after forced logout + * + * @return void + */ + private function redirect_user_after_force_logout() { + global $aio_wp_security; + if (isset($_GET['aiowpsec_do_log_out'])) { + $nonce = isset($_GET['_wpnonce']) ? $_GET['_wpnonce'] : ''; + // We can not use AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap to check user capabilities = manage_option as subscriber, editor etc users do not have it only administrators will have. If that check is applied it can not force the logout user and creates too many redirect errors. + if (!wp_verify_nonce($nonce, 'aio_logout')) { + return; + } + wp_logout(); + if (isset($_GET['after_logout'])) { //Redirect to the after logout url directly + $after_logout_url = esc_url($_GET['after_logout']); + AIOWPSecurity_Utility::redirect_to_url($after_logout_url); + } + $additional_data = strip_tags($_GET['al_additional_data']); + if (isset($additional_data)) { + $login_url = ''; + + if (AIOWPSecurity_Utility::is_woocommerce_plugin_active()) { + $login_url = get_permalink(get_option('woocommerce_myaccount_page_id')); + } elseif ('1' == $aio_wp_security->configs->get_value('aiowps_enable_rename_login_page')) { //Check if rename login feature enabled. + if (get_option('permalink_structure')) { + $home_url = trailingslashit(home_url()); + } else { + $home_url = trailingslashit(home_url()) . '?'; + } + $login_url = $home_url.$aio_wp_security->configs->get_value('aiowps_login_page_slug'); + } else { + $login_url = wp_login_url(); + } + + //Inspect the payload and do redirect to login page with a msg and redirect url + $logout_payload = (is_multisite() ? get_site_transient('aiowps_logout_payload') : get_transient('aiowps_logout_payload')); + if (!empty($logout_payload['redirect_to'])) { + $login_url = AIOWPSecurity_Utility::add_query_data_to_url($login_url, 'redirect_to', $logout_payload['redirect_to']); + } + if (!empty($logout_payload['msg'])) { + $login_url .= '&'.$logout_payload['msg']; + } + if (!empty($login_url)) { + AIOWPSecurity_Utility::redirect_to_url($login_url); + } + } + } + } + + /** + * Check whether current admin page is Admin Dashboard page or not. + * + * @return boolean True if Admin Dashboard page, Otherwise false. + */ + public function is_admin_dashboard_page() { + if (isset($this->is_admin_dashboard_page)) { + return $this->is_admin_dashboard_page; + } + global $pagenow; + $this->is_admin_dashboard_page = 'index.php' == $pagenow; + return $this->is_admin_dashboard_page; + } + + /** + * Check whether current admin page is plugin page or not. + * + * @return boolean True if Admin Plugin page, Otherwise false. + */ + public function is_plugin_admin_page() { + if (isset($this->is_plugin_admin_page)) { + return $this->is_plugin_admin_page; + } + global $pagenow; + $this->is_plugin_admin_page = 'plugins.php' == $pagenow; + return $this->is_plugin_admin_page; + } + + /** + * Check whether current admin page is All-In-One Security admin page or not. + * + * @return boolean True if All-In-One Security admin page, Otherwise false. + */ + public function is_aiowps_admin_page() { + if (isset($this->is_aiowps_admin_page)) { + return $this->is_aiowps_admin_page; + } + global $pagenow; + $this->is_aiowps_admin_page = ('admin.php' == $pagenow && isset($_GET['page']) && false !== strpos($_GET['page'], AIOWPSEC_MENU_SLUG_PREFIX)); + return $this->is_aiowps_admin_page; + } + + /** + * Check whether current admin page is Google reCAPTCHA tab page or not. + * + * @return boolean True if Google reCAPTCHA tab page, Otherwise false. + */ + public function is_aiowps_google_recaptcha_tab_page() { + if (isset($this->is_aiowps_google_recaptcha_tab_page)) { + return $this->is_aiowps_google_recaptcha_tab_page; + } + global $pagenow; + $this->is_aiowps_google_recaptcha_tab_page = ('admin.php' == $pagenow + && isset($_GET['page']) + && 'aiowpsec_brute_force' == $_GET['page'] + && isset($_GET['tab']) + && 'captcha-settings' == $_GET['tab'] + ); + return $this->is_aiowps_google_recaptcha_tab_page; + } + + /** + * Set pagenow global variable to wp-login.php for renamed login page + * + * @return void + */ + public function set_pagenow_for_renamed_loginpage() { + global $pagenow; + if ('1' == $this->configs->get_value('aiowps_enable_rename_login_page')) { + include_once(AIO_WP_SECURITY_PATH . '/classes/wp-security-process-renamed-login-page.php'); + $login_slug = $this->configs->get_value('aiowps_login_page_slug'); + if (AIOWPSecurity_Process_Renamed_Login_Page::is_renamed_login_page_requested($login_slug)) { + //wp-login.php pagenow variable required in determine_locale method for language change to work by login page dropdown + $pagenow = 'wp-login.php'; + } + } + } + + /** + * Invokes all functions attached to action hook aiowps_force_logout_check + * + * @return void + */ + public function do_action_force_logout_check() { + do_action('aiowps_force_logout_check'); + } + + /** + * Check AIOS_DISABLE_LOGIN_LOCKOUT constant value + * + * @return boolean True if the AIOS_DISABLE_LOGIN_LOCKOUT constant defined with true value, otherwise false. + */ + public function is_login_lockdown_by_const() { + return defined('AIOS_DISABLE_LOGIN_LOCKOUT') && AIOS_DISABLE_LOGIN_LOCKOUT; + } + + /** + * Instantiate Ajax handling class + */ + private function load_ajax_handler() { + include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-ajax.php'); + AIOWPSecurity_Ajax::get_instance(); + } + + /** + * Append salt postfixes. + * + * @param string $salt Salt + * @param string $scheme Authentication scheme. Values include 'auth', 'secure_auth', 'logged_in', and 'nonce'. + * @return new salt + */ + public function salt($salt, $scheme) { + $salt_postfixes = $this->configs->get_site_value('aiowps_salt_postfixes'); + if (!isset($salt_postfixes[$scheme])) { + AIOWPSecurity_Utility::change_salt_postfixes(); + $salt_postfixes = $this->configs->get_site_value('aiowps_salt_postfixes'); + } + + if (empty($salt_postfixes[$scheme])) { + return $salt; + } + + return $salt.$salt_postfixes[$scheme]; + } + + } // End of class + +}//End of class not exists check + +$GLOBALS['aio_wp_security'] = new AIO_WP_Security(); diff --git a/wp-content/plugins/all-in-one-wp-security-and-firewall/wp-security.php b/wp-content/plugins/all-in-one-wp-security-and-firewall/wp-security.php new file mode 100755 index 00000000..6d3d7e4e --- /dev/null +++ b/wp-content/plugins/all-in-one-wp-security-and-firewall/wp-security.php @@ -0,0 +1,87 @@ + +
            +

            +

            + +

            5.6+'); ?>

            + +

            '.phpversion().''); ?>

            +

            +
            + ' . __('Settings', 'all-in-one-wp-security-and-firewall') . ''; + array_unshift($links, $settings_link); + } + return $links; +} +add_filter('plugin_action_links', 'aiowps_show_plugin_settings_link', 10, 2); + +function aiowps_ms_handle_new_site($new_site) { + global $wpdb; + $plugin_basename = plugin_basename(__FILE__); + if (is_plugin_active_for_network($plugin_basename)) { + if (!class_exists('AIOWPSecurity_Installer')) { + include_once('classes/wp-security-installer.php'); + } + $old_blog = $wpdb->blogid; + switch_to_blog($new_site->blog_id); + AIOWPSecurity_Installer::create_db_tables(); + switch_to_blog($old_blog); + } + + +} +// The priority is 20 instead of 10 because all subsite's tables are created by `add_action( 'wp_initialize_site', 'wp_initialize_site', 10, 2 );`. We should call the `aiowps_ms_handle_new_site` function after all subsite's tables are created because the `aiowps_ms_handle_new_site` function adds option in subsite's table. +add_action('wp_initialize_site', 'aiowps_ms_handle_new_site', 20, 1);