Changeset 3450292
- Timestamp:
- 01/30/2026 09:40:47 AM (2 months ago)
- Location:
- nhrrob-secure
- Files:
-
- 10 added
- 26 edited
- 1 copied
-
tags/1.3.0 (copied) (copied from nhrrob-secure/trunk)
-
tags/1.3.0/assets/src/components/Hardening.js (modified) (1 diff)
-
tags/1.3.0/assets/src/components/HealthCheck.js (added)
-
tags/1.3.0/assets/src/components/IPManager.js (added)
-
tags/1.3.0/assets/src/components/SessionManager.js (modified) (1 diff)
-
tags/1.3.0/assets/src/index.js (modified) (2 diffs)
-
tags/1.3.0/assets/src/style.css (modified) (5 diffs)
-
tags/1.3.0/build/admin.asset.php (modified) (1 diff)
-
tags/1.3.0/build/admin.css (modified) (21 diffs)
-
tags/1.3.0/build/admin.js (modified) (1 diff)
-
tags/1.3.0/build/profile.asset.php (modified) (1 diff)
-
tags/1.3.0/build/profile.css (modified) (17 diffs)
-
tags/1.3.0/includes/Admin/Api.php (modified) (4 diffs)
-
tags/1.3.0/includes/Firewall.php (added)
-
tags/1.3.0/includes/HealthCheck.php (added)
-
tags/1.3.0/includes/IPManager.php (added)
-
tags/1.3.0/includes/TwoFactor.php (modified) (2 diffs)
-
tags/1.3.0/nhrrob-secure.php (modified) (3 diffs)
-
tags/1.3.0/readme.txt (modified) (4 diffs)
-
trunk/assets/src/components/Hardening.js (modified) (1 diff)
-
trunk/assets/src/components/HealthCheck.js (added)
-
trunk/assets/src/components/IPManager.js (added)
-
trunk/assets/src/components/SessionManager.js (modified) (1 diff)
-
trunk/assets/src/index.js (modified) (2 diffs)
-
trunk/assets/src/style.css (modified) (5 diffs)
-
trunk/build/admin.asset.php (modified) (1 diff)
-
trunk/build/admin.css (modified) (21 diffs)
-
trunk/build/admin.js (modified) (1 diff)
-
trunk/build/profile.asset.php (modified) (1 diff)
-
trunk/build/profile.css (modified) (17 diffs)
-
trunk/includes/Admin/Api.php (modified) (4 diffs)
-
trunk/includes/Firewall.php (added)
-
trunk/includes/HealthCheck.php (added)
-
trunk/includes/IPManager.php (added)
-
trunk/includes/TwoFactor.php (modified) (2 diffs)
-
trunk/nhrrob-secure.php (modified) (3 diffs)
-
trunk/readme.txt (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
nhrrob-secure/tags/1.3.0/assets/src/components/Hardening.js
r3441244 r3450292 43 43 <h3 className="nhrrob-secure-setting-subtitle">{__('Firewall Rules', 'nhrrob-secure')}</h3> 44 44 45 <ToggleControl 46 label={__('Advanced Firewall (IPS) Protection', 'nhrrob-secure')} 47 help={__('Proactively block common attacks like SQL Injection, XSS, and LFI by scanning request data.', 'nhrrob-secure')} 48 checked={settings?.nhrrob_secure_enable_advanced_firewall || false} 49 onChange={(value) => updateSetting('nhrrob_secure_enable_advanced_firewall', value)} 50 /> 51 45 52 <TextareaControl 46 53 label={__('Block User Agents', 'nhrrob-secure')} -
nhrrob-secure/tags/1.3.0/assets/src/components/SessionManager.js
r3441244 r3450292 133 133 isDestructive 134 134 onClick={destroyOtherSessions} 135 className=" w-full justify-center"135 className="justify-center h-auto py-2 text-xs" 136 136 > 137 137 {__('Log Out All Other Devices', 'nhrrob-secure')} -
nhrrob-secure/tags/1.3.0/assets/src/index.js
r3441244 r3450292 16 16 import SessionManager from './components/SessionManager'; 17 17 import AuditLog from './components/AuditLog'; 18 import HealthCheck from './components/HealthCheck'; 19 import IPManager from './components/IPManager'; 18 20 import './style.css'; 19 21 … … 124 126 125 127 <div className="nhrrob-secure-cards"> 126 <LoginProtection settings={settings} updateSetting={updateSetting} /> 127 <CustomLoginPage settings={settings} updateSetting={updateSetting} /> 128 <TwoFactorAuth settings={settings} updateSetting={updateSetting} /> 129 <Hardening settings={settings} updateSetting={updateSetting} /> 130 <FileProtection settings={settings} updateSetting={updateSetting} /> 131 <VulnerabilityChecker /> 132 <FileScanner /> 133 <SessionManager settings={settings} updateSetting={updateSetting} /> 134 <AuditLog settings={settings} updateSetting={updateSetting} /> 128 <div className="md:col-span-2 lg:col-span-3"> 129 <HealthCheck onApplyOneClick={(newSettings) => setSettings(newSettings)} /> 130 </div> 131 <div className="md:col-span-2 lg:col-span-3"> 132 <LoginProtection settings={settings} updateSetting={updateSetting} /> 133 </div> 134 <div className="md:col-span-2 lg:col-span-3"> 135 <CustomLoginPage settings={settings} updateSetting={updateSetting} /> 136 </div> 137 <div className="md:col-span-2 lg:col-span-3"> 138 <TwoFactorAuth settings={settings} updateSetting={updateSetting} /> 139 </div> 140 <div className="md:col-span-2 lg:col-span-3"> 141 <Hardening settings={settings} updateSetting={updateSetting} /> 142 </div> 143 <div className="md:col-span-2 lg:col-span-3"> 144 <FileProtection settings={settings} updateSetting={updateSetting} /> 145 </div> 146 <div className="md:col-span-2 lg:col-span-3"> 147 <VulnerabilityChecker /> 148 </div> 149 <div className="md:col-span-2 lg:col-span-3"> 150 <IPManager settings={settings} updateSetting={updateSetting} /> 151 </div> 152 <div className="md:col-span-2 lg:col-span-3"> 153 <FileScanner /> 154 </div> 155 <div className="md:col-span-2 lg:col-span-3"> 156 <SessionManager settings={settings} updateSetting={updateSetting} /> 157 </div> 158 <div className="md:col-span-2 lg:col-span-3"> 159 <AuditLog settings={settings} updateSetting={updateSetting} /> 160 </div> 135 161 </div> 136 162 -
nhrrob-secure/tags/1.3.0/assets/src/style.css
r3441244 r3450292 83 83 84 84 .nhrrob-secure-cards { 85 @apply grid g ap-5 mb-6;85 @apply grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5 mb-6; 86 86 } 87 87 … … 124 124 .dark-mode .components-placeholder__instructions, 125 125 .dark-mode .nhrrob-secure-2fa-method h3, 126 .dark-mode .nhrrob-secure-enforced-roles h3 { 126 .dark-mode .nhrrob-secure-enforced-roles h3, 127 .dark-mode .nhrrob-secure-ip-card h3, 128 .dark-mode .nhrrob-secure-ip-card .components-base-control__label, 129 .dark-mode .nhrrob-secure-country-select label { 127 130 color: var(--nhrrob-secure-text) !important; 128 131 } 129 132 133 . 130 134 .dark-mode .components-placeholder { 131 135 background-color: var(--nhrrob-secure-vuln-bg) !important; … … 135 139 136 140 .dark-mode .components-text-control__input, 137 .dark-mode .components-textarea-control__input { 141 .dark-mode .components-textarea-control__input, 142 .dark-mode .components-select-control__input { 143 background-color: #2c3338 !important; 144 border-color: #43494e !important; 145 color: #f0f0f1 !important; 146 } 147 148 /* IP Manager SelectControl specific styling */ 149 .dark-mode .nhrrob-secure-ip-card .components-select-control__input { 138 150 background-color: #2c3338 !important; 139 151 border-color: #43494e !important; … … 265 277 266 278 .nhrrob-scan-controls { 267 @apply flex items-center gap-4; 279 @apply flex items-center gap-4 shrink-0; 280 } 281 282 .nhrrob-scan-controls .components-button { 283 @apply flex items-center justify-center gap-2 px-4 py-2 h-auto !important; 284 } 285 286 .nhrrob-scan-controls .components-button .dashicon { 287 @apply static m-0 !important; 268 288 } 269 289 … … 332 352 333 353 .nhrrob-result-list { 334 @apply divide-y ;354 @apply divide-y overflow-y-auto max-h-[400px]; 335 355 } 336 356 -
nhrrob-secure/tags/1.3.0/build/admin.asset.php
r3441244 r3450292 1 <?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-components', 'wp-element', 'wp-html-entities', 'wp-i18n'), 'version' => ' 876f03e1a6accd816f8d');1 <?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-components', 'wp-element', 'wp-html-entities', 'wp-i18n'), 'version' => 'd12ca91feb6f2445566e'); -
nhrrob-secure/tags/1.3.0/build/admin.css
r3441244 r3450292 116 116 margin-bottom: 1.5rem; 117 117 display: grid; 118 grid-template-columns: repeat(1, minmax(0, 1fr)); 118 119 gap: 1.25rem; 120 } 121 122 @media (min-width: 768px) { 123 124 .nhrrob-secure-cards { 125 grid-template-columns: repeat(2, minmax(0, 1fr)); 126 } 127 } 128 129 @media (min-width: 1024px) { 130 131 .nhrrob-secure-cards { 132 grid-template-columns: repeat(3, minmax(0, 1fr)); 133 } 119 134 } 120 135 … … 177 192 .dark-mode .components-placeholder__instructions, 178 193 .dark-mode .nhrrob-secure-2fa-method h3, 179 .dark-mode .nhrrob-secure-enforced-roles h3 { 194 .dark-mode .nhrrob-secure-enforced-roles h3, 195 .dark-mode .nhrrob-secure-ip-card h3, 196 .dark-mode .nhrrob-secure-ip-card .components-base-control__label, 197 .dark-mode .nhrrob-secure-country-select label { 180 198 color: var(--nhrrob-secure-text) !important; 181 199 } 182 200 201 . 183 202 .dark-mode .components-placeholder { 184 203 background-color: var(--nhrrob-secure-vuln-bg) !important; … … 188 207 189 208 .dark-mode .components-text-control__input, 190 .dark-mode .components-textarea-control__input { 209 .dark-mode .components-textarea-control__input, 210 .dark-mode .components-select-control__input { 211 background-color: #2c3338 !important; 212 border-color: #43494e !important; 213 color: #f0f0f1 !important; 214 } 215 216 /* IP Manager SelectControl specific styling */ 217 .dark-mode .nhrrob-secure-ip-card .components-select-control__input { 191 218 background-color: #2c3338 !important; 192 219 border-color: #43494e !important; … … 371 398 .nhrrob-scan-controls { 372 399 display: flex; 400 flex-shrink: 0; 373 401 align-items: center; 374 402 gap: 1rem; 403 } 404 405 .nhrrob-scan-controls .components-button { 406 display: flex !important; 407 height: auto !important; 408 align-items: center !important; 409 justify-content: center !important; 410 gap: 0.5rem !important; 411 padding-left: 1rem !important; 412 padding-right: 1rem !important; 413 padding-top: 0.5rem !important; 414 padding-bottom: 0.5rem !important; 415 } 416 417 .nhrrob-scan-controls .components-button .dashicon { 418 position: static !important; 419 margin: 0px !important; 375 420 } 376 421 … … 518 563 } 519 564 565 .nhrrob-result-list { 566 max-height: 400px; 567 } 568 520 569 .nhrrob-result-list > :not([hidden]) ~ :not([hidden]) { 521 570 --tw-divide-y-reverse: 0; 522 571 border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse))); 523 572 border-bottom-width: calc(1px * var(--tw-divide-y-reverse)); 573 } 574 575 .nhrrob-result-list { 576 overflow-y: auto; 524 577 } 525 578 … … 605 658 border-color: var(--nhrrob-secure-border); 606 659 } 660 .absolute { 661 position: absolute; 662 } 663 .relative { 664 position: relative; 665 } 666 .-mr-0\.5 { 667 margin-right: -0.125rem; 668 } 607 669 .mb-2 { 608 670 margin-bottom: 0.5rem; … … 614 676 margin-bottom: 1rem; 615 677 } 678 .mb-6 { 679 margin-bottom: 1.5rem; 680 } 616 681 .ml-2 { 617 682 margin-left: 0.5rem; … … 623 688 margin-top: 0px; 624 689 } 690 .mt-0\.5 { 691 margin-top: 0.125rem; 692 } 625 693 .mt-1 { 626 694 margin-top: 0.25rem; … … 629 697 margin-top: 1rem; 630 698 } 699 .mt-8 { 700 margin-top: 2rem; 701 } 631 702 .block { 632 703 display: block; … … 644 715 display: none; 645 716 } 717 .h-32 { 718 height: 8rem; 719 } 720 .h-auto { 721 height: auto; 722 } 723 .h-full { 724 height: 100%; 725 } 726 .w-32 { 727 width: 8rem; 728 } 646 729 .w-64 { 647 730 width: 16rem; … … 650 733 width: 100%; 651 734 } 735 .max-w-xs { 736 max-width: 20rem; 737 } 738 .flex-1 { 739 flex: 1 1 0%; 740 } 741 .-rotate-90 { 742 --tw-rotate: -90deg; 743 transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); 744 } 745 .transform { 746 transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); 747 } 748 .cursor-pointer { 749 cursor: pointer; 750 } 751 .grid-cols-1 { 752 grid-template-columns: repeat(1, minmax(0, 1fr)); 753 } 652 754 .grid-cols-2 { 653 755 grid-template-columns: repeat(2, minmax(0, 1fr)); 654 756 } 757 .flex-col { 758 flex-direction: column; 759 } 760 .flex-wrap { 761 flex-wrap: wrap; 762 } 655 763 .items-start { 656 764 align-items: flex-start; 657 765 } 766 .items-end { 767 align-items: flex-end; 768 } 769 .items-center { 770 align-items: center; 771 } 658 772 .justify-center { 659 773 justify-content: center; … … 662 776 justify-content: space-between; 663 777 } 778 .gap-1 { 779 gap: 0.25rem; 780 } 664 781 .gap-2 { 665 782 gap: 0.5rem; 783 } 784 .gap-3 { 785 gap: 0.75rem; 786 } 787 .gap-4 { 788 gap: 1rem; 789 } 790 .gap-6 { 791 gap: 1.5rem; 792 } 793 .gap-8 { 794 gap: 2rem; 666 795 } 667 796 .truncate { … … 676 805 border-radius: 9999px; 677 806 } 807 .rounded-lg { 808 border-radius: 0.5rem; 809 } 678 810 .border { 679 811 border-width: 1px; 680 812 } 813 .border-0 { 814 border-width: 0px; 815 } 816 .border-b { 817 border-bottom-width: 1px; 818 } 681 819 .border-t { 682 820 border-top-width: 1px; 821 } 822 .border-none { 823 border-style: none; 683 824 } 684 825 .border-blue-200 { … … 694 835 border-color: rgb(229 231 235 / var(--tw-border-opacity, 1)); 695 836 } 837 .border-red-200 { 838 --tw-border-opacity: 1; 839 border-color: rgb(254 202 202 / var(--tw-border-opacity, 1)); 840 } 696 841 .bg-blue-100 { 697 842 --tw-bg-opacity: 1; … … 705 850 --tw-bg-opacity: 1; 706 851 background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1)); 852 } 853 .bg-green-100 { 854 --tw-bg-opacity: 1; 855 background-color: rgb(220 252 231 / var(--tw-bg-opacity, 1)); 856 } 857 .bg-red-100 { 858 --tw-bg-opacity: 1; 859 background-color: rgb(254 226 226 / var(--tw-bg-opacity, 1)); 860 } 861 .bg-red-50 { 862 --tw-bg-opacity: 1; 863 background-color: rgb(254 242 242 / var(--tw-bg-opacity, 1)); 864 } 865 .bg-yellow-100 { 866 --tw-bg-opacity: 1; 867 background-color: rgb(254 249 195 / var(--tw-bg-opacity, 1)); 868 } 869 .p-0\.5 { 870 padding: 0.125rem; 707 871 } 708 872 .p-3 { 709 873 padding: 0.75rem; 874 } 875 .p-5 { 876 padding: 1.25rem; 877 } 878 .p-6 { 879 padding: 1.5rem; 710 880 } 711 881 .px-2 { … … 713 883 padding-right: 0.5rem; 714 884 } 885 .px-3 { 886 padding-left: 0.75rem; 887 padding-right: 0.75rem; 888 } 715 889 .py-0\.5 { 716 890 padding-top: 0.125rem; 717 891 padding-bottom: 0.125rem; 718 892 } 893 .py-1 { 894 padding-top: 0.25rem; 895 padding-bottom: 0.25rem; 896 } 897 .py-1\.5 { 898 padding-top: 0.375rem; 899 padding-bottom: 0.375rem; 900 } 901 .py-2 { 902 padding-top: 0.5rem; 903 padding-bottom: 0.5rem; 904 } 905 .pb-0 { 906 padding-bottom: 0px; 907 } 719 908 .pt-3 { 720 909 padding-top: 0.75rem; … … 725 914 .font-mono { 726 915 font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 916 } 917 .text-2xl { 918 font-size: 1.5rem; 919 line-height: 2rem; 920 } 921 .text-3xl { 922 font-size: 1.875rem; 923 line-height: 2.25rem; 924 } 925 .text-\[10px\] { 926 font-size: 10px; 727 927 } 728 928 .text-sm { … … 734 934 line-height: 1rem; 735 935 } 936 .font-bold { 937 font-weight: 700; 938 } 736 939 .font-medium { 737 940 font-weight: 500; … … 740 943 font-weight: 600; 741 944 } 945 .uppercase { 946 text-transform: uppercase; 947 } 948 .italic { 949 font-style: italic; 950 } 951 .leading-none { 952 line-height: 1; 953 } 954 .tracking-wider { 955 letter-spacing: 0.05em; 956 } 742 957 .text-blue-800 { 743 958 --tw-text-opacity: 1; 744 959 color: rgb(30 64 175 / var(--tw-text-opacity, 1)); 745 960 } 961 .text-gray-100 { 962 --tw-text-opacity: 1; 963 color: rgb(243 244 246 / var(--tw-text-opacity, 1)); 964 } 746 965 .text-gray-400 { 747 966 --tw-text-opacity: 1; … … 755 974 --tw-text-opacity: 1; 756 975 color: rgb(55 65 81 / var(--tw-text-opacity, 1)); 976 } 977 .text-gray-900 { 978 --tw-text-opacity: 1; 979 color: rgb(17 24 39 / var(--tw-text-opacity, 1)); 980 } 981 .text-green-500 { 982 --tw-text-opacity: 1; 983 color: rgb(34 197 94 / var(--tw-text-opacity, 1)); 984 } 985 .text-green-600 { 986 --tw-text-opacity: 1; 987 color: rgb(22 163 74 / var(--tw-text-opacity, 1)); 988 } 989 .text-green-700 { 990 --tw-text-opacity: 1; 991 color: rgb(21 128 61 / var(--tw-text-opacity, 1)); 992 } 993 .text-red-400 { 994 --tw-text-opacity: 1; 995 color: rgb(248 113 113 / var(--tw-text-opacity, 1)); 996 } 997 .text-red-500 { 998 --tw-text-opacity: 1; 999 color: rgb(239 68 68 / var(--tw-text-opacity, 1)); 1000 } 1001 .text-red-600 { 1002 --tw-text-opacity: 1; 1003 color: rgb(220 38 38 / var(--tw-text-opacity, 1)); 1004 } 1005 .text-red-700 { 1006 --tw-text-opacity: 1; 1007 color: rgb(185 28 28 / var(--tw-text-opacity, 1)); 1008 } 1009 .text-yellow-500 { 1010 --tw-text-opacity: 1; 1011 color: rgb(234 179 8 / var(--tw-text-opacity, 1)); 1012 } 1013 .text-yellow-700 { 1014 --tw-text-opacity: 1; 1015 color: rgb(161 98 7 / var(--tw-text-opacity, 1)); 1016 } 1017 .opacity-60 { 1018 opacity: 0.6; 757 1019 } 758 1020 .filter { 759 1021 filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); 1022 } 1023 .transition-all { 1024 transition-property: all; 1025 transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); 1026 transition-duration: 150ms; 1027 } 1028 .transition-colors { 1029 transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; 1030 transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); 1031 transition-duration: 150ms; 1032 } 1033 .duration-1000 { 1034 transition-duration: 1000ms; 1035 } 1036 .ease-out { 1037 transition-timing-function: cubic-bezier(0, 0, 0.2, 1); 760 1038 } 761 1039 … … 923 1201 border-left-color: rgb(220 38 38 / var(--tw-border-opacity, 1)); 924 1202 } 1203 1204 @media (prefers-color-scheme: dark) { 1205 1206 .dark-mode .session-item .dark\:text-gray-500 { 1207 color: var(--nhrrob-secure-text-muted) !important; 1208 } 1209 } 1210 1211 .hover\:bg-blue-600:hover { 1212 --tw-bg-opacity: 1; 1213 background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1)); 1214 } 1215 1216 .hover\:text-white:hover { 1217 --tw-text-opacity: 1; 1218 color: rgb(255 255 255 / var(--tw-text-opacity, 1)); 1219 } 1220 1221 .focus\:outline-none:focus { 1222 outline: 2px solid transparent; 1223 outline-offset: 2px; 1224 } 1225 1226 @media (min-width: 640px) { 1227 1228 .sm\:grid-cols-2 { 1229 grid-template-columns: repeat(2, minmax(0, 1fr)); 1230 } 1231 } 1232 1233 @media (min-width: 768px) { 1234 1235 .md\:col-span-2 { 1236 grid-column: span 2 / span 2; 1237 } 1238 1239 .md\:grid-cols-2 { 1240 grid-template-columns: repeat(2, minmax(0, 1fr)); 1241 } 1242 1243 .md\:flex-row { 1244 flex-direction: row; 1245 } 1246 } 1247 1248 @media (min-width: 1024px) { 1249 1250 .lg\:col-span-3 { 1251 grid-column: span 3 / span 3; 1252 } 1253 } 1254 1255 @media (prefers-color-scheme: dark) { 1256 1257 .dark\:border-gray-700 { 1258 --tw-border-opacity: 1; 1259 border-color: rgb(55 65 81 / var(--tw-border-opacity, 1)); 1260 } 1261 1262 .dark\:border-gray-800 { 1263 --tw-border-opacity: 1; 1264 border-color: rgb(31 41 55 / var(--tw-border-opacity, 1)); 1265 } 1266 1267 .dark\:border-red-800\/50 { 1268 border-color: rgb(153 27 27 / 0.5); 1269 } 1270 1271 .dark\:bg-red-900\/20 { 1272 background-color: rgb(127 29 29 / 0.2); 1273 } 1274 1275 .dark\:text-gray-100 { 1276 --tw-text-opacity: 1; 1277 color: rgb(243 244 246 / var(--tw-text-opacity, 1)); 1278 } 1279 1280 .dark\:text-gray-300 { 1281 --tw-text-opacity: 1; 1282 color: rgb(209 213 219 / var(--tw-text-opacity, 1)); 1283 } 1284 1285 .dark\:text-gray-400 { 1286 --tw-text-opacity: 1; 1287 color: rgb(156 163 175 / var(--tw-text-opacity, 1)); 1288 } 1289 1290 .dark\:text-gray-500 { 1291 --tw-text-opacity: 1; 1292 color: rgb(107 114 128 / var(--tw-text-opacity, 1)); 1293 } 1294 1295 .dark\:text-gray-800 { 1296 --tw-text-opacity: 1; 1297 color: rgb(31 41 55 / var(--tw-text-opacity, 1)); 1298 } 1299 1300 .dark\:text-green-400 { 1301 --tw-text-opacity: 1; 1302 color: rgb(74 222 128 / var(--tw-text-opacity, 1)); 1303 } 1304 1305 .dark\:text-red-400 { 1306 --tw-text-opacity: 1; 1307 color: rgb(248 113 113 / var(--tw-text-opacity, 1)); 1308 } 1309 } -
nhrrob-secure/tags/1.3.0/build/admin.js
r3441244 r3450292 1 (()=>{"use strict";var e,r={ 195(e,r,t){const n=window.React,s=window.wp.element,a=window.wp.components,l=window.wp.i18n,c=window.wp.apiFetch;var o=t.n(c);const i=({settings:e,updateSetting:r})=>(0,n.createElement)(a.Card,{className:"nhrrob-secure-card"},(0,n.createElement)(a.CardBody,null,(0,n.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,l.__)("Login Protection","nhrrob-secure")),(0,n.createElement)(a.ToggleControl,{label:(0,l.__)("Enable Login Attempts Limit","nhrrob-secure"),help:(0,l.__)("Limit failed login attempts to prevent brute force attacks","nhrrob-secure"),checked:e.nhrrob_secure_limit_login_attempts,onChange:e=>r("nhrrob_secure_limit_login_attempts",e)}),e.nhrrob_secure_limit_login_attempts&&(0,n.createElement)(a.TextControl,{label:(0,l.__)("Maximum Login Attempts","nhrrob-secure"),help:(0,l.__)("Number of failed attempts before blocking (default: 5)","nhrrob-secure"),type:"number",value:e.nhrrob_secure_login_attempts_limit,onChange:e=>r("nhrrob_secure_login_attempts_limit",parseInt(e)||5),min:"1",max:"20"}),(0,n.createElement)(a.ToggleControl,{label:(0,l.__)("Enable Proxy IP Detection","nhrrob-secure"),help:(0,l.__)("Detect real IP behind proxies (Cloudflare, etc.)","nhrrob-secure"),checked:e.nhrrob_secure_enable_proxy_ip,onChange:e=>r("nhrrob_secure_enable_proxy_ip",e)}))),u=({settings:e,updateSetting:r})=>(0,n.createElement)(a.Card,{className:"nhrrob-secure-card"},(0,n.createElement)(a.CardBody,null,(0,n.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,l.__)("Custom Login Page","nhrrob-secure")),(0,n.createElement)(a.ToggleControl,{label:(0,l.__)("Enable Custom Login URL","nhrrob-secure"),help:(0,l.__)("Hide wp-login.php and use a custom login URL","nhrrob-secure"),checked:e.nhrrob_secure_custom_login_page,onChange:e=>r("nhrrob_secure_custom_login_page",e)}),e.nhrrob_secure_custom_login_page&&(0,n.createElement)(a.TextControl,{label:(0,l.__)("Custom Login URL","nhrrob-secure"),help:(0,l.__)("Your login page will be accessible at this URL","nhrrob-secure"),value:e.nhrrob_secure_custom_login_url,onChange:e=>r("nhrrob_secure_custom_login_url",e),placeholder:"/hidden-access-52w"}),e.nhrrob_secure_custom_login_page&&(0,n.createElement)("div",{className:"nhrrob-secure-info"},(0,n.createElement)("strong",null,(0,l.__)("Your login URL:","nhrrob-secure")),(0,n.createElement)("code",null,window.location.origin,e.nhrrob_secure_custom_login_url)))),m=({settings:e,updateSetting:r})=>{const t=e.nhrrob_secure_2fa_enforced_roles||[],s=e.available_roles||[];return(0,n.createElement)(a.Card,{className:"nhrrob-secure-card"},(0,n.createElement)(a.CardBody,null,(0,n.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,l.__)("Two-Factor Authentication","nhrrob-secure")),(0,n.createElement)(a.ToggleControl,{label:(0,l.__)("Enable Global 2FA","nhrrob-secure"),help:(0,n.createElement)(n.Fragment,null,(0,l.__)("Enables Google Authenticator support for all users. Users can set it up in their ","nhrrob-secure"),(0,n.createElement)("a",{href:nhrrobSecureSettings.profile_url,target:"_blank",rel:"noreferrer"},(0,l.__)("profile page","nhrrob-secure")),"."),checked:e.nhrrob_secure_enable_2fa,onChange:e=>r("nhrrob_secure_enable_2fa",e)}),e.nhrrob_secure_enable_2fa&&(0,n.createElement)(n.Fragment,null,(0,n.createElement)("div",{className:"nhrrob-secure-2fa-method pt-4 border-t border-gray-100"},(0,n.createElement)("h3",{className:"text-sm font-semibold mb-3"},(0,l.__)("2FA Method","nhrrob-secure")),(0,n.createElement)(a.RadioControl,{selected:e.nhrrob_secure_2fa_type||"app",options:[{label:(0,l.__)("Authenticator App (Recommended)","nhrrob-secure"),value:"app"},{label:(0,l.__)("Email OTP","nhrrob-secure"),value:"email"}],onChange:e=>r("nhrrob_secure_2fa_type",e)})),(0,n.createElement)("div",{className:"nhrrob-secure-enforced-roles pt-4 border-t border-gray-100"},(0,n.createElement)("h3",{className:"text-sm font-semibold mb-3"},(0,l.__)("Enforced 2FA by Role","nhrrob-secure")),(0,n.createElement)("p",{className:"text-xs text-gray-500 mb-4"},(0,l.__)("Users with the selected roles will be forced to set up 2FA before they can access the admin dashboard.","nhrrob-secure")),(0,n.createElement)("div",{className:"grid grid-cols-2 gap-2"},s.map(e=>(0,n.createElement)(a.CheckboxControl,{key:e.value,label:e.label,checked:t.includes(e.value),onChange:n=>((e,n)=>{const s=n?[...t,e]:t.filter(r=>r!==e);r("nhrrob_secure_2fa_enforced_roles",s)})(e.value,n)})))))))},h=({settings:e,updateSetting:r})=>(0,n.createElement)(a.Card,{className:"nhrrob-secure-card"},(0,n.createElement)(a.CardBody,null,(0,n.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,l.__)("File Protection","nhrrob-secure")),(0,n.createElement)(a.ToggleControl,{label:(0,l.__)("Protect Debug Log","nhrrob-secure"),help:(0,l.__)("Block direct access to wp-content/debug.log","nhrrob-secure"),checked:e.nhrrob_secure_protect_debug_log,onChange:e=>r("nhrrob_secure_protect_debug_log",e)}))),d=window.wp.htmlEntities,b=()=>{const[e,r]=(0,s.useState)(null),[t,c]=(0,s.useState)(!0),[i,u]=(0,s.useState)(!1),[m,h]=(0,s.useState)(null);(0,s.useEffect)(()=>{b()},[]);const b=async()=>{try{const e=await o()({path:"/nhrrob-secure/v1/vulnerability/status"});r(e),c(!1)}catch(e){h((0,l.__)("Failed to fetch vulnerability status","nhrrob-secure")),c(!1)}};if(t)return(0,n.createElement)(a.Card,{className:"nhrrob-secure-card"},(0,n.createElement)(a.CardBody,null,(0,n.createElement)(a.Spinner,null)));const _=e&&(e.core.length>0||e.plugins.length>0||e.themes.length>0);return(0,n.createElement)(a.Card,{className:"nhrrob-secure-card nhrrob-secure-vulnerability-card"},(0,n.createElement)(a.CardBody,null,(0,n.createElement)("div",{className:"nhrrob-secure-card-header-flex"},(0,n.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,l.__)("Vulnerability Checker","nhrrob-secure")),(0,n.createElement)(a.Button,{variant:"primary",onClick:async()=>{u(!0),h(null);try{const e=await o()({path:"/nhrrob-secure/v1/vulnerability/scan",method:"POST"});r(e)}catch(e){h((0,l.__)("Failed to run vulnerability scan","nhrrob-secure"))}finally{u(!1)}},isBusy:i,disabled:i,icon:"update",iconPosition:"right"},i?(0,l.__)("Scanning...","nhrrob-secure"):(0,l.__)("Scan Now","nhrrob-secure"))),(0,n.createElement)("p",{className:"nhrrob-secure-last-scan"},(0,n.createElement)("strong",null,(0,l.__)("Last Scan:","nhrrob-secure"))," ",(g=e.last_scan)?new Date(1e3*g).toLocaleString():(0,l.__)("Never","nhrrob-secure")),m&&(0,n.createElement)(a.Notice,{status:"error",isDismissible:!1},m),_?(0,n.createElement)("div",{className:"nhrrob-secure-vulnerability-list"},(0,n.createElement)(a.Notice,{status:"warning",isDismissible:!1},(0,l.__)("Vulnerabilities detected! Please review and update the items below.","nhrrob-secure")),e.core.length>0&&(0,n.createElement)("div",{className:"vulnerability-section"},(0,n.createElement)("h3",null,(0,l.__)("WordPress Core","nhrrob-secure")),(0,n.createElement)("ul",null,e.core.map((e,r)=>(0,n.createElement)("li",{key:r},(0,d.decodeEntities)(e.name))))),e.plugins.length>0&&(0,n.createElement)("div",{className:"vulnerability-section"},(0,n.createElement)("h3",null,(0,l.__)("Plugins","nhrrob-secure")),e.plugins.map((e,r)=>(0,n.createElement)("div",{key:r,className:"vulnerability-item"},(0,n.createElement)("strong",null,(0,n.createElement)("a",{href:"plugins.php",style:{textDecoration:"none",color:"inherit"}},(0,d.decodeEntities)(e.name)),(0,n.createElement)("span",{style:{fontWeight:"normal",color:"#666"}}," (",e.version,")")),(0,n.createElement)("ul",null,e.vulnerabilities.map((e,r)=>(0,n.createElement)("li",{key:r},(0,d.decodeEntities)(e.name))))))),e.themes.length>0&&(0,n.createElement)("div",{className:"vulnerability-section"},(0,n.createElement)("h3",null,(0,l.__)("Themes","nhrrob-secure")),e.themes.map((e,r)=>(0,n.createElement)("div",{key:r,className:"vulnerability-item"},(0,n.createElement)("strong",null,(0,d.decodeEntities)(e.name)," (",e.version,")"),(0,n.createElement)("ul",null,e.vulnerabilities.map((e,r)=>(0,n.createElement)("li",{key:r},(0,d.decodeEntities)(e.name)))))))):(0,n.createElement)("div",{className:"nhrrob-secure-status-success"},(0,n.createElement)("span",{className:"dashicons dashicons-yes-alt"}),(0,l.__)("No known vulnerabilities detected.","nhrrob-secure"))));var g},_=()=>{const[e,r]=(0,s.useState)(!1),[t,c]=(0,s.useState)(null),[i,u]=(0,s.useState)(null),[m,h]=(0,s.useState)("core"),d=async()=>{r(!0),u(null),c(null);try{const e="core"===m?"/nhrrob-secure/v1/scanner/core":"/nhrrob-secure/v1/scanner/malware",r=await o()({path:e,method:"POST"});c(r)}catch(e){u(e.message||(0,l.__)("An error occurred during scan.","nhrrob-secure"))}finally{r(!1)}};return(0,n.createElement)("div",{className:"nhrrob-secure-card nhrrob-secure-vulnerability-card padded-header"},(0,n.createElement)("div",{className:"nhrrob-secure-card-header-flex"},(0,n.createElement)("div",{className:"nhrrob-secure-header-content"},(0,n.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,l.__)("File Scanner","nhrrob-secure")),(0,n.createElement)("p",{className:"nhrrob-secure-card-subtitle"},(0,l.__)("Scan your site for file modifications and potential malware.","nhrrob-secure"))),(0,n.createElement)("div",{className:"nhrrob-scan-controls"},(0,n.createElement)("div",{className:"nhrrob-scan-type-toggle"},(0,n.createElement)("button",{className:"nhrrob-scan-toggle-btn "+("core"===m?"active":""),onClick:()=>h("core"),disabled:e},(0,l.__)("Core Integrity","nhrrob-secure")),(0,n.createElement)("button",{className:"nhrrob-scan-toggle-btn "+("malware"===m?"active":""),onClick:()=>h("malware"),disabled:e},(0,l.__)("Malware Scan","nhrrob-secure"))),(0,n.createElement)(a.Button,{variant:"primary",onClick:()=>d(),isBusy:e,disabled:e,icon:"update",iconPosition:"right"},e?(0,l.__)("Scanning...","nhrrob-secure"):(0,l.__)("Start Scan","nhrrob-secure")))),(0,n.createElement)("div",{className:"nhrrob-card-body"},i&&(0,n.createElement)("div",{className:"notice notice-error inline-notice"},(0,n.createElement)("p",null,i)),t&&(0,n.createElement)("div",{className:"nhrrob-secure-vulnerability-list"},("core"===m&&(t.modified?.length>0||t.missing?.length>0)||"malware"===m&&t.suspicious?.length>0)&&(0,n.createElement)("div",{className:"notice notice-warning inline-notice nhrrob-warning-notice"},(0,n.createElement)("p",null,(0,l.__)("Issues detected! Please review and update the items below.","nhrrob-secure"))),"core"===m&&(0,n.createElement)(n.Fragment,null,t.modified&&t.modified.length>0&&(0,n.createElement)("div",{className:"nhrrob-result-group"},(0,n.createElement)("h3",{className:"nhrrob-result-group-title"},(0,l.__)("Modified Core Files","nhrrob-secure")),(0,n.createElement)("div",{className:"nhrrob-result-list"},t.modified.map((e,r)=>(0,n.createElement)("div",{key:r,className:"nhrrob-result-row"},(0,n.createElement)("div",{className:"nhrrob-file-info"},(0,n.createElement)("strong",null,e)),(0,n.createElement)(a.Button,{variant:"secondary",isSmall:!0,onClick:()=>(async e=>{if(confirm((0,l.__)("Are you sure you want to repair this file? It will be overwritten with the original version.","nhrrob-secure")))try{await o()({path:"/nhrrob-secure/v1/scanner/repair",method:"POST",data:{file:e}}),alert((0,l.__)("File repaired successfully.","nhrrob-secure")),d()}catch(e){alert(e.message||(0,l.__)("Repair failed.","nhrrob-secure"))}})(e)},(0,l.__)("Repair","nhrrob-secure")))))),t.missing&&t.missing.length>0&&(0,n.createElement)("div",{className:"nhrrob-result-group"},(0,n.createElement)("h3",{className:"nhrrob-result-group-title"},(0,l.__)("Missing Core Files","nhrrob-secure")),(0,n.createElement)("div",{className:"nhrrob-result-list"},t.missing.map((e,r)=>(0,n.createElement)("div",{key:r,className:"nhrrob-result-row"},(0,n.createElement)("div",{className:"nhrrob-file-info"},(0,n.createElement)("strong",null,e)))))),!t.modified?.length&&!t.missing?.length&&(0,n.createElement)("div",{className:"nhrrob-secure-status-success"},(0,n.createElement)("span",{className:"dashicons dashicons-yes-alt"}),(0,l.__)("No modified core files found.","nhrrob-secure"))),"malware"===m&&(0,n.createElement)(n.Fragment,null,t.suspicious&&t.suspicious.length>0?(0,n.createElement)("div",{className:"nhrrob-result-group"},(0,n.createElement)("h3",{className:"nhrrob-result-group-title"},(0,l.__)("Suspicious Files","nhrrob-secure")),(0,n.createElement)("div",{className:"nhrrob-result-list"},t.suspicious.map((e,r)=>(0,n.createElement)("div",{key:r,className:"nhrrob-result-row"},(0,n.createElement)("div",{className:"nhrrob-file-info"},(0,n.createElement)("strong",null,e.file),(0,n.createElement)("span",{className:"nhrrob-file-meta"},e.reason)),(0,n.createElement)(a.Button,{variant:"link",isDestructive:!0,onClick:()=>(async e=>{if(confirm((0,l.__)("Are you sure you want to PERMANENTLY delete this file?","nhrrob-secure")))try{await o()({path:"/nhrrob-secure/v1/scanner/delete",method:"POST",data:{file:e}}),alert((0,l.__)("File deleted successfully.","nhrrob-secure")),d()}catch(e){alert(e.message||(0,l.__)("Delete failed.","nhrrob-secure"))}})(e.file)},(0,l.__)("Delete","nhrrob-secure")))))):(0,n.createElement)("div",{className:"nhrrob-secure-status-success"},(0,n.createElement)("span",{className:"dashicons dashicons-yes-alt"}),(0,l.__)("No suspicious files found.","nhrrob-secure")),(0,n.createElement)("p",{className:"description nhrrob-scan-count"},(0,n.createElement)("small",null,(0,l.__)("Scanned files:","nhrrob-secure")," ",t.scanned_count))))))},g=({settings:e,updateSetting:r})=>(0,n.createElement)(a.Card,{className:"nhrrob-secure-card nhrrob-secure-hardening-card"},(0,n.createElement)(a.CardBody,null,(0,n.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,l.__)("Hardening & Firewall","nhrrob-secure")),(0,n.createElement)("div",{className:"nhrrob-secure-setting-group"},(0,n.createElement)("h3",{className:"nhrrob-secure-setting-subtitle"},(0,l.__)("General Hardening","nhrrob-secure")),(0,n.createElement)(a.ToggleControl,{label:(0,l.__)("Disable XML-RPC","nhrrob-secure"),help:(0,l.__)("Prevents external systems (like mobile apps and Jetpack) from accessing your site via XML-RPC. Recommended if not used.","nhrrob-secure"),checked:e.nhrrob_secure_disable_xmlrpc,onChange:e=>r("nhrrob_secure_disable_xmlrpc",e)}),(0,n.createElement)(a.ToggleControl,{label:(0,l.__)("Disable File Editor","nhrrob-secure"),help:(0,l.__)("Disables the built-in theme and plugin file editor to prevent code execution if an admin account is compromised.","nhrrob-secure"),checked:e.nhrrob_secure_disable_file_editor,onChange:e=>r("nhrrob_secure_disable_file_editor",e)}),(0,n.createElement)(a.ToggleControl,{label:(0,l.__)("Hide WP Version","nhrrob-secure"),help:(0,l.__)("Removes WordPress version from page source and RSS feeds to make reconnaissance harder for attackers.","nhrrob-secure"),checked:e.nhrrob_secure_hide_wp_version,onChange:e=>r("nhrrob_secure_hide_wp_version",e)}),(0,n.createElement)(a.ToggleControl,{label:(0,l.__)("Disable REST API User Enumeration","nhrrob-secure"),help:(0,l.__)("Blocks access to /wp-json/wp/v2/users to prevent attackers from listing your users.","nhrrob-secure"),checked:e.nhrrob_secure_disable_rest_users,onChange:e=>r("nhrrob_secure_disable_rest_users",e)})),(0,n.createElement)("div",{className:"nhrrob-secure-setting-group border-t border-gray-100 pt-4 mt-4"},(0,n.createElement)("h3",{className:"nhrrob-secure-setting-subtitle"},(0,l.__)("Firewall Rules","nhrrob-secure")),(0,n.createElement)(a.TextareaControl,{label:(0,l.__)("Block User Agents","nhrrob-secure"),help:(0,l.__)('Enter one User-Agent per line to block. Case-insensitive partial match. Example: "HTTrack", "curl".',"nhrrob-secure"),value:e.nhrrob_secure_firewall_blocked_uas,onChange:e=>r("nhrrob_secure_firewall_blocked_uas",e),rows:5,placeholder:"SemrushBot\nAhrefsBot\nMJ12bot"})))),E=({settings:e,updateSetting:r})=>{const[t,c]=(0,s.useState)([]),[i,u]=(0,s.useState)(!1),[m,h]=(0,s.useState)(null);(0,s.useEffect)(()=>{d()},[]);const d=async()=>{u(!0),h(null);try{const e=await o()({path:"/nhrrob-secure/v1/sessions"});c(e)}catch(e){h(e.message||(0,l.__)("Failed to load sessions.","nhrrob-secure"))}finally{u(!1)}};return(0,n.createElement)(a.Card,{className:"nhrrob-secure-card nhrrob-secure-sessions-card"},(0,n.createElement)(a.CardBody,null,(0,n.createElement)("div",{className:"nhrrob-secure-card-header-flex"},(0,n.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,l.__)("User Session Management","nhrrob-secure")),(0,n.createElement)(a.Button,{variant:"primary",onClick:d,isBusy:i,disabled:i,icon:"update"},(0,l.__)("Refresh","nhrrob-secure"))),(0,n.createElement)("div",{className:"nhrrob-secure-setting-group"},(0,n.createElement)(a.TextControl,{label:(0,l.__)("Idle Timeout (Minutes)","nhrrob-secure"),help:(0,l.__)("Automatically log out inactive users after X minutes. Set to 0 to disable.","nhrrob-secure"),type:"number",value:e?.nhrrob_secure_idle_timeout||0,onChange:e=>r("nhrrob_secure_idle_timeout",parseInt(e)||0),min:"0"})),m&&(0,n.createElement)(a.Notice,{status:"error",isDismissible:!1},m),(0,n.createElement)("div",{className:"nhrrob-secure-sessions-list mt-4"},(0,n.createElement)("h3",{className:"text-sm font-semibold mb-3"},(0,l.__)("Active Sessions","nhrrob-secure")),0!==t.length||i?(0,n.createElement)("div",{className:"sessions-grid"},t.map((e,r)=>(0,n.createElement)("div",{key:r,className:"session-item p-3 border rounded mb-2 "+(e.is_current?"bg-blue-50 border-blue-200":"bg-gray-50 border-gray-200")},(0,n.createElement)("div",{className:"flex justify-between items-start"},(0,n.createElement)("div",{className:"session-info"},(0,n.createElement)("div",{className:"font-medium text-gray-700"},e.ip,e.is_current&&(0,n.createElement)("span",{className:"ml-2 px-2 py-0.5 text-xs bg-blue-100 text-blue-800 rounded-full"},(0,l.__)("Current Session","nhrrob-secure"))),(0,n.createElement)("div",{className:"text-xs text-gray-500 mt-1"},(0,n.createElement)("div",null,(0,l.__)("Login:","nhrrob-secure")," ",new Date(1e3*e.login).toLocaleString()),(0,n.createElement)("div",null,(0,l.__)("Expires:","nhrrob-secure")," ",new Date(1e3*e.expiration).toLocaleString()),(0,n.createElement)("div",{className:"mt-1 font-mono text-gray-400 truncate w-64",title:e.ua},e.ua))),!e.is_current&&(0,n.createElement)(a.Button,{variant:"link",isDestructive:!0,onClick:()=>(async e=>{if(confirm((0,l.__)("Are you sure you want to log out this session?","nhrrob-secure")))try{await o()({path:"/nhrrob-secure/v1/sessions/destroy",method:"POST",data:{verifier:e}}),d()}catch(e){alert(e.message||(0,l.__)("Failed to destroy session.","nhrrob-secure"))}})(e.verifier)},(0,l.__)("Logout","nhrrob-secure")))))):(0,n.createElement)("p",null,(0,l.__)("No active sessions found.","nhrrob-secure"))),t.length>1&&(0,n.createElement)("div",{className:"mt-4 pt-3 border-t"},(0,n.createElement)(a.Button,{variant:"secondary",isDestructive:!0,onClick:async()=>{if(confirm((0,l.__)("Are you sure you want to log out all other devices?","nhrrob-secure")))try{await o()({path:"/nhrrob-secure/v1/sessions/destroy-others",method:"POST"}),d(),alert((0,l.__)("All other sessions logged out.","nhrrob-secure"))}catch(e){alert(e.message||(0,l.__)("Failed to destroy sessions.","nhrrob-secure"))}},className:"w-full justify-center"},(0,l.__)("Log Out All Other Devices","nhrrob-secure")))))},p=({settings:e,updateSetting:r})=>{const[t,c]=(0,s.useState)([]),[i,u]=(0,s.useState)(!0),[m,h]=(0,s.useState)(0),[d,b]=(0,s.useState)(1);(0,s.useEffect)(()=>{_()},[d]);const _=async()=>{u(!0);try{const e=20*(d-1),r=await o()({path:`/nhrrob-secure/v1/logs?limit=20&offset=${e}`});c(r.items),h(r.total)}catch(e){console.error(e)}finally{u(!1)}},g=Math.ceil(m/20);return(0,n.createElement)(a.Card,{className:"nhrrob-secure-card nhrrob-secure-audit-log-card"},(0,n.createElement)(a.CardBody,null,(0,n.createElement)("div",{className:"nhrrob-secure-card-header-flex"},(0,n.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,l.__)("Activity Audit Log","nhrrob-secure")),(0,n.createElement)("div",{className:"nhrrob-secure-card-header-actions"},e&&(0,n.createElement)(a.SelectControl,{className:"nhrrob-secure-retention-select",value:e.nhrrob_secure_log_retention_days,options:[{label:(0,l.__)("Keep logs: 7 days","nhrrob-secure"),value:7},{label:(0,l.__)("Keep logs: 30 days","nhrrob-secure"),value:30},{label:(0,l.__)("Keep logs: 90 days","nhrrob-secure"),value:90},{label:(0,l.__)("Keep logs: 1 year","nhrrob-secure"),value:365}],onChange:e=>r("nhrrob_secure_log_retention_days",parseInt(e))}),(0,n.createElement)(a.Button,{variant:"primary",onClick:_,disabled:i,isBusy:i,icon:"update",iconPosition:"right"},(0,l.__)("Refresh","nhrrob-secure")))),i&&(0,n.createElement)("div",{className:"nhrrob-secure-loading-overlay"},(0,n.createElement)(a.Spinner,null)),(0,n.createElement)("div",{className:"nhrrob-secure-audit-table-wrapper"},(0,n.createElement)("table",{className:"nhrrob-secure-audit-table"},(0,n.createElement)("thead",null,(0,n.createElement)("tr",null,(0,n.createElement)("th",null,(0,l.__)("Date","nhrrob-secure")),(0,n.createElement)("th",null,(0,l.__)("User","nhrrob-secure")),(0,n.createElement)("th",null,(0,l.__)("Context","nhrrob-secure")),(0,n.createElement)("th",null,(0,l.__)("Action","nhrrob-secure")),(0,n.createElement)("th",null,(0,l.__)("Item","nhrrob-secure")),(0,n.createElement)("th",null,(0,l.__)("IP Address","nhrrob-secure")))),(0,n.createElement)("tbody",null,t.length>0?t.map(e=>(0,n.createElement)("tr",{key:e.id,className:`severity-${e.severity}`},(0,n.createElement)("td",null,new Date(e.date).toLocaleString()),(0,n.createElement)("td",null,e.user),(0,n.createElement)("td",null,(0,n.createElement)("span",{className:"nhrrob-secure-badge"},e.context)),(0,n.createElement)("td",null,e.action),(0,n.createElement)("td",null,e.label),(0,n.createElement)("td",null,e.ip))):(0,n.createElement)("tr",null,(0,n.createElement)("td",{colSpan:"6",className:"no-logs"},!i&&(0,l.__)("No activity logs found.","nhrrob-secure")))))),g>1&&(0,n.createElement)("div",{className:"nhrrob-secure-pagination"},(0,n.createElement)(a.Button,{isSmall:!0,disabled:1===d||i,onClick:()=>b(d-1)},"« ",(0,l.__)("Prev","nhrrob-secure")),(0,n.createElement)("span",{className:"nhrrob-secure-page-info"},(0,l.__)("Page","nhrrob-secure")," ",d," ",(0,l.__)("of","nhrrob-secure")," ",g),(0,n.createElement)(a.Button,{isSmall:!0,disabled:d===g||i,onClick:()=>b(d+1)},(0,l.__)("Next","nhrrob-secure")," »"))))},v=document.getElementById("nhrrob-secure-settings-root");v&&(0,s.render)((0,n.createElement)(()=>{const[e,r]=(0,s.useState)(null),[t,c]=(0,s.useState)(!0),[d,v]=(0,s.useState)(!1),[y,f]=(0,s.useState)(null);(0,s.useEffect)(()=>{N()},[]);const N=async()=>{try{const e=await o()({path:"/nhrrob-secure/v1/settings"});r(e),c(!1)}catch(e){f({type:"error",message:(0,l.__)("Failed to load settings","nhrrob-secure")}),c(!1)}},w=(t,n)=>{r({...e,[t]:n})};return(0,s.useEffect)(()=>{e?.nhrrob_secure_dark_mode?document.body.classList.add("nhrrob-secure-dark-mode-active"):document.body.classList.remove("nhrrob-secure-dark-mode-active")},[e?.nhrrob_secure_dark_mode]),t?(0,n.createElement)("div",{className:"nhrrob-secure-loading"},(0,n.createElement)(a.Spinner,null)):(0,n.createElement)("div",{className:"nhrrob-secure-settings "+(e.nhrrob_secure_dark_mode?"dark-mode":"")},(0,n.createElement)("div",{className:"nhrrob-secure-header"},(0,n.createElement)("div",{className:"nhrrob-secure-header-main"},(0,n.createElement)("h1",null,(0,l.__)("NHR Secure Settings","nhrrob-secure")),(0,n.createElement)(a.Button,{className:"nhrrob-secure-dark-mode-toggle",icon:e.nhrrob_secure_dark_mode?(0,n.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",width:"20",height:"20"},(0,n.createElement)("path",{d:"M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zM2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1zm18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1zM11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1zm0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1zM5.99 4.58a.996.996 0 00-1.41 0 .996.996 0 000 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41L5.99 4.58zm12.37 12.37a.996.996 0 00-1.41 0 .996.996 0 000 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41l-1.06-1.06zm1.06-10.96a.996.996 0 00-1.41-1.41l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06zM7.05 18.36a.996.996 0 00-1.41-1.41l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06z"})):(0,n.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",width:"20",height:"20"},(0,n.createElement)("path",{d:"M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-.46-.04-.92-.1-1.36-.98 1.37-2.58 2.26-4.4 2.26-2.98 0-5.4-2.42-5.4-5.4 0-1.81.89-3.42 2.26-4.4-.44-.06-.9-.1-1.36-.1z"})),onClick:async()=>{const r=!e.nhrrob_secure_dark_mode;w("nhrrob_secure_dark_mode",r);try{await o()({path:"/nhrrob-secure/v1/settings",method:"POST",data:{...e,nhrrob_secure_dark_mode:r}})}catch(e){console.error("Failed to save dark mode preference",e)}},label:(0,l.__)("Toggle Dark Mode","nhrrob-secure")})),(0,n.createElement)("p",{className:"nhrrob-secure-subtitle"},(0,l.__)("Configure security features for your WordPress site","nhrrob-secure"))),y&&(0,n.createElement)(a.Notice,{status:y.type,isDismissible:!0,onRemove:()=>f(null)},y.message),(0,n.createElement)("div",{className:"nhrrob-secure-cards"},(0,n.createElement)(i,{settings:e,updateSetting:w}),(0,n.createElement)(u,{settings:e,updateSetting:w}),(0,n.createElement)(m,{settings:e,updateSetting:w}),(0,n.createElement)(g,{settings:e,updateSetting:w}),(0,n.createElement)(h,{settings:e,updateSetting:w}),(0,n.createElement)(b,null),(0,n.createElement)(_,null),(0,n.createElement)(E,{settings:e,updateSetting:w}),(0,n.createElement)(p,{settings:e,updateSetting:w})),(0,n.createElement)("div",{className:"nhrrob-secure-actions"},(0,n.createElement)(a.Button,{variant:"primary",onClick:async()=>{v(!0),f(null);try{await o()({path:"/nhrrob-secure/v1/settings",method:"POST",data:e}),f({type:"success",message:(0,l.__)("Settings saved successfully!","nhrrob-secure")})}catch(e){f({type:"error",message:(0,l.__)("Failed to save settings","nhrrob-secure")})}finally{v(!1)}},isBusy:d,disabled:d},d?(0,l.__)("Saving...","nhrrob-secure"):(0,l.__)("Save Settings","nhrrob-secure"))))},null),v)}},t={};function n(e){var s=t[e];if(void 0!==s)return s.exports;var a=t[e]={exports:{}};return r[e](a,a.exports,n),a.exports}n.m=r,e=[],n.O=(r,t,s,a)=>{if(!t){var l=1/0;for(u=0;u<e.length;u++){for(var[t,s,a]=e[u],c=!0,o=0;o<t.length;o++)(!1&a||l>=a)&&Object.keys(n.O).every(e=>n.O[e](t[o]))?t.splice(o--,1):(c=!1,a<l&&(l=a));if(c){e.splice(u--,1);var i=s();void 0!==i&&(r=i)}}return r}a=a||0;for(var u=e.length;u>0&&e[u-1][2]>a;u--)e[u]=e[u-1];e[u]=[t,s,a]},n.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return n.d(r,{a:r}),r},n.d=(e,r)=>{for(var t in r)n.o(r,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},n.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),(()=>{var e={884:0,15:0};n.O.j=r=>0===e[r];var r=(r,t)=>{var s,a,[l,c,o]=t,i=0;if(l.some(r=>0!==e[r])){for(s in c)n.o(c,s)&&(n.m[s]=c[s]);if(o)var u=o(n)}for(r&&r(t);i<l.length;i++)a=l[i],n.o(e,a)&&e[a]&&e[a][0](),e[a]=0;return n.O(u)},t=globalThis.webpackChunknhrrob_secure=globalThis.webpackChunknhrrob_secure||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})();var s=n.O(void 0,[15],()=>n(195));s=n.O(s)})();1 (()=>{"use strict";var e,r={855(e,r,t){const a=window.React,l=window.wp.element,n=window.wp.components,s=window.wp.i18n,c=window.wp.apiFetch;var o=t.n(c);const i=({settings:e,updateSetting:r})=>(0,a.createElement)(n.Card,{className:"nhrrob-secure-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("Login Protection","nhrrob-secure")),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Enable Login Attempts Limit","nhrrob-secure"),help:(0,s.__)("Limit failed login attempts to prevent brute force attacks","nhrrob-secure"),checked:e.nhrrob_secure_limit_login_attempts,onChange:e=>r("nhrrob_secure_limit_login_attempts",e)}),e.nhrrob_secure_limit_login_attempts&&(0,a.createElement)(n.TextControl,{label:(0,s.__)("Maximum Login Attempts","nhrrob-secure"),help:(0,s.__)("Number of failed attempts before blocking (default: 5)","nhrrob-secure"),type:"number",value:e.nhrrob_secure_login_attempts_limit,onChange:e=>r("nhrrob_secure_login_attempts_limit",parseInt(e)||5),min:"1",max:"20"}),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Enable Proxy IP Detection","nhrrob-secure"),help:(0,s.__)("Detect real IP behind proxies (Cloudflare, etc.)","nhrrob-secure"),checked:e.nhrrob_secure_enable_proxy_ip,onChange:e=>r("nhrrob_secure_enable_proxy_ip",e)}))),u=({settings:e,updateSetting:r})=>(0,a.createElement)(n.Card,{className:"nhrrob-secure-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("Custom Login Page","nhrrob-secure")),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Enable Custom Login URL","nhrrob-secure"),help:(0,s.__)("Hide wp-login.php and use a custom login URL","nhrrob-secure"),checked:e.nhrrob_secure_custom_login_page,onChange:e=>r("nhrrob_secure_custom_login_page",e)}),e.nhrrob_secure_custom_login_page&&(0,a.createElement)(n.TextControl,{label:(0,s.__)("Custom Login URL","nhrrob-secure"),help:(0,s.__)("Your login page will be accessible at this URL","nhrrob-secure"),value:e.nhrrob_secure_custom_login_url,onChange:e=>r("nhrrob_secure_custom_login_url",e),placeholder:"/hidden-access-52w"}),e.nhrrob_secure_custom_login_page&&(0,a.createElement)("div",{className:"nhrrob-secure-info"},(0,a.createElement)("strong",null,(0,s.__)("Your login URL:","nhrrob-secure")),(0,a.createElement)("code",null,window.location.origin,e.nhrrob_secure_custom_login_url)))),m=({settings:e,updateSetting:r})=>{const t=e.nhrrob_secure_2fa_enforced_roles||[],l=e.available_roles||[];return(0,a.createElement)(n.Card,{className:"nhrrob-secure-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("Two-Factor Authentication","nhrrob-secure")),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Enable Global 2FA","nhrrob-secure"),help:(0,a.createElement)(a.Fragment,null,(0,s.__)("Enables Google Authenticator support for all users. Users can set it up in their ","nhrrob-secure"),(0,a.createElement)("a",{href:nhrrobSecureSettings.profile_url,target:"_blank",rel:"noreferrer"},(0,s.__)("profile page","nhrrob-secure")),"."),checked:e.nhrrob_secure_enable_2fa,onChange:e=>r("nhrrob_secure_enable_2fa",e)}),e.nhrrob_secure_enable_2fa&&(0,a.createElement)(a.Fragment,null,(0,a.createElement)("div",{className:"nhrrob-secure-2fa-method pt-4 border-t border-gray-100"},(0,a.createElement)("h3",{className:"text-sm font-semibold mb-3"},(0,s.__)("2FA Method","nhrrob-secure")),(0,a.createElement)(n.RadioControl,{selected:e.nhrrob_secure_2fa_type||"app",options:[{label:(0,s.__)("Authenticator App (Recommended)","nhrrob-secure"),value:"app"},{label:(0,s.__)("Email OTP","nhrrob-secure"),value:"email"}],onChange:e=>r("nhrrob_secure_2fa_type",e)})),(0,a.createElement)("div",{className:"nhrrob-secure-enforced-roles pt-4 border-t border-gray-100"},(0,a.createElement)("h3",{className:"text-sm font-semibold mb-3"},(0,s.__)("Enforced 2FA by Role","nhrrob-secure")),(0,a.createElement)("p",{className:"text-xs text-gray-500 mb-4"},(0,s.__)("Users with the selected roles will be forced to set up 2FA before they can access the admin dashboard.","nhrrob-secure")),(0,a.createElement)("div",{className:"grid grid-cols-2 gap-2"},l.map(e=>(0,a.createElement)(n.CheckboxControl,{key:e.value,label:e.label,checked:t.includes(e.value),onChange:a=>((e,a)=>{const l=a?[...t,e]:t.filter(r=>r!==e);r("nhrrob_secure_2fa_enforced_roles",l)})(e.value,a)})))))))},b=({settings:e,updateSetting:r})=>(0,a.createElement)(n.Card,{className:"nhrrob-secure-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("File Protection","nhrrob-secure")),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Protect Debug Log","nhrrob-secure"),help:(0,s.__)("Block direct access to wp-content/debug.log","nhrrob-secure"),checked:e.nhrrob_secure_protect_debug_log,onChange:e=>r("nhrrob_secure_protect_debug_log",e)}))),d=window.wp.htmlEntities,h=()=>{const[e,r]=(0,l.useState)(null),[t,c]=(0,l.useState)(!0),[i,u]=(0,l.useState)(!1),[m,b]=(0,l.useState)(null);(0,l.useEffect)(()=>{h()},[]);const h=async()=>{try{const e=await o()({path:"/nhrrob-secure/v1/vulnerability/status"});r(e),c(!1)}catch(e){b((0,s.__)("Failed to fetch vulnerability status","nhrrob-secure")),c(!1)}};if(t)return(0,a.createElement)(n.Card,{className:"nhrrob-secure-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)(n.Spinner,null)));const _=e&&(e.core.length>0||e.plugins.length>0||e.themes.length>0);return(0,a.createElement)(n.Card,{className:"nhrrob-secure-card nhrrob-secure-vulnerability-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)("div",{className:"nhrrob-secure-card-header-flex"},(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("Vulnerability Checker","nhrrob-secure")),(0,a.createElement)(n.Button,{variant:"primary",onClick:async()=>{u(!0),b(null);try{const e=await o()({path:"/nhrrob-secure/v1/vulnerability/scan",method:"POST"});r(e)}catch(e){b((0,s.__)("Failed to run vulnerability scan","nhrrob-secure"))}finally{u(!1)}},isBusy:i,disabled:i,icon:"update",iconPosition:"right"},i?(0,s.__)("Scanning...","nhrrob-secure"):(0,s.__)("Scan Now","nhrrob-secure"))),(0,a.createElement)("p",{className:"nhrrob-secure-last-scan"},(0,a.createElement)("strong",null,(0,s.__)("Last Scan:","nhrrob-secure"))," ",(g=e.last_scan)?new Date(1e3*g).toLocaleString():(0,s.__)("Never","nhrrob-secure")),m&&(0,a.createElement)(n.Notice,{status:"error",isDismissible:!1},m),_?(0,a.createElement)("div",{className:"nhrrob-secure-vulnerability-list"},(0,a.createElement)(n.Notice,{status:"warning",isDismissible:!1},(0,s.__)("Vulnerabilities detected! Please review and update the items below.","nhrrob-secure")),e.core.length>0&&(0,a.createElement)("div",{className:"vulnerability-section"},(0,a.createElement)("h3",null,(0,s.__)("WordPress Core","nhrrob-secure")),(0,a.createElement)("ul",null,e.core.map((e,r)=>(0,a.createElement)("li",{key:r},(0,d.decodeEntities)(e.name))))),e.plugins.length>0&&(0,a.createElement)("div",{className:"vulnerability-section"},(0,a.createElement)("h3",null,(0,s.__)("Plugins","nhrrob-secure")),e.plugins.map((e,r)=>(0,a.createElement)("div",{key:r,className:"vulnerability-item"},(0,a.createElement)("strong",null,(0,a.createElement)("a",{href:"plugins.php",style:{textDecoration:"none",color:"inherit"}},(0,d.decodeEntities)(e.name)),(0,a.createElement)("span",{style:{fontWeight:"normal",color:"#666"}}," (",e.version,")")),(0,a.createElement)("ul",null,e.vulnerabilities.map((e,r)=>(0,a.createElement)("li",{key:r},(0,d.decodeEntities)(e.name))))))),e.themes.length>0&&(0,a.createElement)("div",{className:"vulnerability-section"},(0,a.createElement)("h3",null,(0,s.__)("Themes","nhrrob-secure")),e.themes.map((e,r)=>(0,a.createElement)("div",{key:r,className:"vulnerability-item"},(0,a.createElement)("strong",null,(0,d.decodeEntities)(e.name)," (",e.version,")"),(0,a.createElement)("ul",null,e.vulnerabilities.map((e,r)=>(0,a.createElement)("li",{key:r},(0,d.decodeEntities)(e.name)))))))):(0,a.createElement)("div",{className:"nhrrob-secure-status-success"},(0,a.createElement)("span",{className:"dashicons dashicons-yes-alt"}),(0,s.__)("No known vulnerabilities detected.","nhrrob-secure"))));var g},_=()=>{const[e,r]=(0,l.useState)(!1),[t,c]=(0,l.useState)(null),[i,u]=(0,l.useState)(null),[m,b]=(0,l.useState)("core"),d=async()=>{r(!0),u(null),c(null);try{const e="core"===m?"/nhrrob-secure/v1/scanner/core":"/nhrrob-secure/v1/scanner/malware",r=await o()({path:e,method:"POST"});c(r)}catch(e){u(e.message||(0,s.__)("An error occurred during scan.","nhrrob-secure"))}finally{r(!1)}};return(0,a.createElement)("div",{className:"nhrrob-secure-card nhrrob-secure-vulnerability-card padded-header"},(0,a.createElement)("div",{className:"nhrrob-secure-card-header-flex"},(0,a.createElement)("div",{className:"nhrrob-secure-header-content"},(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("File Scanner","nhrrob-secure")),(0,a.createElement)("p",{className:"nhrrob-secure-card-subtitle"},(0,s.__)("Scan your site for file modifications and potential malware.","nhrrob-secure"))),(0,a.createElement)("div",{className:"nhrrob-scan-controls"},(0,a.createElement)("div",{className:"nhrrob-scan-type-toggle"},(0,a.createElement)("button",{className:"nhrrob-scan-toggle-btn "+("core"===m?"active":""),onClick:()=>b("core"),disabled:e},(0,s.__)("Core Integrity","nhrrob-secure")),(0,a.createElement)("button",{className:"nhrrob-scan-toggle-btn "+("malware"===m?"active":""),onClick:()=>b("malware"),disabled:e},(0,s.__)("Malware Scan","nhrrob-secure"))),(0,a.createElement)(n.Button,{variant:"primary",onClick:()=>d(),isBusy:e,disabled:e,icon:"update",iconPosition:"right"},e?(0,s.__)("Scanning...","nhrrob-secure"):(0,s.__)("Start Scan","nhrrob-secure")))),(0,a.createElement)("div",{className:"nhrrob-card-body"},i&&(0,a.createElement)("div",{className:"notice notice-error inline-notice"},(0,a.createElement)("p",null,i)),t&&(0,a.createElement)("div",{className:"nhrrob-secure-vulnerability-list"},("core"===m&&(t.modified?.length>0||t.missing?.length>0)||"malware"===m&&t.suspicious?.length>0)&&(0,a.createElement)("div",{className:"notice notice-warning inline-notice nhrrob-warning-notice"},(0,a.createElement)("p",null,(0,s.__)("Issues detected! Please review and update the items below.","nhrrob-secure"))),"core"===m&&(0,a.createElement)(a.Fragment,null,t.modified&&t.modified.length>0&&(0,a.createElement)("div",{className:"nhrrob-result-group"},(0,a.createElement)("h3",{className:"nhrrob-result-group-title"},(0,s.__)("Modified Core Files","nhrrob-secure")),(0,a.createElement)("div",{className:"nhrrob-result-list"},t.modified.map((e,r)=>(0,a.createElement)("div",{key:r,className:"nhrrob-result-row"},(0,a.createElement)("div",{className:"nhrrob-file-info"},(0,a.createElement)("strong",null,e)),(0,a.createElement)(n.Button,{variant:"secondary",isSmall:!0,onClick:()=>(async e=>{if(confirm((0,s.__)("Are you sure you want to repair this file? It will be overwritten with the original version.","nhrrob-secure")))try{await o()({path:"/nhrrob-secure/v1/scanner/repair",method:"POST",data:{file:e}}),alert((0,s.__)("File repaired successfully.","nhrrob-secure")),d()}catch(e){alert(e.message||(0,s.__)("Repair failed.","nhrrob-secure"))}})(e)},(0,s.__)("Repair","nhrrob-secure")))))),t.missing&&t.missing.length>0&&(0,a.createElement)("div",{className:"nhrrob-result-group"},(0,a.createElement)("h3",{className:"nhrrob-result-group-title"},(0,s.__)("Missing Core Files","nhrrob-secure")),(0,a.createElement)("div",{className:"nhrrob-result-list"},t.missing.map((e,r)=>(0,a.createElement)("div",{key:r,className:"nhrrob-result-row"},(0,a.createElement)("div",{className:"nhrrob-file-info"},(0,a.createElement)("strong",null,e)))))),!t.modified?.length&&!t.missing?.length&&(0,a.createElement)("div",{className:"nhrrob-secure-status-success"},(0,a.createElement)("span",{className:"dashicons dashicons-yes-alt"}),(0,s.__)("No modified core files found.","nhrrob-secure"))),"malware"===m&&(0,a.createElement)(a.Fragment,null,t.suspicious&&t.suspicious.length>0?(0,a.createElement)("div",{className:"nhrrob-result-group"},(0,a.createElement)("h3",{className:"nhrrob-result-group-title"},(0,s.__)("Suspicious Files","nhrrob-secure")),(0,a.createElement)("div",{className:"nhrrob-result-list"},t.suspicious.map((e,r)=>(0,a.createElement)("div",{key:r,className:"nhrrob-result-row"},(0,a.createElement)("div",{className:"nhrrob-file-info"},(0,a.createElement)("strong",null,e.file),(0,a.createElement)("span",{className:"nhrrob-file-meta"},e.reason)),(0,a.createElement)(n.Button,{variant:"link",isDestructive:!0,onClick:()=>(async e=>{if(confirm((0,s.__)("Are you sure you want to PERMANENTLY delete this file?","nhrrob-secure")))try{await o()({path:"/nhrrob-secure/v1/scanner/delete",method:"POST",data:{file:e}}),alert((0,s.__)("File deleted successfully.","nhrrob-secure")),d()}catch(e){alert(e.message||(0,s.__)("Delete failed.","nhrrob-secure"))}})(e.file)},(0,s.__)("Delete","nhrrob-secure")))))):(0,a.createElement)("div",{className:"nhrrob-secure-status-success"},(0,a.createElement)("span",{className:"dashicons dashicons-yes-alt"}),(0,s.__)("No suspicious files found.","nhrrob-secure")),(0,a.createElement)("p",{className:"description nhrrob-scan-count"},(0,a.createElement)("small",null,(0,s.__)("Scanned files:","nhrrob-secure")," ",t.scanned_count))))))},g=({settings:e,updateSetting:r})=>(0,a.createElement)(n.Card,{className:"nhrrob-secure-card nhrrob-secure-hardening-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("Hardening & Firewall","nhrrob-secure")),(0,a.createElement)("div",{className:"nhrrob-secure-setting-group"},(0,a.createElement)("h3",{className:"nhrrob-secure-setting-subtitle"},(0,s.__)("General Hardening","nhrrob-secure")),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Disable XML-RPC","nhrrob-secure"),help:(0,s.__)("Prevents external systems (like mobile apps and Jetpack) from accessing your site via XML-RPC. Recommended if not used.","nhrrob-secure"),checked:e.nhrrob_secure_disable_xmlrpc,onChange:e=>r("nhrrob_secure_disable_xmlrpc",e)}),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Disable File Editor","nhrrob-secure"),help:(0,s.__)("Disables the built-in theme and plugin file editor to prevent code execution if an admin account is compromised.","nhrrob-secure"),checked:e.nhrrob_secure_disable_file_editor,onChange:e=>r("nhrrob_secure_disable_file_editor",e)}),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Hide WP Version","nhrrob-secure"),help:(0,s.__)("Removes WordPress version from page source and RSS feeds to make reconnaissance harder for attackers.","nhrrob-secure"),checked:e.nhrrob_secure_hide_wp_version,onChange:e=>r("nhrrob_secure_hide_wp_version",e)}),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Disable REST API User Enumeration","nhrrob-secure"),help:(0,s.__)("Blocks access to /wp-json/wp/v2/users to prevent attackers from listing your users.","nhrrob-secure"),checked:e.nhrrob_secure_disable_rest_users,onChange:e=>r("nhrrob_secure_disable_rest_users",e)})),(0,a.createElement)("div",{className:"nhrrob-secure-setting-group border-t border-gray-100 pt-4 mt-4"},(0,a.createElement)("h3",{className:"nhrrob-secure-setting-subtitle"},(0,s.__)("Firewall Rules","nhrrob-secure")),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Advanced Firewall (IPS) Protection","nhrrob-secure"),help:(0,s.__)("Proactively block common attacks like SQL Injection, XSS, and LFI by scanning request data.","nhrrob-secure"),checked:e?.nhrrob_secure_enable_advanced_firewall||!1,onChange:e=>r("nhrrob_secure_enable_advanced_firewall",e)}),(0,a.createElement)(n.TextareaControl,{label:(0,s.__)("Block User Agents","nhrrob-secure"),help:(0,s.__)('Enter one User-Agent per line to block. Case-insensitive partial match. Example: "HTTrack", "curl".',"nhrrob-secure"),value:e.nhrrob_secure_firewall_blocked_uas,onChange:e=>r("nhrrob_secure_firewall_blocked_uas",e),rows:5,placeholder:"SemrushBot\nAhrefsBot\nMJ12bot"})))),v=({settings:e,updateSetting:r})=>{const[t,c]=(0,l.useState)([]),[i,u]=(0,l.useState)(!1),[m,b]=(0,l.useState)(null);(0,l.useEffect)(()=>{d()},[]);const d=async()=>{u(!0),b(null);try{const e=await o()({path:"/nhrrob-secure/v1/sessions"});c(e)}catch(e){b(e.message||(0,s.__)("Failed to load sessions.","nhrrob-secure"))}finally{u(!1)}};return(0,a.createElement)(n.Card,{className:"nhrrob-secure-card nhrrob-secure-sessions-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)("div",{className:"nhrrob-secure-card-header-flex"},(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("User Session Management","nhrrob-secure")),(0,a.createElement)(n.Button,{variant:"primary",onClick:d,isBusy:i,disabled:i,icon:"update"},(0,s.__)("Refresh","nhrrob-secure"))),(0,a.createElement)("div",{className:"nhrrob-secure-setting-group"},(0,a.createElement)(n.TextControl,{label:(0,s.__)("Idle Timeout (Minutes)","nhrrob-secure"),help:(0,s.__)("Automatically log out inactive users after X minutes. Set to 0 to disable.","nhrrob-secure"),type:"number",value:e?.nhrrob_secure_idle_timeout||0,onChange:e=>r("nhrrob_secure_idle_timeout",parseInt(e)||0),min:"0"})),m&&(0,a.createElement)(n.Notice,{status:"error",isDismissible:!1},m),(0,a.createElement)("div",{className:"nhrrob-secure-sessions-list mt-4"},(0,a.createElement)("h3",{className:"text-sm font-semibold mb-3"},(0,s.__)("Active Sessions","nhrrob-secure")),0!==t.length||i?(0,a.createElement)("div",{className:"sessions-grid"},t.map((e,r)=>(0,a.createElement)("div",{key:r,className:"session-item p-3 border rounded mb-2 "+(e.is_current?"bg-blue-50 border-blue-200":"bg-gray-50 border-gray-200")},(0,a.createElement)("div",{className:"flex justify-between items-start"},(0,a.createElement)("div",{className:"session-info"},(0,a.createElement)("div",{className:"font-medium text-gray-700"},e.ip,e.is_current&&(0,a.createElement)("span",{className:"ml-2 px-2 py-0.5 text-xs bg-blue-100 text-blue-800 rounded-full"},(0,s.__)("Current Session","nhrrob-secure"))),(0,a.createElement)("div",{className:"text-xs text-gray-500 mt-1"},(0,a.createElement)("div",null,(0,s.__)("Login:","nhrrob-secure")," ",new Date(1e3*e.login).toLocaleString()),(0,a.createElement)("div",null,(0,s.__)("Expires:","nhrrob-secure")," ",new Date(1e3*e.expiration).toLocaleString()),(0,a.createElement)("div",{className:"mt-1 font-mono text-gray-400 truncate w-64",title:e.ua},e.ua))),!e.is_current&&(0,a.createElement)(n.Button,{variant:"link",isDestructive:!0,onClick:()=>(async e=>{if(confirm((0,s.__)("Are you sure you want to log out this session?","nhrrob-secure")))try{await o()({path:"/nhrrob-secure/v1/sessions/destroy",method:"POST",data:{verifier:e}}),d()}catch(e){alert(e.message||(0,s.__)("Failed to destroy session.","nhrrob-secure"))}})(e.verifier)},(0,s.__)("Logout","nhrrob-secure")))))):(0,a.createElement)("p",null,(0,s.__)("No active sessions found.","nhrrob-secure"))),t.length>1&&(0,a.createElement)("div",{className:"mt-4 pt-3 border-t"},(0,a.createElement)(n.Button,{variant:"secondary",isDestructive:!0,onClick:async()=>{if(confirm((0,s.__)("Are you sure you want to log out all other devices?","nhrrob-secure")))try{await o()({path:"/nhrrob-secure/v1/sessions/destroy-others",method:"POST"}),d(),alert((0,s.__)("All other sessions logged out.","nhrrob-secure"))}catch(e){alert(e.message||(0,s.__)("Failed to destroy sessions.","nhrrob-secure"))}},className:"justify-center h-auto py-2 text-xs"},(0,s.__)("Log Out All Other Devices","nhrrob-secure")))))},p=({settings:e,updateSetting:r})=>{const[t,c]=(0,l.useState)([]),[i,u]=(0,l.useState)(!0),[m,b]=(0,l.useState)(0),[d,h]=(0,l.useState)(1);(0,l.useEffect)(()=>{_()},[d]);const _=async()=>{u(!0);try{const e=20*(d-1),r=await o()({path:`/nhrrob-secure/v1/logs?limit=20&offset=${e}`});c(r.items),b(r.total)}catch(e){console.error(e)}finally{u(!1)}},g=Math.ceil(m/20);return(0,a.createElement)(n.Card,{className:"nhrrob-secure-card nhrrob-secure-audit-log-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)("div",{className:"nhrrob-secure-card-header-flex"},(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("Activity Audit Log","nhrrob-secure")),(0,a.createElement)("div",{className:"nhrrob-secure-card-header-actions"},e&&(0,a.createElement)(n.SelectControl,{className:"nhrrob-secure-retention-select",value:e.nhrrob_secure_log_retention_days,options:[{label:(0,s.__)("Keep logs: 7 days","nhrrob-secure"),value:7},{label:(0,s.__)("Keep logs: 30 days","nhrrob-secure"),value:30},{label:(0,s.__)("Keep logs: 90 days","nhrrob-secure"),value:90},{label:(0,s.__)("Keep logs: 1 year","nhrrob-secure"),value:365}],onChange:e=>r("nhrrob_secure_log_retention_days",parseInt(e))}),(0,a.createElement)(n.Button,{variant:"primary",onClick:_,disabled:i,isBusy:i,icon:"update",iconPosition:"right"},(0,s.__)("Refresh","nhrrob-secure")))),i&&(0,a.createElement)("div",{className:"nhrrob-secure-loading-overlay"},(0,a.createElement)(n.Spinner,null)),(0,a.createElement)("div",{className:"nhrrob-secure-audit-table-wrapper"},(0,a.createElement)("table",{className:"nhrrob-secure-audit-table"},(0,a.createElement)("thead",null,(0,a.createElement)("tr",null,(0,a.createElement)("th",null,(0,s.__)("Date","nhrrob-secure")),(0,a.createElement)("th",null,(0,s.__)("User","nhrrob-secure")),(0,a.createElement)("th",null,(0,s.__)("Context","nhrrob-secure")),(0,a.createElement)("th",null,(0,s.__)("Action","nhrrob-secure")),(0,a.createElement)("th",null,(0,s.__)("Item","nhrrob-secure")),(0,a.createElement)("th",null,(0,s.__)("IP Address","nhrrob-secure")))),(0,a.createElement)("tbody",null,t.length>0?t.map(e=>(0,a.createElement)("tr",{key:e.id,className:`severity-${e.severity}`},(0,a.createElement)("td",null,new Date(e.date).toLocaleString()),(0,a.createElement)("td",null,e.user),(0,a.createElement)("td",null,(0,a.createElement)("span",{className:"nhrrob-secure-badge"},e.context)),(0,a.createElement)("td",null,e.action),(0,a.createElement)("td",null,e.label),(0,a.createElement)("td",null,e.ip))):(0,a.createElement)("tr",null,(0,a.createElement)("td",{colSpan:"6",className:"no-logs"},!i&&(0,s.__)("No activity logs found.","nhrrob-secure")))))),g>1&&(0,a.createElement)("div",{className:"nhrrob-secure-pagination"},(0,a.createElement)(n.Button,{isSmall:!0,disabled:1===d||i,onClick:()=>h(d-1)},"« ",(0,s.__)("Prev","nhrrob-secure")),(0,a.createElement)("span",{className:"nhrrob-secure-page-info"},(0,s.__)("Page","nhrrob-secure")," ",d," ",(0,s.__)("of","nhrrob-secure")," ",g),(0,a.createElement)(n.Button,{isSmall:!0,disabled:d===g||i,onClick:()=>h(d+1)},(0,s.__)("Next","nhrrob-secure")," »"))))},E=({onApplyOneClick:e})=>{const[r,t]=(0,l.useState)(null),[c,i]=(0,l.useState)(!0),[u,m]=(0,l.useState)(!1);(0,l.useEffect)(()=>{b()},[]);const b=async()=>{try{const e=await o()({path:"/nhrrob-secure/v1/health-stats"});t(e),i(!1)}catch(e){console.error("Failed to fetch health stats",e),i(!1)}};if(c)return(0,a.createElement)("div",{className:"nhrrob-secure-card p-6 flex items-center justify-center"},(0,a.createElement)(n.Spinner,null));if(!r)return null;const{score:d,total:h,checks:_,grade:g}=r,v=Math.round(d/h*100);return(0,a.createElement)("div",{className:"nhrrob-secure-card h-full flex flex-col"},(0,a.createElement)("div",{className:"p-5 border-b border-gray-100 dark:border-gray-800 flex items-center justify-between"},(0,a.createElement)("div",null,(0,a.createElement)("h2",{className:"nhrrob-secure-card-title border-0 pb-0"},(0,s.__)("Security Health Check","nhrrob-secure")),(0,a.createElement)("p",{className:"text-xs text-gray-500 mt-1"},(0,s.__)("Overall protection status of your WordPress site","nhrrob-secure"))),(0,a.createElement)("div",{className:"text-2xl font-bold px-3 py-1 rounded-lg "+(E=g,E.startsWith("A")?"bg-green-100 text-green-700":"B"===E?"bg-yellow-100 text-yellow-700":"bg-red-100 text-red-700")},g)),(0,a.createElement)("div",{className:"p-6 flex flex-col md:flex-row items-center gap-8"},(0,a.createElement)("div",{className:"relative w-32 h-32 flex items-center justify-center"},(0,a.createElement)("svg",{className:"w-full h-full transform -rotate-90"},(0,a.createElement)("circle",{cx:"64",cy:"64",r:"58",stroke:"currentColor",strokeWidth:"10",fill:"transparent",className:"text-gray-100 dark:text-gray-800"}),(0,a.createElement)("circle",{cx:"64",cy:"64",r:"58",stroke:"currentColor",strokeWidth:"10",fill:"transparent",strokeDasharray:364,strokeDashoffset:364-364*v/100,strokeLinecap:"round",className:"transition-all duration-1000 ease-out "+(p=v,p>=80?"text-green-500":p>=60?"text-yellow-500":"text-red-500")})),(0,a.createElement)("div",{className:"absolute flex flex-col items-center"},(0,a.createElement)("span",{className:"text-3xl font-bold"},v,"%"),(0,a.createElement)("span",{className:"text-[10px] uppercase tracking-wider text-gray-400 font-semibold"},(0,s.__)("Secure","nhrrob-secure")))),(0,a.createElement)("div",{className:"flex-1 w-full"},(0,a.createElement)("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-3 mb-4"},_.map(e=>(0,a.createElement)("div",{key:e.id,className:"flex items-start gap-2 group"},(0,a.createElement)("div",{className:"mt-0.5 rounded-full p-0.5 "+(e.passed?"text-green-500":"text-red-400 opacity-60")},(0,a.createElement)(n.Icon,{icon:e.passed?"yes":"no-alt",size:16})),(0,a.createElement)("div",null,(0,a.createElement)("span",{className:"text-xs font-medium "+(e.passed?"text-gray-700 dark:text-gray-300":"text-gray-400")},e.label))))),(0,a.createElement)(n.Button,{variant:"secondary",className:"justify-center text-xs py-2 h-auto hover:bg-blue-600 hover:text-white transition-colors",onClick:async()=>{m(!0);try{const r=await o()({path:"/nhrrob-secure/v1/one-click-secure",method:"POST"});r.success&&(t(r.stats),e(r.settings))}catch(e){console.error("One-click secure failed",e)}finally{m(!1)}},isBusy:u,disabled:u},u?(0,s.__)("Applying...","nhrrob-secure"):(0,s.__)("One-Click Secure Recommendations","nhrrob-secure")))));var p,E},y=({settings:e,updateSetting:r})=>{const t=[{label:(0,s.__)("Select Countries to Block...","nhrrob-secure"),value:""},{label:"Afghanistan",value:"AF"},{label:"Albania",value:"AL"},{label:"Algeria",value:"DZ"},{label:"Argentina",value:"AR"},{label:"Australia",value:"AU"},{label:"Austria",value:"AT"},{label:"Bangladesh",value:"BD"},{label:"Belarus",value:"BY"},{label:"Belgium",value:"BE"},{label:"Brazil",value:"BR"},{label:"Bulgaria",value:"BG"},{label:"Canada",value:"CA"},{label:"Chile",value:"CL"},{label:"China",value:"CN"},{label:"Colombia",value:"CO"},{label:"Croatia",value:"HR"},{label:"Cuba",value:"CU"},{label:"Czech Republic",value:"CZ"},{label:"Denmark",value:"DK"},{label:"Egypt",value:"EG"},{label:"Estonia",value:"EE"},{label:"Ethiopia",value:"ET"},{label:"Finland",value:"FI"},{label:"France",value:"FR"},{label:"Germany",value:"DE"},{label:"Ghana",value:"GH"},{label:"Greece",value:"GR"},{label:"Hong Kong",value:"HK"},{label:"Hungary",value:"HU"},{label:"Iceland",value:"IS"},{label:"India",value:"IN"},{label:"Indonesia",value:"ID"},{label:"Iran",value:"IR"},{label:"Iraq",value:"IQ"},{label:"Ireland",value:"IE"},{label:"Israel",value:"IL"},{label:"Italy",value:"IT"},{label:"Japan",value:"JP"},{label:"Kazakhstan",value:"KZ"},{label:"Kenya",value:"KE"},{label:"Kuwait",value:"KW"},{label:"Latvia",value:"LV"},{label:"Lebanon",value:"LB"},{label:"Libya",value:"LY"},{label:"Lithuania",value:"LT"},{label:"Luxembourg",value:"LU"},{label:"Malaysia",value:"MY"},{label:"Mexico",value:"MX"},{label:"Morocco",value:"MA"},{label:"Myanmar",value:"MM"},{label:"Nepal",value:"NP"},{label:"Netherlands",value:"NL"},{label:"New Zealand",value:"NZ"},{label:"Nigeria",value:"NG"},{label:"North Korea",value:"KP"},{label:"Norway",value:"NO"},{label:"Pakistan",value:"PK"},{label:"Palestine",value:"PS"},{label:"Philippines",value:"PH"},{label:"Poland",value:"PL"},{label:"Portugal",value:"PT"},{label:"Qatar",value:"QA"},{label:"Romania",value:"RO"},{label:"Russia",value:"RU"},{label:"Saudi Arabia",value:"SA"},{label:"Serbia",value:"RS"},{label:"Singapore",value:"SG"},{label:"Slovakia",value:"SK"},{label:"Slovenia",value:"SI"},{label:"Somalia",value:"SO"},{label:"South Africa",value:"ZA"},{label:"South Korea",value:"KR"},{label:"Spain",value:"ES"},{label:"Sri Lanka",value:"LK"},{label:"Sudan",value:"SD"},{label:"Sweden",value:"SE"},{label:"Switzerland",value:"CH"},{label:"Syria",value:"SY"},{label:"Taiwan",value:"TW"},{label:"Thailand",value:"TH"},{label:"Turkey",value:"TR"},{label:"Ukraine",value:"UA"},{label:"United Arab Emirates",value:"AE"},{label:"United Kingdom",value:"GB"},{label:"United States",value:"US"},{label:"Venezuela",value:"VE"},{label:"Vietnam",value:"VN"},{label:"Yemen",value:"YE"},{label:"Zimbabwe",value:"ZW"}],l=e.nhrrob_secure_blocked_countries||[],c=e=>{if(!e)return;let t;t=l.includes(e)?l.filter(r=>r!==e):[...l,e],r("nhrrob_secure_blocked_countries",t)};return(0,a.createElement)(n.Card,{className:"nhrrob-secure-card nhrrob-secure-ip-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("IP & Country Management","nhrrob-secure")),(0,a.createElement)("p",{className:"text-sm text-gray-500 dark:text-gray-400 mb-6"},(0,s.__)("Control access to your site by whitelisting safe IPs or blocking malicious ones and entire countries.","nhrrob-secure")),(0,a.createElement)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6"},(0,a.createElement)("div",{className:"nhrrob-secure-setting-group"},(0,a.createElement)("label",{className:"block text-sm font-semibold text-green-600 dark:text-green-400 mb-2"},(0,s.__)("IP Whitelist (Safe)","nhrrob-secure")),(0,a.createElement)(n.TextareaControl,{help:(0,s.__)("One IP or CIDR per line (e.g., 192.168.1.1 or 10.0.0.0/24). Whitelisted IPs bypass all security filters.","nhrrob-secure"),value:e.nhrrob_secure_ip_whitelist,onChange:e=>r("nhrrob_secure_ip_whitelist",e),rows:6,placeholder:"1.2.3.4"})),(0,a.createElement)("div",{className:"nhrrob-secure-setting-group"},(0,a.createElement)("label",{className:"block text-sm font-semibold text-red-600 dark:text-red-400 mb-2"},(0,s.__)("IP Blacklist (Blocked)","nhrrob-secure")),(0,a.createElement)(n.TextareaControl,{help:(0,s.__)("One IP or CIDR per line. Blacklisted IPs are blocked immediately from the entire site.","nhrrob-secure"),value:e.nhrrob_secure_ip_blacklist,onChange:e=>r("nhrrob_secure_ip_blacklist",e),rows:6,placeholder:"5.6.7.8"}))),(0,a.createElement)("div",{className:"mt-8 border-t border-gray-100 dark:border-gray-700"},(0,a.createElement)("h3",{className:"text-sm font-semibold mb-4 text-gray-900 dark:text-gray-100"},(0,s.__)("Country Blocking","nhrrob-secure")),(0,a.createElement)("div",{className:"flex flex-wrap gap-4 items-end"},(0,a.createElement)("div",{className:"flex-1 max-w-xs nhrrob-secure-country-select"},(0,a.createElement)(n.SelectControl,{label:(0,s.__)("Add Country to Block","nhrrob-secure"),options:t,onChange:c,className:"dark-mode-select"}))),l.length>0&&(0,a.createElement)("div",{className:"mt-4 flex flex-wrap gap-2"},l.map(e=>(0,a.createElement)("div",{key:e,className:"bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-400 px-3 py-1.5 rounded-full text-xs font-medium flex items-center gap-1 border border-red-200 dark:border-red-800/50"},t.find(r=>r.value===e)?.label||e,(0,a.createElement)("button",{onClick:()=>c(e),className:"focus:outline-none transition-colors text-sm leading-none -mr-0.5 bg-red-50 dark:bg-red-900/20 border-none cursor-pointer",title:(0,s.__)("Remove","nhrrob-secure"),"aria-label":(0,s.__)("Remove","nhrrob-secure")},"×")))),(0,a.createElement)("p",{className:"text-xs text-gray-400 dark:text-gray-500 mt-4 italic"},(0,s.__)("Note: Country blocking uses a free GeoIP lookup service with caching for performance.","nhrrob-secure")))))},f=document.getElementById("nhrrob-secure-settings-root");f&&(0,l.render)((0,a.createElement)(()=>{const[e,r]=(0,l.useState)(null),[t,c]=(0,l.useState)(!0),[d,f]=(0,l.useState)(!1),[N,k]=(0,l.useState)(null);(0,l.useEffect)(()=>{x()},[]);const x=async()=>{try{const e=await o()({path:"/nhrrob-secure/v1/settings"});r(e),c(!1)}catch(e){k({type:"error",message:(0,s.__)("Failed to load settings","nhrrob-secure")}),c(!1)}},w=(t,a)=>{r({...e,[t]:a})};return(0,l.useEffect)(()=>{e?.nhrrob_secure_dark_mode?document.body.classList.add("nhrrob-secure-dark-mode-active"):document.body.classList.remove("nhrrob-secure-dark-mode-active")},[e?.nhrrob_secure_dark_mode]),t?(0,a.createElement)("div",{className:"nhrrob-secure-loading"},(0,a.createElement)(n.Spinner,null)):(0,a.createElement)("div",{className:"nhrrob-secure-settings "+(e.nhrrob_secure_dark_mode?"dark-mode":"")},(0,a.createElement)("div",{className:"nhrrob-secure-header"},(0,a.createElement)("div",{className:"nhrrob-secure-header-main"},(0,a.createElement)("h1",null,(0,s.__)("NHR Secure Settings","nhrrob-secure")),(0,a.createElement)(n.Button,{className:"nhrrob-secure-dark-mode-toggle",icon:e.nhrrob_secure_dark_mode?(0,a.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",width:"20",height:"20"},(0,a.createElement)("path",{d:"M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zM2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1zm18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1zM11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1zm0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1zM5.99 4.58a.996.996 0 00-1.41 0 .996.996 0 000 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41L5.99 4.58zm12.37 12.37a.996.996 0 00-1.41 0 .996.996 0 000 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41l-1.06-1.06zm1.06-10.96a.996.996 0 00-1.41-1.41l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06zM7.05 18.36a.996.996 0 00-1.41-1.41l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06z"})):(0,a.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",width:"20",height:"20"},(0,a.createElement)("path",{d:"M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-.46-.04-.92-.1-1.36-.98 1.37-2.58 2.26-4.4 2.26-2.98 0-5.4-2.42-5.4-5.4 0-1.81.89-3.42 2.26-4.4-.44-.06-.9-.1-1.36-.1z"})),onClick:async()=>{const r=!e.nhrrob_secure_dark_mode;w("nhrrob_secure_dark_mode",r);try{await o()({path:"/nhrrob-secure/v1/settings",method:"POST",data:{...e,nhrrob_secure_dark_mode:r}})}catch(e){console.error("Failed to save dark mode preference",e)}},label:(0,s.__)("Toggle Dark Mode","nhrrob-secure")})),(0,a.createElement)("p",{className:"nhrrob-secure-subtitle"},(0,s.__)("Configure security features for your WordPress site","nhrrob-secure"))),N&&(0,a.createElement)(n.Notice,{status:N.type,isDismissible:!0,onRemove:()=>k(null)},N.message),(0,a.createElement)("div",{className:"nhrrob-secure-cards"},(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(E,{onApplyOneClick:e=>r(e)})),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(i,{settings:e,updateSetting:w})),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(u,{settings:e,updateSetting:w})),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(m,{settings:e,updateSetting:w})),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(g,{settings:e,updateSetting:w})),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(b,{settings:e,updateSetting:w})),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(h,null)),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(y,{settings:e,updateSetting:w})),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(_,null)),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(v,{settings:e,updateSetting:w})),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(p,{settings:e,updateSetting:w}))),(0,a.createElement)("div",{className:"nhrrob-secure-actions"},(0,a.createElement)(n.Button,{variant:"primary",onClick:async()=>{f(!0),k(null);try{await o()({path:"/nhrrob-secure/v1/settings",method:"POST",data:e}),k({type:"success",message:(0,s.__)("Settings saved successfully!","nhrrob-secure")})}catch(e){k({type:"error",message:(0,s.__)("Failed to save settings","nhrrob-secure")})}finally{f(!1)}},isBusy:d,disabled:d},d?(0,s.__)("Saving...","nhrrob-secure"):(0,s.__)("Save Settings","nhrrob-secure"))))},null),f)}},t={};function a(e){var l=t[e];if(void 0!==l)return l.exports;var n=t[e]={exports:{}};return r[e](n,n.exports,a),n.exports}a.m=r,e=[],a.O=(r,t,l,n)=>{if(!t){var s=1/0;for(u=0;u<e.length;u++){for(var[t,l,n]=e[u],c=!0,o=0;o<t.length;o++)(!1&n||s>=n)&&Object.keys(a.O).every(e=>a.O[e](t[o]))?t.splice(o--,1):(c=!1,n<s&&(s=n));if(c){e.splice(u--,1);var i=l();void 0!==i&&(r=i)}}return r}n=n||0;for(var u=e.length;u>0&&e[u-1][2]>n;u--)e[u]=e[u-1];e[u]=[t,l,n]},a.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return a.d(r,{a:r}),r},a.d=(e,r)=>{for(var t in r)a.o(r,t)&&!a.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},a.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),(()=>{var e={884:0,15:0};a.O.j=r=>0===e[r];var r=(r,t)=>{var l,n,[s,c,o]=t,i=0;if(s.some(r=>0!==e[r])){for(l in c)a.o(c,l)&&(a.m[l]=c[l]);if(o)var u=o(a)}for(r&&r(t);i<s.length;i++)n=s[i],a.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return a.O(u)},t=globalThis.webpackChunknhrrob_secure=globalThis.webpackChunknhrrob_secure||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})();var l=a.O(void 0,[15],()=>a(855));l=a.O(l)})(); -
nhrrob-secure/tags/1.3.0/build/profile.asset.php
r3441244 r3450292 1 <?php return array('dependencies' => array(), 'version' => ' b365bbc000a0d9a2f03a');1 <?php return array('dependencies' => array(), 'version' => '8b4ecd4b3ffe54fafb7d'); -
nhrrob-secure/tags/1.3.0/build/profile.css
r3441244 r3450292 268 268 line-height: 1.25rem 269 269 } 270 .absolute { 271 272 position: absolute 273 } 274 .relative { 275 276 position: relative 277 } 278 .-mr-0\.5 { 279 280 margin-right: -0.125rem 281 } 270 282 .mb-2 { 271 283 … … 280 292 margin-bottom: 1rem 281 293 } 294 .mb-6 { 295 296 margin-bottom: 1.5rem 297 } 282 298 .ml-2 { 283 299 … … 292 308 margin-top: 0px 293 309 } 310 .mt-0\.5 { 311 312 margin-top: 0.125rem 313 } 294 314 .mt-1 { 295 315 … … 300 320 margin-top: 1rem 301 321 } 322 .mt-8 { 323 324 margin-top: 2rem 325 } 302 326 .block { 303 327 … … 320 344 display: none 321 345 } 346 .h-32 { 347 348 height: 8rem 349 } 350 .h-auto { 351 352 height: auto 353 } 354 .h-full { 355 356 height: 100% 357 } 358 .w-32 { 359 360 width: 8rem 361 } 322 362 .w-64 { 323 363 … … 328 368 width: 100% 329 369 } 370 .max-w-xs { 371 372 max-width: 20rem 373 } 374 .flex-1 { 375 376 flex: 1 1 0% 377 } 378 .-rotate-90 { 379 380 --tw-rotate: -90deg; 381 382 transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) 383 } 384 .transform { 385 386 transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) 387 } 388 .cursor-pointer { 389 390 cursor: pointer 391 } 392 .grid-cols-1 { 393 394 grid-template-columns: repeat(1, minmax(0, 1fr)) 395 } 330 396 .grid-cols-2 { 331 397 332 398 grid-template-columns: repeat(2, minmax(0, 1fr)) 333 399 } 400 .flex-col { 401 402 flex-direction: column 403 } 404 .flex-wrap { 405 406 flex-wrap: wrap 407 } 334 408 .items-start { 335 409 336 410 align-items: flex-start 337 411 } 412 .items-end { 413 414 align-items: flex-end 415 } 416 .items-center { 417 418 align-items: center 419 } 338 420 .justify-center { 339 421 … … 344 426 justify-content: space-between 345 427 } 428 .gap-1 { 429 430 gap: 0.25rem 431 } 346 432 .gap-2 { 347 433 348 434 gap: 0.5rem 349 435 } 436 .gap-3 { 437 438 gap: 0.75rem 439 } 440 .gap-4 { 441 442 gap: 1rem 443 } 444 .gap-6 { 445 446 gap: 1.5rem 447 } 448 .gap-8 { 449 450 gap: 2rem 451 } 350 452 .truncate { 351 453 … … 364 466 border-radius: 9999px 365 467 } 468 .rounded-lg { 469 470 border-radius: 0.5rem 471 } 366 472 .border { 367 473 368 474 border-width: 1px 369 475 } 476 .border-0 { 477 478 border-width: 0px 479 } 480 .border-b { 481 482 border-bottom-width: 1px 483 } 370 484 .border-t { 371 485 372 486 border-top-width: 1px 373 487 } 488 .border-none { 489 490 border-style: none 491 } 374 492 .border-blue-200 { 375 493 … … 390 508 border-color: rgb(229 231 235 / var(--tw-border-opacity, 1)) 391 509 } 510 .border-red-200 { 511 512 --tw-border-opacity: 1; 513 514 border-color: rgb(254 202 202 / var(--tw-border-opacity, 1)) 515 } 392 516 .bg-blue-100 { 393 517 … … 408 532 background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1)) 409 533 } 534 .bg-green-100 { 535 536 --tw-bg-opacity: 1; 537 538 background-color: rgb(220 252 231 / var(--tw-bg-opacity, 1)) 539 } 540 .bg-red-100 { 541 542 --tw-bg-opacity: 1; 543 544 background-color: rgb(254 226 226 / var(--tw-bg-opacity, 1)) 545 } 546 .bg-red-50 { 547 548 --tw-bg-opacity: 1; 549 550 background-color: rgb(254 242 242 / var(--tw-bg-opacity, 1)) 551 } 552 .bg-yellow-100 { 553 554 --tw-bg-opacity: 1; 555 556 background-color: rgb(254 249 195 / var(--tw-bg-opacity, 1)) 557 } 558 .p-0\.5 { 559 560 padding: 0.125rem 561 } 410 562 .p-3 { 411 563 412 564 padding: 0.75rem 413 565 } 566 .p-5 { 567 568 padding: 1.25rem 569 } 570 .p-6 { 571 572 padding: 1.5rem 573 } 414 574 .px-2 { 415 575 … … 418 578 padding-right: 0.5rem 419 579 } 580 .px-3 { 581 582 padding-left: 0.75rem; 583 584 padding-right: 0.75rem 585 } 420 586 .py-0\.5 { 421 587 … … 424 590 padding-bottom: 0.125rem 425 591 } 592 .py-1 { 593 594 padding-top: 0.25rem; 595 596 padding-bottom: 0.25rem 597 } 598 .py-1\.5 { 599 600 padding-top: 0.375rem; 601 602 padding-bottom: 0.375rem 603 } 604 .py-2 { 605 606 padding-top: 0.5rem; 607 608 padding-bottom: 0.5rem 609 } 610 .pb-0 { 611 612 padding-bottom: 0px 613 } 426 614 .pt-3 { 427 615 … … 436 624 font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace 437 625 } 626 .text-2xl { 627 628 font-size: 1.5rem; 629 630 line-height: 2rem 631 } 632 .text-3xl { 633 634 font-size: 1.875rem; 635 636 line-height: 2.25rem 637 } 638 .text-\[10px\] { 639 640 font-size: 10px 641 } 438 642 .text-sm { 439 643 … … 448 652 line-height: 1rem 449 653 } 654 .font-bold { 655 656 font-weight: 700 657 } 450 658 .font-medium { 451 659 … … 456 664 font-weight: 600 457 665 } 666 .uppercase { 667 668 text-transform: uppercase 669 } 670 .italic { 671 672 font-style: italic 673 } 674 .leading-none { 675 676 line-height: 1 677 } 678 .tracking-wider { 679 680 letter-spacing: 0.05em 681 } 458 682 .text-blue-800 { 459 683 … … 462 686 color: rgb(30 64 175 / var(--tw-text-opacity, 1)) 463 687 } 688 .text-gray-100 { 689 690 --tw-text-opacity: 1; 691 692 color: rgb(243 244 246 / var(--tw-text-opacity, 1)) 693 } 464 694 .text-gray-400 { 465 695 … … 480 710 color: rgb(55 65 81 / var(--tw-text-opacity, 1)) 481 711 } 712 .text-gray-900 { 713 714 --tw-text-opacity: 1; 715 716 color: rgb(17 24 39 / var(--tw-text-opacity, 1)) 717 } 718 .text-green-500 { 719 720 --tw-text-opacity: 1; 721 722 color: rgb(34 197 94 / var(--tw-text-opacity, 1)) 723 } 724 .text-green-600 { 725 726 --tw-text-opacity: 1; 727 728 color: rgb(22 163 74 / var(--tw-text-opacity, 1)) 729 } 730 .text-green-700 { 731 732 --tw-text-opacity: 1; 733 734 color: rgb(21 128 61 / var(--tw-text-opacity, 1)) 735 } 736 .text-red-400 { 737 738 --tw-text-opacity: 1; 739 740 color: rgb(248 113 113 / var(--tw-text-opacity, 1)) 741 } 742 .text-red-500 { 743 744 --tw-text-opacity: 1; 745 746 color: rgb(239 68 68 / var(--tw-text-opacity, 1)) 747 } 748 .text-red-600 { 749 750 --tw-text-opacity: 1; 751 752 color: rgb(220 38 38 / var(--tw-text-opacity, 1)) 753 } 754 .text-red-700 { 755 756 --tw-text-opacity: 1; 757 758 color: rgb(185 28 28 / var(--tw-text-opacity, 1)) 759 } 760 .text-yellow-500 { 761 762 --tw-text-opacity: 1; 763 764 color: rgb(234 179 8 / var(--tw-text-opacity, 1)) 765 } 766 .text-yellow-700 { 767 768 --tw-text-opacity: 1; 769 770 color: rgb(161 98 7 / var(--tw-text-opacity, 1)) 771 } 772 .opacity-60 { 773 774 opacity: 0.6 775 } 482 776 .filter { 483 777 484 778 filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow) 485 779 } 780 .transition-all { 781 782 transition-property: all; 783 784 transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); 785 786 transition-duration: 150ms 787 } 788 .transition-colors { 789 790 transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; 791 792 transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); 793 794 transition-duration: 150ms 795 } 796 .duration-1000 { 797 798 transition-duration: 1000ms 799 } 800 .ease-out { 801 802 transition-timing-function: cubic-bezier(0, 0, 0.2, 1) 803 } 804 .hover\:bg-blue-600:hover { 805 806 --tw-bg-opacity: 1; 807 808 background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1)) 809 } 810 .hover\:text-white:hover { 811 812 --tw-text-opacity: 1; 813 814 color: rgb(255 255 255 / var(--tw-text-opacity, 1)) 815 } 816 .focus\:outline-none:focus { 817 818 outline: 2px solid transparent; 819 820 outline-offset: 2px 821 } 822 @media (min-width: 640px) { 823 824 .sm\:grid-cols-2 { 825 826 grid-template-columns: repeat(2, minmax(0, 1fr)) 827 } 828 } 829 @media (min-width: 768px) { 830 831 .md\:col-span-2 { 832 833 grid-column: span 2 / span 2 834 } 835 836 .md\:grid-cols-2 { 837 838 grid-template-columns: repeat(2, minmax(0, 1fr)) 839 } 840 841 .md\:flex-row { 842 843 flex-direction: row 844 } 845 } 846 @media (min-width: 1024px) { 847 848 .lg\:col-span-3 { 849 850 grid-column: span 3 / span 3 851 } 852 } 853 @media (prefers-color-scheme: dark) { 854 855 .dark\:border-gray-700 { 856 857 --tw-border-opacity: 1; 858 859 border-color: rgb(55 65 81 / var(--tw-border-opacity, 1)) 860 } 861 862 .dark\:border-gray-800 { 863 864 --tw-border-opacity: 1; 865 866 border-color: rgb(31 41 55 / var(--tw-border-opacity, 1)) 867 } 868 869 .dark\:border-red-800\/50 { 870 871 border-color: rgb(153 27 27 / 0.5) 872 } 873 874 .dark\:bg-red-900\/20 { 875 876 background-color: rgb(127 29 29 / 0.2) 877 } 878 879 .dark\:text-gray-100 { 880 881 --tw-text-opacity: 1; 882 883 color: rgb(243 244 246 / var(--tw-text-opacity, 1)) 884 } 885 886 .dark\:text-gray-300 { 887 888 --tw-text-opacity: 1; 889 890 color: rgb(209 213 219 / var(--tw-text-opacity, 1)) 891 } 892 893 .dark\:text-gray-400 { 894 895 --tw-text-opacity: 1; 896 897 color: rgb(156 163 175 / var(--tw-text-opacity, 1)) 898 } 899 900 .dark\:text-gray-500 { 901 902 --tw-text-opacity: 1; 903 904 color: rgb(107 114 128 / var(--tw-text-opacity, 1)) 905 } 906 907 .dark\:text-gray-800 { 908 909 --tw-text-opacity: 1; 910 911 color: rgb(31 41 55 / var(--tw-text-opacity, 1)) 912 } 913 914 .dark\:text-green-400 { 915 916 --tw-text-opacity: 1; 917 918 color: rgb(74 222 128 / var(--tw-text-opacity, 1)) 919 } 920 921 .dark\:text-red-400 { 922 923 --tw-text-opacity: 1; 924 925 color: rgb(248 113 113 / var(--tw-text-opacity, 1)) 926 } 927 } -
nhrrob-secure/tags/1.3.0/includes/Admin/Api.php
r3441244 r3450292 118 118 'sanitize_callback' => 'absint', 119 119 ], 120 'nhrrob_secure_enable_advanced_firewall' => [ 121 'type' => 'boolean', 122 'sanitize_callback' => 'rest_sanitize_boolean', 123 ], 124 'nhrrob_secure_ip_whitelist' => [ 125 'type' => 'string', 126 'sanitize_callback' => 'sanitize_textarea_field', 127 ], 128 'nhrrob_secure_ip_blacklist' => [ 129 'type' => 'string', 130 'sanitize_callback' => 'sanitize_textarea_field', 131 ], 132 'nhrrob_secure_blocked_countries' => [ 133 'type' => 'array', 134 'items' => [ 135 'type' => 'string', 136 ], 137 'sanitize_callback' => function ($countries) { 138 return is_array($countries) ? array_map('sanitize_text_field', $countries) : []; 139 }, 140 ], 120 141 ], 121 142 ]); … … 227 248 'methods' => 'POST', 228 249 'callback' => [$this, 'destroy_other_sessions'], 250 'permission_callback' => function () { 251 return current_user_can('manage_options'); 252 }, 253 ]); 254 255 // Health check stats 256 register_rest_route('nhrrob-secure/v1', '/health-stats', [ 257 'methods' => 'GET', 258 'callback' => [$this, 'get_health_stats'], 259 'permission_callback' => function () { 260 return current_user_can('manage_options'); 261 }, 262 ]); 263 264 // One-click secure 265 register_rest_route('nhrrob-secure/v1', '/one-click-secure', [ 266 'methods' => 'POST', 267 'callback' => [$this, 'apply_one_click_secure'], 229 268 'permission_callback' => function () { 230 269 return current_user_can('manage_options'); … … 256 295 'nhrrob_secure_firewall_blocked_uas' => get_option('nhrrob_secure_firewall_blocked_uas', ''), 257 296 'nhrrob_secure_idle_timeout' => (int) get_option('nhrrob_secure_idle_timeout', 0), 297 'nhrrob_secure_enable_advanced_firewall' => (bool) get_option('nhrrob_secure_enable_advanced_firewall', false), 298 'nhrrob_secure_ip_whitelist' => get_option('nhrrob_secure_ip_whitelist', ''), 299 'nhrrob_secure_ip_blacklist' => get_option('nhrrob_secure_ip_blacklist', ''), 300 'nhrrob_secure_blocked_countries' => (array) get_option('nhrrob_secure_blocked_countries', []), 258 301 'available_roles' => $this->get_available_roles(), 259 302 ]; … … 430 473 return ['success' => true]; 431 474 } 475 476 /** 477 * Get health stats 478 */ 479 public function get_health_stats() 480 { 481 $health = new \NHRRob\Secure\HealthCheck(); 482 return $health->get_stats(); 483 } 484 485 /** 486 * Apply one-click secure 487 */ 488 public function apply_one_click_secure() 489 { 490 $health = new \NHRRob\Secure\HealthCheck(); 491 $health->apply_one_click_secure(); 492 493 return [ 494 'success' => true, 495 'settings' => $this->get_settings(), 496 'stats' => $health->get_stats(), 497 ]; 498 } 432 499 } -
nhrrob-secure/tags/1.3.0/includes/TwoFactor.php
r3436910 r3450292 26 26 $this->tfa = new \RobThree\Auth\TwoFactorAuth( 27 27 new \RobThree\Auth\Providers\Qr\QRServerProvider(), 28 'NHR Secure'28 get_bloginfo('name') . ' - NHR Secure' 29 29 ); 30 30 … … 78 78 // Generate QR Code URL 79 79 $label = $user->user_email; 80 $issuer = 'NHR Secure';80 $issuer = get_bloginfo('name') . ' - NHR Secure'; 81 81 $otpauth_url = sprintf( 'otpauth://totp/%s:%s?secret=%s&issuer=%s', urlencode( $issuer ), urlencode( $label ), $secret, urlencode( $issuer ) ); 82 82 $qrCodeUrl = sprintf( 'https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=%s', urlencode( $otpauth_url ) ); -
nhrrob-secure/tags/1.3.0/nhrrob-secure.php
r3441244 r3450292 6 6 * Author: Nazmul Hasan Robin 7 7 * Author URI: https://profiles.wordpress.org/nhrrob/ 8 * Version: 1. 2.08 * Version: 1.3.0 9 9 * Requires at least: 6.0 10 10 * Requires PHP: 7.4 … … 31 31 * @var string 32 32 */ 33 const version = '1. 2.0';33 const version = '1.3.0'; 34 34 35 35 /** … … 106 106 new \NHRRob\Secure\Hardening(); 107 107 108 // Initialize advanced firewall (IPS) 109 new \NHRRob\Secure\Firewall(); 110 111 // Initialize IP & Country manager 112 new \NHRRob\Secure\IPManager(); 113 108 114 // Initialize session manager 109 115 new \NHRRob\Secure\SessionManager(); -
nhrrob-secure/tags/1.3.0/readme.txt
r3441244 r3450292 5 5 Tested up to: 6.9 6 6 Requires PHP: 7.4 7 Stable tag: 1. 2.07 Stable tag: 1.3.0 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 19 19 - Add 2FA to your WordPress site. 20 20 - Scan core files, plugins, and themes for known vulnerabilities. 21 - Monitor site health with one-click security recommendations. 22 - Protect against SQL injection, XSS, and LFI attacks. 23 - Block malicious IPs and entire countries. 21 24 22 25 ### **Features at a glance:** … … 75 78 - View user, IP, and event details. 76 79 - Configurable log retention policy. 80 81 ### 🏥 Security Health Check & One-Click Secure 82 Get an instant overview of your site's security posture. 83 - **Security Score:** View your overall protection percentage and grade (A+ to F). 84 - **Health Dashboard:** See which security features are active and which need attention. 85 - **One-Click Secure:** Apply recommended security settings instantly. 86 - **11 Security Checks:** Comprehensive analysis of your security status. 87 88 ### 🛡️ Advanced Firewall (IPS) 89 Proactive intrusion prevention system that blocks malicious requests in real-time. 90 - **SQL Injection Protection:** Detect and block SQLi attacks automatically. 91 - **XSS Prevention:** Stop cross-site scripting attempts. 92 - **LFI Protection:** Prevent local file inclusion attacks. 93 - **Pattern Matching:** Advanced regex-based detection for common attack vectors. 94 - **Automatic Blocking:** Suspicious requests are blocked before they reach WordPress. 95 96 ### 🌍 IP & Country Management 97 Control access to your site with granular IP and geographic filtering. 98 - **IP Whitelist:** Allow trusted IPs to bypass all security filters. 99 - **IP Blacklist:** Block malicious IPs permanently from your site. 100 - **CIDR Support:** Use CIDR notation for blocking entire IP ranges (e.g., 192.168.1.0/24). 101 - **Country Blocking:** Block access from 90+ countries using GeoIP lookup. 102 - **Smart Caching:** GeoIP lookups are cached for 24 hours for optimal performance. 103 - **Private IP Detection:** Automatically skip local/private IPs. 77 104 78 105 ### ⚡ Lightweight & Minimal … … 124 151 == Changelog == 125 152 153 = 1.3.0 - 28/01/2026 = 154 - Added: Security Health Check with scoring system (A+ to F grade) 155 - Added: One-Click Secure feature to apply recommended settings instantly 156 - Added: Advanced Firewall (IPS) with real-time protection against SQL Injection, XSS, and LFI attacks 157 - Added: IP Management with Whitelist and Blacklist (CIDR support) 158 - Added: Country Blocking for 90+ countries using GeoIP lookup with caching 159 - Improved: Dark mode styling for all components 160 - Improved: Overall security dashboard UI/UX 161 126 162 = 1.2.0 - 17/01/2026 = 127 163 - Added: User Session Management (View active sessions, remote logout, idle timeout) -
nhrrob-secure/trunk/assets/src/components/Hardening.js
r3441244 r3450292 43 43 <h3 className="nhrrob-secure-setting-subtitle">{__('Firewall Rules', 'nhrrob-secure')}</h3> 44 44 45 <ToggleControl 46 label={__('Advanced Firewall (IPS) Protection', 'nhrrob-secure')} 47 help={__('Proactively block common attacks like SQL Injection, XSS, and LFI by scanning request data.', 'nhrrob-secure')} 48 checked={settings?.nhrrob_secure_enable_advanced_firewall || false} 49 onChange={(value) => updateSetting('nhrrob_secure_enable_advanced_firewall', value)} 50 /> 51 45 52 <TextareaControl 46 53 label={__('Block User Agents', 'nhrrob-secure')} -
nhrrob-secure/trunk/assets/src/components/SessionManager.js
r3441244 r3450292 133 133 isDestructive 134 134 onClick={destroyOtherSessions} 135 className=" w-full justify-center"135 className="justify-center h-auto py-2 text-xs" 136 136 > 137 137 {__('Log Out All Other Devices', 'nhrrob-secure')} -
nhrrob-secure/trunk/assets/src/index.js
r3441244 r3450292 16 16 import SessionManager from './components/SessionManager'; 17 17 import AuditLog from './components/AuditLog'; 18 import HealthCheck from './components/HealthCheck'; 19 import IPManager from './components/IPManager'; 18 20 import './style.css'; 19 21 … … 124 126 125 127 <div className="nhrrob-secure-cards"> 126 <LoginProtection settings={settings} updateSetting={updateSetting} /> 127 <CustomLoginPage settings={settings} updateSetting={updateSetting} /> 128 <TwoFactorAuth settings={settings} updateSetting={updateSetting} /> 129 <Hardening settings={settings} updateSetting={updateSetting} /> 130 <FileProtection settings={settings} updateSetting={updateSetting} /> 131 <VulnerabilityChecker /> 132 <FileScanner /> 133 <SessionManager settings={settings} updateSetting={updateSetting} /> 134 <AuditLog settings={settings} updateSetting={updateSetting} /> 128 <div className="md:col-span-2 lg:col-span-3"> 129 <HealthCheck onApplyOneClick={(newSettings) => setSettings(newSettings)} /> 130 </div> 131 <div className="md:col-span-2 lg:col-span-3"> 132 <LoginProtection settings={settings} updateSetting={updateSetting} /> 133 </div> 134 <div className="md:col-span-2 lg:col-span-3"> 135 <CustomLoginPage settings={settings} updateSetting={updateSetting} /> 136 </div> 137 <div className="md:col-span-2 lg:col-span-3"> 138 <TwoFactorAuth settings={settings} updateSetting={updateSetting} /> 139 </div> 140 <div className="md:col-span-2 lg:col-span-3"> 141 <Hardening settings={settings} updateSetting={updateSetting} /> 142 </div> 143 <div className="md:col-span-2 lg:col-span-3"> 144 <FileProtection settings={settings} updateSetting={updateSetting} /> 145 </div> 146 <div className="md:col-span-2 lg:col-span-3"> 147 <VulnerabilityChecker /> 148 </div> 149 <div className="md:col-span-2 lg:col-span-3"> 150 <IPManager settings={settings} updateSetting={updateSetting} /> 151 </div> 152 <div className="md:col-span-2 lg:col-span-3"> 153 <FileScanner /> 154 </div> 155 <div className="md:col-span-2 lg:col-span-3"> 156 <SessionManager settings={settings} updateSetting={updateSetting} /> 157 </div> 158 <div className="md:col-span-2 lg:col-span-3"> 159 <AuditLog settings={settings} updateSetting={updateSetting} /> 160 </div> 135 161 </div> 136 162 -
nhrrob-secure/trunk/assets/src/style.css
r3441244 r3450292 83 83 84 84 .nhrrob-secure-cards { 85 @apply grid g ap-5 mb-6;85 @apply grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5 mb-6; 86 86 } 87 87 … … 124 124 .dark-mode .components-placeholder__instructions, 125 125 .dark-mode .nhrrob-secure-2fa-method h3, 126 .dark-mode .nhrrob-secure-enforced-roles h3 { 126 .dark-mode .nhrrob-secure-enforced-roles h3, 127 .dark-mode .nhrrob-secure-ip-card h3, 128 .dark-mode .nhrrob-secure-ip-card .components-base-control__label, 129 .dark-mode .nhrrob-secure-country-select label { 127 130 color: var(--nhrrob-secure-text) !important; 128 131 } 129 132 133 . 130 134 .dark-mode .components-placeholder { 131 135 background-color: var(--nhrrob-secure-vuln-bg) !important; … … 135 139 136 140 .dark-mode .components-text-control__input, 137 .dark-mode .components-textarea-control__input { 141 .dark-mode .components-textarea-control__input, 142 .dark-mode .components-select-control__input { 143 background-color: #2c3338 !important; 144 border-color: #43494e !important; 145 color: #f0f0f1 !important; 146 } 147 148 /* IP Manager SelectControl specific styling */ 149 .dark-mode .nhrrob-secure-ip-card .components-select-control__input { 138 150 background-color: #2c3338 !important; 139 151 border-color: #43494e !important; … … 265 277 266 278 .nhrrob-scan-controls { 267 @apply flex items-center gap-4; 279 @apply flex items-center gap-4 shrink-0; 280 } 281 282 .nhrrob-scan-controls .components-button { 283 @apply flex items-center justify-center gap-2 px-4 py-2 h-auto !important; 284 } 285 286 .nhrrob-scan-controls .components-button .dashicon { 287 @apply static m-0 !important; 268 288 } 269 289 … … 332 352 333 353 .nhrrob-result-list { 334 @apply divide-y ;354 @apply divide-y overflow-y-auto max-h-[400px]; 335 355 } 336 356 -
nhrrob-secure/trunk/build/admin.asset.php
r3441244 r3450292 1 <?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-components', 'wp-element', 'wp-html-entities', 'wp-i18n'), 'version' => ' 876f03e1a6accd816f8d');1 <?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-components', 'wp-element', 'wp-html-entities', 'wp-i18n'), 'version' => 'd12ca91feb6f2445566e'); -
nhrrob-secure/trunk/build/admin.css
r3441244 r3450292 116 116 margin-bottom: 1.5rem; 117 117 display: grid; 118 grid-template-columns: repeat(1, minmax(0, 1fr)); 118 119 gap: 1.25rem; 120 } 121 122 @media (min-width: 768px) { 123 124 .nhrrob-secure-cards { 125 grid-template-columns: repeat(2, minmax(0, 1fr)); 126 } 127 } 128 129 @media (min-width: 1024px) { 130 131 .nhrrob-secure-cards { 132 grid-template-columns: repeat(3, minmax(0, 1fr)); 133 } 119 134 } 120 135 … … 177 192 .dark-mode .components-placeholder__instructions, 178 193 .dark-mode .nhrrob-secure-2fa-method h3, 179 .dark-mode .nhrrob-secure-enforced-roles h3 { 194 .dark-mode .nhrrob-secure-enforced-roles h3, 195 .dark-mode .nhrrob-secure-ip-card h3, 196 .dark-mode .nhrrob-secure-ip-card .components-base-control__label, 197 .dark-mode .nhrrob-secure-country-select label { 180 198 color: var(--nhrrob-secure-text) !important; 181 199 } 182 200 201 . 183 202 .dark-mode .components-placeholder { 184 203 background-color: var(--nhrrob-secure-vuln-bg) !important; … … 188 207 189 208 .dark-mode .components-text-control__input, 190 .dark-mode .components-textarea-control__input { 209 .dark-mode .components-textarea-control__input, 210 .dark-mode .components-select-control__input { 211 background-color: #2c3338 !important; 212 border-color: #43494e !important; 213 color: #f0f0f1 !important; 214 } 215 216 /* IP Manager SelectControl specific styling */ 217 .dark-mode .nhrrob-secure-ip-card .components-select-control__input { 191 218 background-color: #2c3338 !important; 192 219 border-color: #43494e !important; … … 371 398 .nhrrob-scan-controls { 372 399 display: flex; 400 flex-shrink: 0; 373 401 align-items: center; 374 402 gap: 1rem; 403 } 404 405 .nhrrob-scan-controls .components-button { 406 display: flex !important; 407 height: auto !important; 408 align-items: center !important; 409 justify-content: center !important; 410 gap: 0.5rem !important; 411 padding-left: 1rem !important; 412 padding-right: 1rem !important; 413 padding-top: 0.5rem !important; 414 padding-bottom: 0.5rem !important; 415 } 416 417 .nhrrob-scan-controls .components-button .dashicon { 418 position: static !important; 419 margin: 0px !important; 375 420 } 376 421 … … 518 563 } 519 564 565 .nhrrob-result-list { 566 max-height: 400px; 567 } 568 520 569 .nhrrob-result-list > :not([hidden]) ~ :not([hidden]) { 521 570 --tw-divide-y-reverse: 0; 522 571 border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse))); 523 572 border-bottom-width: calc(1px * var(--tw-divide-y-reverse)); 573 } 574 575 .nhrrob-result-list { 576 overflow-y: auto; 524 577 } 525 578 … … 605 658 border-color: var(--nhrrob-secure-border); 606 659 } 660 .absolute { 661 position: absolute; 662 } 663 .relative { 664 position: relative; 665 } 666 .-mr-0\.5 { 667 margin-right: -0.125rem; 668 } 607 669 .mb-2 { 608 670 margin-bottom: 0.5rem; … … 614 676 margin-bottom: 1rem; 615 677 } 678 .mb-6 { 679 margin-bottom: 1.5rem; 680 } 616 681 .ml-2 { 617 682 margin-left: 0.5rem; … … 623 688 margin-top: 0px; 624 689 } 690 .mt-0\.5 { 691 margin-top: 0.125rem; 692 } 625 693 .mt-1 { 626 694 margin-top: 0.25rem; … … 629 697 margin-top: 1rem; 630 698 } 699 .mt-8 { 700 margin-top: 2rem; 701 } 631 702 .block { 632 703 display: block; … … 644 715 display: none; 645 716 } 717 .h-32 { 718 height: 8rem; 719 } 720 .h-auto { 721 height: auto; 722 } 723 .h-full { 724 height: 100%; 725 } 726 .w-32 { 727 width: 8rem; 728 } 646 729 .w-64 { 647 730 width: 16rem; … … 650 733 width: 100%; 651 734 } 735 .max-w-xs { 736 max-width: 20rem; 737 } 738 .flex-1 { 739 flex: 1 1 0%; 740 } 741 .-rotate-90 { 742 --tw-rotate: -90deg; 743 transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); 744 } 745 .transform { 746 transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); 747 } 748 .cursor-pointer { 749 cursor: pointer; 750 } 751 .grid-cols-1 { 752 grid-template-columns: repeat(1, minmax(0, 1fr)); 753 } 652 754 .grid-cols-2 { 653 755 grid-template-columns: repeat(2, minmax(0, 1fr)); 654 756 } 757 .flex-col { 758 flex-direction: column; 759 } 760 .flex-wrap { 761 flex-wrap: wrap; 762 } 655 763 .items-start { 656 764 align-items: flex-start; 657 765 } 766 .items-end { 767 align-items: flex-end; 768 } 769 .items-center { 770 align-items: center; 771 } 658 772 .justify-center { 659 773 justify-content: center; … … 662 776 justify-content: space-between; 663 777 } 778 .gap-1 { 779 gap: 0.25rem; 780 } 664 781 .gap-2 { 665 782 gap: 0.5rem; 783 } 784 .gap-3 { 785 gap: 0.75rem; 786 } 787 .gap-4 { 788 gap: 1rem; 789 } 790 .gap-6 { 791 gap: 1.5rem; 792 } 793 .gap-8 { 794 gap: 2rem; 666 795 } 667 796 .truncate { … … 676 805 border-radius: 9999px; 677 806 } 807 .rounded-lg { 808 border-radius: 0.5rem; 809 } 678 810 .border { 679 811 border-width: 1px; 680 812 } 813 .border-0 { 814 border-width: 0px; 815 } 816 .border-b { 817 border-bottom-width: 1px; 818 } 681 819 .border-t { 682 820 border-top-width: 1px; 821 } 822 .border-none { 823 border-style: none; 683 824 } 684 825 .border-blue-200 { … … 694 835 border-color: rgb(229 231 235 / var(--tw-border-opacity, 1)); 695 836 } 837 .border-red-200 { 838 --tw-border-opacity: 1; 839 border-color: rgb(254 202 202 / var(--tw-border-opacity, 1)); 840 } 696 841 .bg-blue-100 { 697 842 --tw-bg-opacity: 1; … … 705 850 --tw-bg-opacity: 1; 706 851 background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1)); 852 } 853 .bg-green-100 { 854 --tw-bg-opacity: 1; 855 background-color: rgb(220 252 231 / var(--tw-bg-opacity, 1)); 856 } 857 .bg-red-100 { 858 --tw-bg-opacity: 1; 859 background-color: rgb(254 226 226 / var(--tw-bg-opacity, 1)); 860 } 861 .bg-red-50 { 862 --tw-bg-opacity: 1; 863 background-color: rgb(254 242 242 / var(--tw-bg-opacity, 1)); 864 } 865 .bg-yellow-100 { 866 --tw-bg-opacity: 1; 867 background-color: rgb(254 249 195 / var(--tw-bg-opacity, 1)); 868 } 869 .p-0\.5 { 870 padding: 0.125rem; 707 871 } 708 872 .p-3 { 709 873 padding: 0.75rem; 874 } 875 .p-5 { 876 padding: 1.25rem; 877 } 878 .p-6 { 879 padding: 1.5rem; 710 880 } 711 881 .px-2 { … … 713 883 padding-right: 0.5rem; 714 884 } 885 .px-3 { 886 padding-left: 0.75rem; 887 padding-right: 0.75rem; 888 } 715 889 .py-0\.5 { 716 890 padding-top: 0.125rem; 717 891 padding-bottom: 0.125rem; 718 892 } 893 .py-1 { 894 padding-top: 0.25rem; 895 padding-bottom: 0.25rem; 896 } 897 .py-1\.5 { 898 padding-top: 0.375rem; 899 padding-bottom: 0.375rem; 900 } 901 .py-2 { 902 padding-top: 0.5rem; 903 padding-bottom: 0.5rem; 904 } 905 .pb-0 { 906 padding-bottom: 0px; 907 } 719 908 .pt-3 { 720 909 padding-top: 0.75rem; … … 725 914 .font-mono { 726 915 font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 916 } 917 .text-2xl { 918 font-size: 1.5rem; 919 line-height: 2rem; 920 } 921 .text-3xl { 922 font-size: 1.875rem; 923 line-height: 2.25rem; 924 } 925 .text-\[10px\] { 926 font-size: 10px; 727 927 } 728 928 .text-sm { … … 734 934 line-height: 1rem; 735 935 } 936 .font-bold { 937 font-weight: 700; 938 } 736 939 .font-medium { 737 940 font-weight: 500; … … 740 943 font-weight: 600; 741 944 } 945 .uppercase { 946 text-transform: uppercase; 947 } 948 .italic { 949 font-style: italic; 950 } 951 .leading-none { 952 line-height: 1; 953 } 954 .tracking-wider { 955 letter-spacing: 0.05em; 956 } 742 957 .text-blue-800 { 743 958 --tw-text-opacity: 1; 744 959 color: rgb(30 64 175 / var(--tw-text-opacity, 1)); 745 960 } 961 .text-gray-100 { 962 --tw-text-opacity: 1; 963 color: rgb(243 244 246 / var(--tw-text-opacity, 1)); 964 } 746 965 .text-gray-400 { 747 966 --tw-text-opacity: 1; … … 755 974 --tw-text-opacity: 1; 756 975 color: rgb(55 65 81 / var(--tw-text-opacity, 1)); 976 } 977 .text-gray-900 { 978 --tw-text-opacity: 1; 979 color: rgb(17 24 39 / var(--tw-text-opacity, 1)); 980 } 981 .text-green-500 { 982 --tw-text-opacity: 1; 983 color: rgb(34 197 94 / var(--tw-text-opacity, 1)); 984 } 985 .text-green-600 { 986 --tw-text-opacity: 1; 987 color: rgb(22 163 74 / var(--tw-text-opacity, 1)); 988 } 989 .text-green-700 { 990 --tw-text-opacity: 1; 991 color: rgb(21 128 61 / var(--tw-text-opacity, 1)); 992 } 993 .text-red-400 { 994 --tw-text-opacity: 1; 995 color: rgb(248 113 113 / var(--tw-text-opacity, 1)); 996 } 997 .text-red-500 { 998 --tw-text-opacity: 1; 999 color: rgb(239 68 68 / var(--tw-text-opacity, 1)); 1000 } 1001 .text-red-600 { 1002 --tw-text-opacity: 1; 1003 color: rgb(220 38 38 / var(--tw-text-opacity, 1)); 1004 } 1005 .text-red-700 { 1006 --tw-text-opacity: 1; 1007 color: rgb(185 28 28 / var(--tw-text-opacity, 1)); 1008 } 1009 .text-yellow-500 { 1010 --tw-text-opacity: 1; 1011 color: rgb(234 179 8 / var(--tw-text-opacity, 1)); 1012 } 1013 .text-yellow-700 { 1014 --tw-text-opacity: 1; 1015 color: rgb(161 98 7 / var(--tw-text-opacity, 1)); 1016 } 1017 .opacity-60 { 1018 opacity: 0.6; 757 1019 } 758 1020 .filter { 759 1021 filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); 1022 } 1023 .transition-all { 1024 transition-property: all; 1025 transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); 1026 transition-duration: 150ms; 1027 } 1028 .transition-colors { 1029 transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; 1030 transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); 1031 transition-duration: 150ms; 1032 } 1033 .duration-1000 { 1034 transition-duration: 1000ms; 1035 } 1036 .ease-out { 1037 transition-timing-function: cubic-bezier(0, 0, 0.2, 1); 760 1038 } 761 1039 … … 923 1201 border-left-color: rgb(220 38 38 / var(--tw-border-opacity, 1)); 924 1202 } 1203 1204 @media (prefers-color-scheme: dark) { 1205 1206 .dark-mode .session-item .dark\:text-gray-500 { 1207 color: var(--nhrrob-secure-text-muted) !important; 1208 } 1209 } 1210 1211 .hover\:bg-blue-600:hover { 1212 --tw-bg-opacity: 1; 1213 background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1)); 1214 } 1215 1216 .hover\:text-white:hover { 1217 --tw-text-opacity: 1; 1218 color: rgb(255 255 255 / var(--tw-text-opacity, 1)); 1219 } 1220 1221 .focus\:outline-none:focus { 1222 outline: 2px solid transparent; 1223 outline-offset: 2px; 1224 } 1225 1226 @media (min-width: 640px) { 1227 1228 .sm\:grid-cols-2 { 1229 grid-template-columns: repeat(2, minmax(0, 1fr)); 1230 } 1231 } 1232 1233 @media (min-width: 768px) { 1234 1235 .md\:col-span-2 { 1236 grid-column: span 2 / span 2; 1237 } 1238 1239 .md\:grid-cols-2 { 1240 grid-template-columns: repeat(2, minmax(0, 1fr)); 1241 } 1242 1243 .md\:flex-row { 1244 flex-direction: row; 1245 } 1246 } 1247 1248 @media (min-width: 1024px) { 1249 1250 .lg\:col-span-3 { 1251 grid-column: span 3 / span 3; 1252 } 1253 } 1254 1255 @media (prefers-color-scheme: dark) { 1256 1257 .dark\:border-gray-700 { 1258 --tw-border-opacity: 1; 1259 border-color: rgb(55 65 81 / var(--tw-border-opacity, 1)); 1260 } 1261 1262 .dark\:border-gray-800 { 1263 --tw-border-opacity: 1; 1264 border-color: rgb(31 41 55 / var(--tw-border-opacity, 1)); 1265 } 1266 1267 .dark\:border-red-800\/50 { 1268 border-color: rgb(153 27 27 / 0.5); 1269 } 1270 1271 .dark\:bg-red-900\/20 { 1272 background-color: rgb(127 29 29 / 0.2); 1273 } 1274 1275 .dark\:text-gray-100 { 1276 --tw-text-opacity: 1; 1277 color: rgb(243 244 246 / var(--tw-text-opacity, 1)); 1278 } 1279 1280 .dark\:text-gray-300 { 1281 --tw-text-opacity: 1; 1282 color: rgb(209 213 219 / var(--tw-text-opacity, 1)); 1283 } 1284 1285 .dark\:text-gray-400 { 1286 --tw-text-opacity: 1; 1287 color: rgb(156 163 175 / var(--tw-text-opacity, 1)); 1288 } 1289 1290 .dark\:text-gray-500 { 1291 --tw-text-opacity: 1; 1292 color: rgb(107 114 128 / var(--tw-text-opacity, 1)); 1293 } 1294 1295 .dark\:text-gray-800 { 1296 --tw-text-opacity: 1; 1297 color: rgb(31 41 55 / var(--tw-text-opacity, 1)); 1298 } 1299 1300 .dark\:text-green-400 { 1301 --tw-text-opacity: 1; 1302 color: rgb(74 222 128 / var(--tw-text-opacity, 1)); 1303 } 1304 1305 .dark\:text-red-400 { 1306 --tw-text-opacity: 1; 1307 color: rgb(248 113 113 / var(--tw-text-opacity, 1)); 1308 } 1309 } -
nhrrob-secure/trunk/build/admin.js
r3441244 r3450292 1 (()=>{"use strict";var e,r={ 195(e,r,t){const n=window.React,s=window.wp.element,a=window.wp.components,l=window.wp.i18n,c=window.wp.apiFetch;var o=t.n(c);const i=({settings:e,updateSetting:r})=>(0,n.createElement)(a.Card,{className:"nhrrob-secure-card"},(0,n.createElement)(a.CardBody,null,(0,n.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,l.__)("Login Protection","nhrrob-secure")),(0,n.createElement)(a.ToggleControl,{label:(0,l.__)("Enable Login Attempts Limit","nhrrob-secure"),help:(0,l.__)("Limit failed login attempts to prevent brute force attacks","nhrrob-secure"),checked:e.nhrrob_secure_limit_login_attempts,onChange:e=>r("nhrrob_secure_limit_login_attempts",e)}),e.nhrrob_secure_limit_login_attempts&&(0,n.createElement)(a.TextControl,{label:(0,l.__)("Maximum Login Attempts","nhrrob-secure"),help:(0,l.__)("Number of failed attempts before blocking (default: 5)","nhrrob-secure"),type:"number",value:e.nhrrob_secure_login_attempts_limit,onChange:e=>r("nhrrob_secure_login_attempts_limit",parseInt(e)||5),min:"1",max:"20"}),(0,n.createElement)(a.ToggleControl,{label:(0,l.__)("Enable Proxy IP Detection","nhrrob-secure"),help:(0,l.__)("Detect real IP behind proxies (Cloudflare, etc.)","nhrrob-secure"),checked:e.nhrrob_secure_enable_proxy_ip,onChange:e=>r("nhrrob_secure_enable_proxy_ip",e)}))),u=({settings:e,updateSetting:r})=>(0,n.createElement)(a.Card,{className:"nhrrob-secure-card"},(0,n.createElement)(a.CardBody,null,(0,n.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,l.__)("Custom Login Page","nhrrob-secure")),(0,n.createElement)(a.ToggleControl,{label:(0,l.__)("Enable Custom Login URL","nhrrob-secure"),help:(0,l.__)("Hide wp-login.php and use a custom login URL","nhrrob-secure"),checked:e.nhrrob_secure_custom_login_page,onChange:e=>r("nhrrob_secure_custom_login_page",e)}),e.nhrrob_secure_custom_login_page&&(0,n.createElement)(a.TextControl,{label:(0,l.__)("Custom Login URL","nhrrob-secure"),help:(0,l.__)("Your login page will be accessible at this URL","nhrrob-secure"),value:e.nhrrob_secure_custom_login_url,onChange:e=>r("nhrrob_secure_custom_login_url",e),placeholder:"/hidden-access-52w"}),e.nhrrob_secure_custom_login_page&&(0,n.createElement)("div",{className:"nhrrob-secure-info"},(0,n.createElement)("strong",null,(0,l.__)("Your login URL:","nhrrob-secure")),(0,n.createElement)("code",null,window.location.origin,e.nhrrob_secure_custom_login_url)))),m=({settings:e,updateSetting:r})=>{const t=e.nhrrob_secure_2fa_enforced_roles||[],s=e.available_roles||[];return(0,n.createElement)(a.Card,{className:"nhrrob-secure-card"},(0,n.createElement)(a.CardBody,null,(0,n.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,l.__)("Two-Factor Authentication","nhrrob-secure")),(0,n.createElement)(a.ToggleControl,{label:(0,l.__)("Enable Global 2FA","nhrrob-secure"),help:(0,n.createElement)(n.Fragment,null,(0,l.__)("Enables Google Authenticator support for all users. Users can set it up in their ","nhrrob-secure"),(0,n.createElement)("a",{href:nhrrobSecureSettings.profile_url,target:"_blank",rel:"noreferrer"},(0,l.__)("profile page","nhrrob-secure")),"."),checked:e.nhrrob_secure_enable_2fa,onChange:e=>r("nhrrob_secure_enable_2fa",e)}),e.nhrrob_secure_enable_2fa&&(0,n.createElement)(n.Fragment,null,(0,n.createElement)("div",{className:"nhrrob-secure-2fa-method pt-4 border-t border-gray-100"},(0,n.createElement)("h3",{className:"text-sm font-semibold mb-3"},(0,l.__)("2FA Method","nhrrob-secure")),(0,n.createElement)(a.RadioControl,{selected:e.nhrrob_secure_2fa_type||"app",options:[{label:(0,l.__)("Authenticator App (Recommended)","nhrrob-secure"),value:"app"},{label:(0,l.__)("Email OTP","nhrrob-secure"),value:"email"}],onChange:e=>r("nhrrob_secure_2fa_type",e)})),(0,n.createElement)("div",{className:"nhrrob-secure-enforced-roles pt-4 border-t border-gray-100"},(0,n.createElement)("h3",{className:"text-sm font-semibold mb-3"},(0,l.__)("Enforced 2FA by Role","nhrrob-secure")),(0,n.createElement)("p",{className:"text-xs text-gray-500 mb-4"},(0,l.__)("Users with the selected roles will be forced to set up 2FA before they can access the admin dashboard.","nhrrob-secure")),(0,n.createElement)("div",{className:"grid grid-cols-2 gap-2"},s.map(e=>(0,n.createElement)(a.CheckboxControl,{key:e.value,label:e.label,checked:t.includes(e.value),onChange:n=>((e,n)=>{const s=n?[...t,e]:t.filter(r=>r!==e);r("nhrrob_secure_2fa_enforced_roles",s)})(e.value,n)})))))))},h=({settings:e,updateSetting:r})=>(0,n.createElement)(a.Card,{className:"nhrrob-secure-card"},(0,n.createElement)(a.CardBody,null,(0,n.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,l.__)("File Protection","nhrrob-secure")),(0,n.createElement)(a.ToggleControl,{label:(0,l.__)("Protect Debug Log","nhrrob-secure"),help:(0,l.__)("Block direct access to wp-content/debug.log","nhrrob-secure"),checked:e.nhrrob_secure_protect_debug_log,onChange:e=>r("nhrrob_secure_protect_debug_log",e)}))),d=window.wp.htmlEntities,b=()=>{const[e,r]=(0,s.useState)(null),[t,c]=(0,s.useState)(!0),[i,u]=(0,s.useState)(!1),[m,h]=(0,s.useState)(null);(0,s.useEffect)(()=>{b()},[]);const b=async()=>{try{const e=await o()({path:"/nhrrob-secure/v1/vulnerability/status"});r(e),c(!1)}catch(e){h((0,l.__)("Failed to fetch vulnerability status","nhrrob-secure")),c(!1)}};if(t)return(0,n.createElement)(a.Card,{className:"nhrrob-secure-card"},(0,n.createElement)(a.CardBody,null,(0,n.createElement)(a.Spinner,null)));const _=e&&(e.core.length>0||e.plugins.length>0||e.themes.length>0);return(0,n.createElement)(a.Card,{className:"nhrrob-secure-card nhrrob-secure-vulnerability-card"},(0,n.createElement)(a.CardBody,null,(0,n.createElement)("div",{className:"nhrrob-secure-card-header-flex"},(0,n.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,l.__)("Vulnerability Checker","nhrrob-secure")),(0,n.createElement)(a.Button,{variant:"primary",onClick:async()=>{u(!0),h(null);try{const e=await o()({path:"/nhrrob-secure/v1/vulnerability/scan",method:"POST"});r(e)}catch(e){h((0,l.__)("Failed to run vulnerability scan","nhrrob-secure"))}finally{u(!1)}},isBusy:i,disabled:i,icon:"update",iconPosition:"right"},i?(0,l.__)("Scanning...","nhrrob-secure"):(0,l.__)("Scan Now","nhrrob-secure"))),(0,n.createElement)("p",{className:"nhrrob-secure-last-scan"},(0,n.createElement)("strong",null,(0,l.__)("Last Scan:","nhrrob-secure"))," ",(g=e.last_scan)?new Date(1e3*g).toLocaleString():(0,l.__)("Never","nhrrob-secure")),m&&(0,n.createElement)(a.Notice,{status:"error",isDismissible:!1},m),_?(0,n.createElement)("div",{className:"nhrrob-secure-vulnerability-list"},(0,n.createElement)(a.Notice,{status:"warning",isDismissible:!1},(0,l.__)("Vulnerabilities detected! Please review and update the items below.","nhrrob-secure")),e.core.length>0&&(0,n.createElement)("div",{className:"vulnerability-section"},(0,n.createElement)("h3",null,(0,l.__)("WordPress Core","nhrrob-secure")),(0,n.createElement)("ul",null,e.core.map((e,r)=>(0,n.createElement)("li",{key:r},(0,d.decodeEntities)(e.name))))),e.plugins.length>0&&(0,n.createElement)("div",{className:"vulnerability-section"},(0,n.createElement)("h3",null,(0,l.__)("Plugins","nhrrob-secure")),e.plugins.map((e,r)=>(0,n.createElement)("div",{key:r,className:"vulnerability-item"},(0,n.createElement)("strong",null,(0,n.createElement)("a",{href:"plugins.php",style:{textDecoration:"none",color:"inherit"}},(0,d.decodeEntities)(e.name)),(0,n.createElement)("span",{style:{fontWeight:"normal",color:"#666"}}," (",e.version,")")),(0,n.createElement)("ul",null,e.vulnerabilities.map((e,r)=>(0,n.createElement)("li",{key:r},(0,d.decodeEntities)(e.name))))))),e.themes.length>0&&(0,n.createElement)("div",{className:"vulnerability-section"},(0,n.createElement)("h3",null,(0,l.__)("Themes","nhrrob-secure")),e.themes.map((e,r)=>(0,n.createElement)("div",{key:r,className:"vulnerability-item"},(0,n.createElement)("strong",null,(0,d.decodeEntities)(e.name)," (",e.version,")"),(0,n.createElement)("ul",null,e.vulnerabilities.map((e,r)=>(0,n.createElement)("li",{key:r},(0,d.decodeEntities)(e.name)))))))):(0,n.createElement)("div",{className:"nhrrob-secure-status-success"},(0,n.createElement)("span",{className:"dashicons dashicons-yes-alt"}),(0,l.__)("No known vulnerabilities detected.","nhrrob-secure"))));var g},_=()=>{const[e,r]=(0,s.useState)(!1),[t,c]=(0,s.useState)(null),[i,u]=(0,s.useState)(null),[m,h]=(0,s.useState)("core"),d=async()=>{r(!0),u(null),c(null);try{const e="core"===m?"/nhrrob-secure/v1/scanner/core":"/nhrrob-secure/v1/scanner/malware",r=await o()({path:e,method:"POST"});c(r)}catch(e){u(e.message||(0,l.__)("An error occurred during scan.","nhrrob-secure"))}finally{r(!1)}};return(0,n.createElement)("div",{className:"nhrrob-secure-card nhrrob-secure-vulnerability-card padded-header"},(0,n.createElement)("div",{className:"nhrrob-secure-card-header-flex"},(0,n.createElement)("div",{className:"nhrrob-secure-header-content"},(0,n.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,l.__)("File Scanner","nhrrob-secure")),(0,n.createElement)("p",{className:"nhrrob-secure-card-subtitle"},(0,l.__)("Scan your site for file modifications and potential malware.","nhrrob-secure"))),(0,n.createElement)("div",{className:"nhrrob-scan-controls"},(0,n.createElement)("div",{className:"nhrrob-scan-type-toggle"},(0,n.createElement)("button",{className:"nhrrob-scan-toggle-btn "+("core"===m?"active":""),onClick:()=>h("core"),disabled:e},(0,l.__)("Core Integrity","nhrrob-secure")),(0,n.createElement)("button",{className:"nhrrob-scan-toggle-btn "+("malware"===m?"active":""),onClick:()=>h("malware"),disabled:e},(0,l.__)("Malware Scan","nhrrob-secure"))),(0,n.createElement)(a.Button,{variant:"primary",onClick:()=>d(),isBusy:e,disabled:e,icon:"update",iconPosition:"right"},e?(0,l.__)("Scanning...","nhrrob-secure"):(0,l.__)("Start Scan","nhrrob-secure")))),(0,n.createElement)("div",{className:"nhrrob-card-body"},i&&(0,n.createElement)("div",{className:"notice notice-error inline-notice"},(0,n.createElement)("p",null,i)),t&&(0,n.createElement)("div",{className:"nhrrob-secure-vulnerability-list"},("core"===m&&(t.modified?.length>0||t.missing?.length>0)||"malware"===m&&t.suspicious?.length>0)&&(0,n.createElement)("div",{className:"notice notice-warning inline-notice nhrrob-warning-notice"},(0,n.createElement)("p",null,(0,l.__)("Issues detected! Please review and update the items below.","nhrrob-secure"))),"core"===m&&(0,n.createElement)(n.Fragment,null,t.modified&&t.modified.length>0&&(0,n.createElement)("div",{className:"nhrrob-result-group"},(0,n.createElement)("h3",{className:"nhrrob-result-group-title"},(0,l.__)("Modified Core Files","nhrrob-secure")),(0,n.createElement)("div",{className:"nhrrob-result-list"},t.modified.map((e,r)=>(0,n.createElement)("div",{key:r,className:"nhrrob-result-row"},(0,n.createElement)("div",{className:"nhrrob-file-info"},(0,n.createElement)("strong",null,e)),(0,n.createElement)(a.Button,{variant:"secondary",isSmall:!0,onClick:()=>(async e=>{if(confirm((0,l.__)("Are you sure you want to repair this file? It will be overwritten with the original version.","nhrrob-secure")))try{await o()({path:"/nhrrob-secure/v1/scanner/repair",method:"POST",data:{file:e}}),alert((0,l.__)("File repaired successfully.","nhrrob-secure")),d()}catch(e){alert(e.message||(0,l.__)("Repair failed.","nhrrob-secure"))}})(e)},(0,l.__)("Repair","nhrrob-secure")))))),t.missing&&t.missing.length>0&&(0,n.createElement)("div",{className:"nhrrob-result-group"},(0,n.createElement)("h3",{className:"nhrrob-result-group-title"},(0,l.__)("Missing Core Files","nhrrob-secure")),(0,n.createElement)("div",{className:"nhrrob-result-list"},t.missing.map((e,r)=>(0,n.createElement)("div",{key:r,className:"nhrrob-result-row"},(0,n.createElement)("div",{className:"nhrrob-file-info"},(0,n.createElement)("strong",null,e)))))),!t.modified?.length&&!t.missing?.length&&(0,n.createElement)("div",{className:"nhrrob-secure-status-success"},(0,n.createElement)("span",{className:"dashicons dashicons-yes-alt"}),(0,l.__)("No modified core files found.","nhrrob-secure"))),"malware"===m&&(0,n.createElement)(n.Fragment,null,t.suspicious&&t.suspicious.length>0?(0,n.createElement)("div",{className:"nhrrob-result-group"},(0,n.createElement)("h3",{className:"nhrrob-result-group-title"},(0,l.__)("Suspicious Files","nhrrob-secure")),(0,n.createElement)("div",{className:"nhrrob-result-list"},t.suspicious.map((e,r)=>(0,n.createElement)("div",{key:r,className:"nhrrob-result-row"},(0,n.createElement)("div",{className:"nhrrob-file-info"},(0,n.createElement)("strong",null,e.file),(0,n.createElement)("span",{className:"nhrrob-file-meta"},e.reason)),(0,n.createElement)(a.Button,{variant:"link",isDestructive:!0,onClick:()=>(async e=>{if(confirm((0,l.__)("Are you sure you want to PERMANENTLY delete this file?","nhrrob-secure")))try{await o()({path:"/nhrrob-secure/v1/scanner/delete",method:"POST",data:{file:e}}),alert((0,l.__)("File deleted successfully.","nhrrob-secure")),d()}catch(e){alert(e.message||(0,l.__)("Delete failed.","nhrrob-secure"))}})(e.file)},(0,l.__)("Delete","nhrrob-secure")))))):(0,n.createElement)("div",{className:"nhrrob-secure-status-success"},(0,n.createElement)("span",{className:"dashicons dashicons-yes-alt"}),(0,l.__)("No suspicious files found.","nhrrob-secure")),(0,n.createElement)("p",{className:"description nhrrob-scan-count"},(0,n.createElement)("small",null,(0,l.__)("Scanned files:","nhrrob-secure")," ",t.scanned_count))))))},g=({settings:e,updateSetting:r})=>(0,n.createElement)(a.Card,{className:"nhrrob-secure-card nhrrob-secure-hardening-card"},(0,n.createElement)(a.CardBody,null,(0,n.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,l.__)("Hardening & Firewall","nhrrob-secure")),(0,n.createElement)("div",{className:"nhrrob-secure-setting-group"},(0,n.createElement)("h3",{className:"nhrrob-secure-setting-subtitle"},(0,l.__)("General Hardening","nhrrob-secure")),(0,n.createElement)(a.ToggleControl,{label:(0,l.__)("Disable XML-RPC","nhrrob-secure"),help:(0,l.__)("Prevents external systems (like mobile apps and Jetpack) from accessing your site via XML-RPC. Recommended if not used.","nhrrob-secure"),checked:e.nhrrob_secure_disable_xmlrpc,onChange:e=>r("nhrrob_secure_disable_xmlrpc",e)}),(0,n.createElement)(a.ToggleControl,{label:(0,l.__)("Disable File Editor","nhrrob-secure"),help:(0,l.__)("Disables the built-in theme and plugin file editor to prevent code execution if an admin account is compromised.","nhrrob-secure"),checked:e.nhrrob_secure_disable_file_editor,onChange:e=>r("nhrrob_secure_disable_file_editor",e)}),(0,n.createElement)(a.ToggleControl,{label:(0,l.__)("Hide WP Version","nhrrob-secure"),help:(0,l.__)("Removes WordPress version from page source and RSS feeds to make reconnaissance harder for attackers.","nhrrob-secure"),checked:e.nhrrob_secure_hide_wp_version,onChange:e=>r("nhrrob_secure_hide_wp_version",e)}),(0,n.createElement)(a.ToggleControl,{label:(0,l.__)("Disable REST API User Enumeration","nhrrob-secure"),help:(0,l.__)("Blocks access to /wp-json/wp/v2/users to prevent attackers from listing your users.","nhrrob-secure"),checked:e.nhrrob_secure_disable_rest_users,onChange:e=>r("nhrrob_secure_disable_rest_users",e)})),(0,n.createElement)("div",{className:"nhrrob-secure-setting-group border-t border-gray-100 pt-4 mt-4"},(0,n.createElement)("h3",{className:"nhrrob-secure-setting-subtitle"},(0,l.__)("Firewall Rules","nhrrob-secure")),(0,n.createElement)(a.TextareaControl,{label:(0,l.__)("Block User Agents","nhrrob-secure"),help:(0,l.__)('Enter one User-Agent per line to block. Case-insensitive partial match. Example: "HTTrack", "curl".',"nhrrob-secure"),value:e.nhrrob_secure_firewall_blocked_uas,onChange:e=>r("nhrrob_secure_firewall_blocked_uas",e),rows:5,placeholder:"SemrushBot\nAhrefsBot\nMJ12bot"})))),E=({settings:e,updateSetting:r})=>{const[t,c]=(0,s.useState)([]),[i,u]=(0,s.useState)(!1),[m,h]=(0,s.useState)(null);(0,s.useEffect)(()=>{d()},[]);const d=async()=>{u(!0),h(null);try{const e=await o()({path:"/nhrrob-secure/v1/sessions"});c(e)}catch(e){h(e.message||(0,l.__)("Failed to load sessions.","nhrrob-secure"))}finally{u(!1)}};return(0,n.createElement)(a.Card,{className:"nhrrob-secure-card nhrrob-secure-sessions-card"},(0,n.createElement)(a.CardBody,null,(0,n.createElement)("div",{className:"nhrrob-secure-card-header-flex"},(0,n.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,l.__)("User Session Management","nhrrob-secure")),(0,n.createElement)(a.Button,{variant:"primary",onClick:d,isBusy:i,disabled:i,icon:"update"},(0,l.__)("Refresh","nhrrob-secure"))),(0,n.createElement)("div",{className:"nhrrob-secure-setting-group"},(0,n.createElement)(a.TextControl,{label:(0,l.__)("Idle Timeout (Minutes)","nhrrob-secure"),help:(0,l.__)("Automatically log out inactive users after X minutes. Set to 0 to disable.","nhrrob-secure"),type:"number",value:e?.nhrrob_secure_idle_timeout||0,onChange:e=>r("nhrrob_secure_idle_timeout",parseInt(e)||0),min:"0"})),m&&(0,n.createElement)(a.Notice,{status:"error",isDismissible:!1},m),(0,n.createElement)("div",{className:"nhrrob-secure-sessions-list mt-4"},(0,n.createElement)("h3",{className:"text-sm font-semibold mb-3"},(0,l.__)("Active Sessions","nhrrob-secure")),0!==t.length||i?(0,n.createElement)("div",{className:"sessions-grid"},t.map((e,r)=>(0,n.createElement)("div",{key:r,className:"session-item p-3 border rounded mb-2 "+(e.is_current?"bg-blue-50 border-blue-200":"bg-gray-50 border-gray-200")},(0,n.createElement)("div",{className:"flex justify-between items-start"},(0,n.createElement)("div",{className:"session-info"},(0,n.createElement)("div",{className:"font-medium text-gray-700"},e.ip,e.is_current&&(0,n.createElement)("span",{className:"ml-2 px-2 py-0.5 text-xs bg-blue-100 text-blue-800 rounded-full"},(0,l.__)("Current Session","nhrrob-secure"))),(0,n.createElement)("div",{className:"text-xs text-gray-500 mt-1"},(0,n.createElement)("div",null,(0,l.__)("Login:","nhrrob-secure")," ",new Date(1e3*e.login).toLocaleString()),(0,n.createElement)("div",null,(0,l.__)("Expires:","nhrrob-secure")," ",new Date(1e3*e.expiration).toLocaleString()),(0,n.createElement)("div",{className:"mt-1 font-mono text-gray-400 truncate w-64",title:e.ua},e.ua))),!e.is_current&&(0,n.createElement)(a.Button,{variant:"link",isDestructive:!0,onClick:()=>(async e=>{if(confirm((0,l.__)("Are you sure you want to log out this session?","nhrrob-secure")))try{await o()({path:"/nhrrob-secure/v1/sessions/destroy",method:"POST",data:{verifier:e}}),d()}catch(e){alert(e.message||(0,l.__)("Failed to destroy session.","nhrrob-secure"))}})(e.verifier)},(0,l.__)("Logout","nhrrob-secure")))))):(0,n.createElement)("p",null,(0,l.__)("No active sessions found.","nhrrob-secure"))),t.length>1&&(0,n.createElement)("div",{className:"mt-4 pt-3 border-t"},(0,n.createElement)(a.Button,{variant:"secondary",isDestructive:!0,onClick:async()=>{if(confirm((0,l.__)("Are you sure you want to log out all other devices?","nhrrob-secure")))try{await o()({path:"/nhrrob-secure/v1/sessions/destroy-others",method:"POST"}),d(),alert((0,l.__)("All other sessions logged out.","nhrrob-secure"))}catch(e){alert(e.message||(0,l.__)("Failed to destroy sessions.","nhrrob-secure"))}},className:"w-full justify-center"},(0,l.__)("Log Out All Other Devices","nhrrob-secure")))))},p=({settings:e,updateSetting:r})=>{const[t,c]=(0,s.useState)([]),[i,u]=(0,s.useState)(!0),[m,h]=(0,s.useState)(0),[d,b]=(0,s.useState)(1);(0,s.useEffect)(()=>{_()},[d]);const _=async()=>{u(!0);try{const e=20*(d-1),r=await o()({path:`/nhrrob-secure/v1/logs?limit=20&offset=${e}`});c(r.items),h(r.total)}catch(e){console.error(e)}finally{u(!1)}},g=Math.ceil(m/20);return(0,n.createElement)(a.Card,{className:"nhrrob-secure-card nhrrob-secure-audit-log-card"},(0,n.createElement)(a.CardBody,null,(0,n.createElement)("div",{className:"nhrrob-secure-card-header-flex"},(0,n.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,l.__)("Activity Audit Log","nhrrob-secure")),(0,n.createElement)("div",{className:"nhrrob-secure-card-header-actions"},e&&(0,n.createElement)(a.SelectControl,{className:"nhrrob-secure-retention-select",value:e.nhrrob_secure_log_retention_days,options:[{label:(0,l.__)("Keep logs: 7 days","nhrrob-secure"),value:7},{label:(0,l.__)("Keep logs: 30 days","nhrrob-secure"),value:30},{label:(0,l.__)("Keep logs: 90 days","nhrrob-secure"),value:90},{label:(0,l.__)("Keep logs: 1 year","nhrrob-secure"),value:365}],onChange:e=>r("nhrrob_secure_log_retention_days",parseInt(e))}),(0,n.createElement)(a.Button,{variant:"primary",onClick:_,disabled:i,isBusy:i,icon:"update",iconPosition:"right"},(0,l.__)("Refresh","nhrrob-secure")))),i&&(0,n.createElement)("div",{className:"nhrrob-secure-loading-overlay"},(0,n.createElement)(a.Spinner,null)),(0,n.createElement)("div",{className:"nhrrob-secure-audit-table-wrapper"},(0,n.createElement)("table",{className:"nhrrob-secure-audit-table"},(0,n.createElement)("thead",null,(0,n.createElement)("tr",null,(0,n.createElement)("th",null,(0,l.__)("Date","nhrrob-secure")),(0,n.createElement)("th",null,(0,l.__)("User","nhrrob-secure")),(0,n.createElement)("th",null,(0,l.__)("Context","nhrrob-secure")),(0,n.createElement)("th",null,(0,l.__)("Action","nhrrob-secure")),(0,n.createElement)("th",null,(0,l.__)("Item","nhrrob-secure")),(0,n.createElement)("th",null,(0,l.__)("IP Address","nhrrob-secure")))),(0,n.createElement)("tbody",null,t.length>0?t.map(e=>(0,n.createElement)("tr",{key:e.id,className:`severity-${e.severity}`},(0,n.createElement)("td",null,new Date(e.date).toLocaleString()),(0,n.createElement)("td",null,e.user),(0,n.createElement)("td",null,(0,n.createElement)("span",{className:"nhrrob-secure-badge"},e.context)),(0,n.createElement)("td",null,e.action),(0,n.createElement)("td",null,e.label),(0,n.createElement)("td",null,e.ip))):(0,n.createElement)("tr",null,(0,n.createElement)("td",{colSpan:"6",className:"no-logs"},!i&&(0,l.__)("No activity logs found.","nhrrob-secure")))))),g>1&&(0,n.createElement)("div",{className:"nhrrob-secure-pagination"},(0,n.createElement)(a.Button,{isSmall:!0,disabled:1===d||i,onClick:()=>b(d-1)},"« ",(0,l.__)("Prev","nhrrob-secure")),(0,n.createElement)("span",{className:"nhrrob-secure-page-info"},(0,l.__)("Page","nhrrob-secure")," ",d," ",(0,l.__)("of","nhrrob-secure")," ",g),(0,n.createElement)(a.Button,{isSmall:!0,disabled:d===g||i,onClick:()=>b(d+1)},(0,l.__)("Next","nhrrob-secure")," »"))))},v=document.getElementById("nhrrob-secure-settings-root");v&&(0,s.render)((0,n.createElement)(()=>{const[e,r]=(0,s.useState)(null),[t,c]=(0,s.useState)(!0),[d,v]=(0,s.useState)(!1),[y,f]=(0,s.useState)(null);(0,s.useEffect)(()=>{N()},[]);const N=async()=>{try{const e=await o()({path:"/nhrrob-secure/v1/settings"});r(e),c(!1)}catch(e){f({type:"error",message:(0,l.__)("Failed to load settings","nhrrob-secure")}),c(!1)}},w=(t,n)=>{r({...e,[t]:n})};return(0,s.useEffect)(()=>{e?.nhrrob_secure_dark_mode?document.body.classList.add("nhrrob-secure-dark-mode-active"):document.body.classList.remove("nhrrob-secure-dark-mode-active")},[e?.nhrrob_secure_dark_mode]),t?(0,n.createElement)("div",{className:"nhrrob-secure-loading"},(0,n.createElement)(a.Spinner,null)):(0,n.createElement)("div",{className:"nhrrob-secure-settings "+(e.nhrrob_secure_dark_mode?"dark-mode":"")},(0,n.createElement)("div",{className:"nhrrob-secure-header"},(0,n.createElement)("div",{className:"nhrrob-secure-header-main"},(0,n.createElement)("h1",null,(0,l.__)("NHR Secure Settings","nhrrob-secure")),(0,n.createElement)(a.Button,{className:"nhrrob-secure-dark-mode-toggle",icon:e.nhrrob_secure_dark_mode?(0,n.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",width:"20",height:"20"},(0,n.createElement)("path",{d:"M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zM2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1zm18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1zM11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1zm0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1zM5.99 4.58a.996.996 0 00-1.41 0 .996.996 0 000 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41L5.99 4.58zm12.37 12.37a.996.996 0 00-1.41 0 .996.996 0 000 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41l-1.06-1.06zm1.06-10.96a.996.996 0 00-1.41-1.41l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06zM7.05 18.36a.996.996 0 00-1.41-1.41l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06z"})):(0,n.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",width:"20",height:"20"},(0,n.createElement)("path",{d:"M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-.46-.04-.92-.1-1.36-.98 1.37-2.58 2.26-4.4 2.26-2.98 0-5.4-2.42-5.4-5.4 0-1.81.89-3.42 2.26-4.4-.44-.06-.9-.1-1.36-.1z"})),onClick:async()=>{const r=!e.nhrrob_secure_dark_mode;w("nhrrob_secure_dark_mode",r);try{await o()({path:"/nhrrob-secure/v1/settings",method:"POST",data:{...e,nhrrob_secure_dark_mode:r}})}catch(e){console.error("Failed to save dark mode preference",e)}},label:(0,l.__)("Toggle Dark Mode","nhrrob-secure")})),(0,n.createElement)("p",{className:"nhrrob-secure-subtitle"},(0,l.__)("Configure security features for your WordPress site","nhrrob-secure"))),y&&(0,n.createElement)(a.Notice,{status:y.type,isDismissible:!0,onRemove:()=>f(null)},y.message),(0,n.createElement)("div",{className:"nhrrob-secure-cards"},(0,n.createElement)(i,{settings:e,updateSetting:w}),(0,n.createElement)(u,{settings:e,updateSetting:w}),(0,n.createElement)(m,{settings:e,updateSetting:w}),(0,n.createElement)(g,{settings:e,updateSetting:w}),(0,n.createElement)(h,{settings:e,updateSetting:w}),(0,n.createElement)(b,null),(0,n.createElement)(_,null),(0,n.createElement)(E,{settings:e,updateSetting:w}),(0,n.createElement)(p,{settings:e,updateSetting:w})),(0,n.createElement)("div",{className:"nhrrob-secure-actions"},(0,n.createElement)(a.Button,{variant:"primary",onClick:async()=>{v(!0),f(null);try{await o()({path:"/nhrrob-secure/v1/settings",method:"POST",data:e}),f({type:"success",message:(0,l.__)("Settings saved successfully!","nhrrob-secure")})}catch(e){f({type:"error",message:(0,l.__)("Failed to save settings","nhrrob-secure")})}finally{v(!1)}},isBusy:d,disabled:d},d?(0,l.__)("Saving...","nhrrob-secure"):(0,l.__)("Save Settings","nhrrob-secure"))))},null),v)}},t={};function n(e){var s=t[e];if(void 0!==s)return s.exports;var a=t[e]={exports:{}};return r[e](a,a.exports,n),a.exports}n.m=r,e=[],n.O=(r,t,s,a)=>{if(!t){var l=1/0;for(u=0;u<e.length;u++){for(var[t,s,a]=e[u],c=!0,o=0;o<t.length;o++)(!1&a||l>=a)&&Object.keys(n.O).every(e=>n.O[e](t[o]))?t.splice(o--,1):(c=!1,a<l&&(l=a));if(c){e.splice(u--,1);var i=s();void 0!==i&&(r=i)}}return r}a=a||0;for(var u=e.length;u>0&&e[u-1][2]>a;u--)e[u]=e[u-1];e[u]=[t,s,a]},n.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return n.d(r,{a:r}),r},n.d=(e,r)=>{for(var t in r)n.o(r,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},n.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),(()=>{var e={884:0,15:0};n.O.j=r=>0===e[r];var r=(r,t)=>{var s,a,[l,c,o]=t,i=0;if(l.some(r=>0!==e[r])){for(s in c)n.o(c,s)&&(n.m[s]=c[s]);if(o)var u=o(n)}for(r&&r(t);i<l.length;i++)a=l[i],n.o(e,a)&&e[a]&&e[a][0](),e[a]=0;return n.O(u)},t=globalThis.webpackChunknhrrob_secure=globalThis.webpackChunknhrrob_secure||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})();var s=n.O(void 0,[15],()=>n(195));s=n.O(s)})();1 (()=>{"use strict";var e,r={855(e,r,t){const a=window.React,l=window.wp.element,n=window.wp.components,s=window.wp.i18n,c=window.wp.apiFetch;var o=t.n(c);const i=({settings:e,updateSetting:r})=>(0,a.createElement)(n.Card,{className:"nhrrob-secure-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("Login Protection","nhrrob-secure")),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Enable Login Attempts Limit","nhrrob-secure"),help:(0,s.__)("Limit failed login attempts to prevent brute force attacks","nhrrob-secure"),checked:e.nhrrob_secure_limit_login_attempts,onChange:e=>r("nhrrob_secure_limit_login_attempts",e)}),e.nhrrob_secure_limit_login_attempts&&(0,a.createElement)(n.TextControl,{label:(0,s.__)("Maximum Login Attempts","nhrrob-secure"),help:(0,s.__)("Number of failed attempts before blocking (default: 5)","nhrrob-secure"),type:"number",value:e.nhrrob_secure_login_attempts_limit,onChange:e=>r("nhrrob_secure_login_attempts_limit",parseInt(e)||5),min:"1",max:"20"}),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Enable Proxy IP Detection","nhrrob-secure"),help:(0,s.__)("Detect real IP behind proxies (Cloudflare, etc.)","nhrrob-secure"),checked:e.nhrrob_secure_enable_proxy_ip,onChange:e=>r("nhrrob_secure_enable_proxy_ip",e)}))),u=({settings:e,updateSetting:r})=>(0,a.createElement)(n.Card,{className:"nhrrob-secure-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("Custom Login Page","nhrrob-secure")),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Enable Custom Login URL","nhrrob-secure"),help:(0,s.__)("Hide wp-login.php and use a custom login URL","nhrrob-secure"),checked:e.nhrrob_secure_custom_login_page,onChange:e=>r("nhrrob_secure_custom_login_page",e)}),e.nhrrob_secure_custom_login_page&&(0,a.createElement)(n.TextControl,{label:(0,s.__)("Custom Login URL","nhrrob-secure"),help:(0,s.__)("Your login page will be accessible at this URL","nhrrob-secure"),value:e.nhrrob_secure_custom_login_url,onChange:e=>r("nhrrob_secure_custom_login_url",e),placeholder:"/hidden-access-52w"}),e.nhrrob_secure_custom_login_page&&(0,a.createElement)("div",{className:"nhrrob-secure-info"},(0,a.createElement)("strong",null,(0,s.__)("Your login URL:","nhrrob-secure")),(0,a.createElement)("code",null,window.location.origin,e.nhrrob_secure_custom_login_url)))),m=({settings:e,updateSetting:r})=>{const t=e.nhrrob_secure_2fa_enforced_roles||[],l=e.available_roles||[];return(0,a.createElement)(n.Card,{className:"nhrrob-secure-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("Two-Factor Authentication","nhrrob-secure")),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Enable Global 2FA","nhrrob-secure"),help:(0,a.createElement)(a.Fragment,null,(0,s.__)("Enables Google Authenticator support for all users. Users can set it up in their ","nhrrob-secure"),(0,a.createElement)("a",{href:nhrrobSecureSettings.profile_url,target:"_blank",rel:"noreferrer"},(0,s.__)("profile page","nhrrob-secure")),"."),checked:e.nhrrob_secure_enable_2fa,onChange:e=>r("nhrrob_secure_enable_2fa",e)}),e.nhrrob_secure_enable_2fa&&(0,a.createElement)(a.Fragment,null,(0,a.createElement)("div",{className:"nhrrob-secure-2fa-method pt-4 border-t border-gray-100"},(0,a.createElement)("h3",{className:"text-sm font-semibold mb-3"},(0,s.__)("2FA Method","nhrrob-secure")),(0,a.createElement)(n.RadioControl,{selected:e.nhrrob_secure_2fa_type||"app",options:[{label:(0,s.__)("Authenticator App (Recommended)","nhrrob-secure"),value:"app"},{label:(0,s.__)("Email OTP","nhrrob-secure"),value:"email"}],onChange:e=>r("nhrrob_secure_2fa_type",e)})),(0,a.createElement)("div",{className:"nhrrob-secure-enforced-roles pt-4 border-t border-gray-100"},(0,a.createElement)("h3",{className:"text-sm font-semibold mb-3"},(0,s.__)("Enforced 2FA by Role","nhrrob-secure")),(0,a.createElement)("p",{className:"text-xs text-gray-500 mb-4"},(0,s.__)("Users with the selected roles will be forced to set up 2FA before they can access the admin dashboard.","nhrrob-secure")),(0,a.createElement)("div",{className:"grid grid-cols-2 gap-2"},l.map(e=>(0,a.createElement)(n.CheckboxControl,{key:e.value,label:e.label,checked:t.includes(e.value),onChange:a=>((e,a)=>{const l=a?[...t,e]:t.filter(r=>r!==e);r("nhrrob_secure_2fa_enforced_roles",l)})(e.value,a)})))))))},b=({settings:e,updateSetting:r})=>(0,a.createElement)(n.Card,{className:"nhrrob-secure-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("File Protection","nhrrob-secure")),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Protect Debug Log","nhrrob-secure"),help:(0,s.__)("Block direct access to wp-content/debug.log","nhrrob-secure"),checked:e.nhrrob_secure_protect_debug_log,onChange:e=>r("nhrrob_secure_protect_debug_log",e)}))),d=window.wp.htmlEntities,h=()=>{const[e,r]=(0,l.useState)(null),[t,c]=(0,l.useState)(!0),[i,u]=(0,l.useState)(!1),[m,b]=(0,l.useState)(null);(0,l.useEffect)(()=>{h()},[]);const h=async()=>{try{const e=await o()({path:"/nhrrob-secure/v1/vulnerability/status"});r(e),c(!1)}catch(e){b((0,s.__)("Failed to fetch vulnerability status","nhrrob-secure")),c(!1)}};if(t)return(0,a.createElement)(n.Card,{className:"nhrrob-secure-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)(n.Spinner,null)));const _=e&&(e.core.length>0||e.plugins.length>0||e.themes.length>0);return(0,a.createElement)(n.Card,{className:"nhrrob-secure-card nhrrob-secure-vulnerability-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)("div",{className:"nhrrob-secure-card-header-flex"},(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("Vulnerability Checker","nhrrob-secure")),(0,a.createElement)(n.Button,{variant:"primary",onClick:async()=>{u(!0),b(null);try{const e=await o()({path:"/nhrrob-secure/v1/vulnerability/scan",method:"POST"});r(e)}catch(e){b((0,s.__)("Failed to run vulnerability scan","nhrrob-secure"))}finally{u(!1)}},isBusy:i,disabled:i,icon:"update",iconPosition:"right"},i?(0,s.__)("Scanning...","nhrrob-secure"):(0,s.__)("Scan Now","nhrrob-secure"))),(0,a.createElement)("p",{className:"nhrrob-secure-last-scan"},(0,a.createElement)("strong",null,(0,s.__)("Last Scan:","nhrrob-secure"))," ",(g=e.last_scan)?new Date(1e3*g).toLocaleString():(0,s.__)("Never","nhrrob-secure")),m&&(0,a.createElement)(n.Notice,{status:"error",isDismissible:!1},m),_?(0,a.createElement)("div",{className:"nhrrob-secure-vulnerability-list"},(0,a.createElement)(n.Notice,{status:"warning",isDismissible:!1},(0,s.__)("Vulnerabilities detected! Please review and update the items below.","nhrrob-secure")),e.core.length>0&&(0,a.createElement)("div",{className:"vulnerability-section"},(0,a.createElement)("h3",null,(0,s.__)("WordPress Core","nhrrob-secure")),(0,a.createElement)("ul",null,e.core.map((e,r)=>(0,a.createElement)("li",{key:r},(0,d.decodeEntities)(e.name))))),e.plugins.length>0&&(0,a.createElement)("div",{className:"vulnerability-section"},(0,a.createElement)("h3",null,(0,s.__)("Plugins","nhrrob-secure")),e.plugins.map((e,r)=>(0,a.createElement)("div",{key:r,className:"vulnerability-item"},(0,a.createElement)("strong",null,(0,a.createElement)("a",{href:"plugins.php",style:{textDecoration:"none",color:"inherit"}},(0,d.decodeEntities)(e.name)),(0,a.createElement)("span",{style:{fontWeight:"normal",color:"#666"}}," (",e.version,")")),(0,a.createElement)("ul",null,e.vulnerabilities.map((e,r)=>(0,a.createElement)("li",{key:r},(0,d.decodeEntities)(e.name))))))),e.themes.length>0&&(0,a.createElement)("div",{className:"vulnerability-section"},(0,a.createElement)("h3",null,(0,s.__)("Themes","nhrrob-secure")),e.themes.map((e,r)=>(0,a.createElement)("div",{key:r,className:"vulnerability-item"},(0,a.createElement)("strong",null,(0,d.decodeEntities)(e.name)," (",e.version,")"),(0,a.createElement)("ul",null,e.vulnerabilities.map((e,r)=>(0,a.createElement)("li",{key:r},(0,d.decodeEntities)(e.name)))))))):(0,a.createElement)("div",{className:"nhrrob-secure-status-success"},(0,a.createElement)("span",{className:"dashicons dashicons-yes-alt"}),(0,s.__)("No known vulnerabilities detected.","nhrrob-secure"))));var g},_=()=>{const[e,r]=(0,l.useState)(!1),[t,c]=(0,l.useState)(null),[i,u]=(0,l.useState)(null),[m,b]=(0,l.useState)("core"),d=async()=>{r(!0),u(null),c(null);try{const e="core"===m?"/nhrrob-secure/v1/scanner/core":"/nhrrob-secure/v1/scanner/malware",r=await o()({path:e,method:"POST"});c(r)}catch(e){u(e.message||(0,s.__)("An error occurred during scan.","nhrrob-secure"))}finally{r(!1)}};return(0,a.createElement)("div",{className:"nhrrob-secure-card nhrrob-secure-vulnerability-card padded-header"},(0,a.createElement)("div",{className:"nhrrob-secure-card-header-flex"},(0,a.createElement)("div",{className:"nhrrob-secure-header-content"},(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("File Scanner","nhrrob-secure")),(0,a.createElement)("p",{className:"nhrrob-secure-card-subtitle"},(0,s.__)("Scan your site for file modifications and potential malware.","nhrrob-secure"))),(0,a.createElement)("div",{className:"nhrrob-scan-controls"},(0,a.createElement)("div",{className:"nhrrob-scan-type-toggle"},(0,a.createElement)("button",{className:"nhrrob-scan-toggle-btn "+("core"===m?"active":""),onClick:()=>b("core"),disabled:e},(0,s.__)("Core Integrity","nhrrob-secure")),(0,a.createElement)("button",{className:"nhrrob-scan-toggle-btn "+("malware"===m?"active":""),onClick:()=>b("malware"),disabled:e},(0,s.__)("Malware Scan","nhrrob-secure"))),(0,a.createElement)(n.Button,{variant:"primary",onClick:()=>d(),isBusy:e,disabled:e,icon:"update",iconPosition:"right"},e?(0,s.__)("Scanning...","nhrrob-secure"):(0,s.__)("Start Scan","nhrrob-secure")))),(0,a.createElement)("div",{className:"nhrrob-card-body"},i&&(0,a.createElement)("div",{className:"notice notice-error inline-notice"},(0,a.createElement)("p",null,i)),t&&(0,a.createElement)("div",{className:"nhrrob-secure-vulnerability-list"},("core"===m&&(t.modified?.length>0||t.missing?.length>0)||"malware"===m&&t.suspicious?.length>0)&&(0,a.createElement)("div",{className:"notice notice-warning inline-notice nhrrob-warning-notice"},(0,a.createElement)("p",null,(0,s.__)("Issues detected! Please review and update the items below.","nhrrob-secure"))),"core"===m&&(0,a.createElement)(a.Fragment,null,t.modified&&t.modified.length>0&&(0,a.createElement)("div",{className:"nhrrob-result-group"},(0,a.createElement)("h3",{className:"nhrrob-result-group-title"},(0,s.__)("Modified Core Files","nhrrob-secure")),(0,a.createElement)("div",{className:"nhrrob-result-list"},t.modified.map((e,r)=>(0,a.createElement)("div",{key:r,className:"nhrrob-result-row"},(0,a.createElement)("div",{className:"nhrrob-file-info"},(0,a.createElement)("strong",null,e)),(0,a.createElement)(n.Button,{variant:"secondary",isSmall:!0,onClick:()=>(async e=>{if(confirm((0,s.__)("Are you sure you want to repair this file? It will be overwritten with the original version.","nhrrob-secure")))try{await o()({path:"/nhrrob-secure/v1/scanner/repair",method:"POST",data:{file:e}}),alert((0,s.__)("File repaired successfully.","nhrrob-secure")),d()}catch(e){alert(e.message||(0,s.__)("Repair failed.","nhrrob-secure"))}})(e)},(0,s.__)("Repair","nhrrob-secure")))))),t.missing&&t.missing.length>0&&(0,a.createElement)("div",{className:"nhrrob-result-group"},(0,a.createElement)("h3",{className:"nhrrob-result-group-title"},(0,s.__)("Missing Core Files","nhrrob-secure")),(0,a.createElement)("div",{className:"nhrrob-result-list"},t.missing.map((e,r)=>(0,a.createElement)("div",{key:r,className:"nhrrob-result-row"},(0,a.createElement)("div",{className:"nhrrob-file-info"},(0,a.createElement)("strong",null,e)))))),!t.modified?.length&&!t.missing?.length&&(0,a.createElement)("div",{className:"nhrrob-secure-status-success"},(0,a.createElement)("span",{className:"dashicons dashicons-yes-alt"}),(0,s.__)("No modified core files found.","nhrrob-secure"))),"malware"===m&&(0,a.createElement)(a.Fragment,null,t.suspicious&&t.suspicious.length>0?(0,a.createElement)("div",{className:"nhrrob-result-group"},(0,a.createElement)("h3",{className:"nhrrob-result-group-title"},(0,s.__)("Suspicious Files","nhrrob-secure")),(0,a.createElement)("div",{className:"nhrrob-result-list"},t.suspicious.map((e,r)=>(0,a.createElement)("div",{key:r,className:"nhrrob-result-row"},(0,a.createElement)("div",{className:"nhrrob-file-info"},(0,a.createElement)("strong",null,e.file),(0,a.createElement)("span",{className:"nhrrob-file-meta"},e.reason)),(0,a.createElement)(n.Button,{variant:"link",isDestructive:!0,onClick:()=>(async e=>{if(confirm((0,s.__)("Are you sure you want to PERMANENTLY delete this file?","nhrrob-secure")))try{await o()({path:"/nhrrob-secure/v1/scanner/delete",method:"POST",data:{file:e}}),alert((0,s.__)("File deleted successfully.","nhrrob-secure")),d()}catch(e){alert(e.message||(0,s.__)("Delete failed.","nhrrob-secure"))}})(e.file)},(0,s.__)("Delete","nhrrob-secure")))))):(0,a.createElement)("div",{className:"nhrrob-secure-status-success"},(0,a.createElement)("span",{className:"dashicons dashicons-yes-alt"}),(0,s.__)("No suspicious files found.","nhrrob-secure")),(0,a.createElement)("p",{className:"description nhrrob-scan-count"},(0,a.createElement)("small",null,(0,s.__)("Scanned files:","nhrrob-secure")," ",t.scanned_count))))))},g=({settings:e,updateSetting:r})=>(0,a.createElement)(n.Card,{className:"nhrrob-secure-card nhrrob-secure-hardening-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("Hardening & Firewall","nhrrob-secure")),(0,a.createElement)("div",{className:"nhrrob-secure-setting-group"},(0,a.createElement)("h3",{className:"nhrrob-secure-setting-subtitle"},(0,s.__)("General Hardening","nhrrob-secure")),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Disable XML-RPC","nhrrob-secure"),help:(0,s.__)("Prevents external systems (like mobile apps and Jetpack) from accessing your site via XML-RPC. Recommended if not used.","nhrrob-secure"),checked:e.nhrrob_secure_disable_xmlrpc,onChange:e=>r("nhrrob_secure_disable_xmlrpc",e)}),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Disable File Editor","nhrrob-secure"),help:(0,s.__)("Disables the built-in theme and plugin file editor to prevent code execution if an admin account is compromised.","nhrrob-secure"),checked:e.nhrrob_secure_disable_file_editor,onChange:e=>r("nhrrob_secure_disable_file_editor",e)}),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Hide WP Version","nhrrob-secure"),help:(0,s.__)("Removes WordPress version from page source and RSS feeds to make reconnaissance harder for attackers.","nhrrob-secure"),checked:e.nhrrob_secure_hide_wp_version,onChange:e=>r("nhrrob_secure_hide_wp_version",e)}),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Disable REST API User Enumeration","nhrrob-secure"),help:(0,s.__)("Blocks access to /wp-json/wp/v2/users to prevent attackers from listing your users.","nhrrob-secure"),checked:e.nhrrob_secure_disable_rest_users,onChange:e=>r("nhrrob_secure_disable_rest_users",e)})),(0,a.createElement)("div",{className:"nhrrob-secure-setting-group border-t border-gray-100 pt-4 mt-4"},(0,a.createElement)("h3",{className:"nhrrob-secure-setting-subtitle"},(0,s.__)("Firewall Rules","nhrrob-secure")),(0,a.createElement)(n.ToggleControl,{label:(0,s.__)("Advanced Firewall (IPS) Protection","nhrrob-secure"),help:(0,s.__)("Proactively block common attacks like SQL Injection, XSS, and LFI by scanning request data.","nhrrob-secure"),checked:e?.nhrrob_secure_enable_advanced_firewall||!1,onChange:e=>r("nhrrob_secure_enable_advanced_firewall",e)}),(0,a.createElement)(n.TextareaControl,{label:(0,s.__)("Block User Agents","nhrrob-secure"),help:(0,s.__)('Enter one User-Agent per line to block. Case-insensitive partial match. Example: "HTTrack", "curl".',"nhrrob-secure"),value:e.nhrrob_secure_firewall_blocked_uas,onChange:e=>r("nhrrob_secure_firewall_blocked_uas",e),rows:5,placeholder:"SemrushBot\nAhrefsBot\nMJ12bot"})))),v=({settings:e,updateSetting:r})=>{const[t,c]=(0,l.useState)([]),[i,u]=(0,l.useState)(!1),[m,b]=(0,l.useState)(null);(0,l.useEffect)(()=>{d()},[]);const d=async()=>{u(!0),b(null);try{const e=await o()({path:"/nhrrob-secure/v1/sessions"});c(e)}catch(e){b(e.message||(0,s.__)("Failed to load sessions.","nhrrob-secure"))}finally{u(!1)}};return(0,a.createElement)(n.Card,{className:"nhrrob-secure-card nhrrob-secure-sessions-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)("div",{className:"nhrrob-secure-card-header-flex"},(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("User Session Management","nhrrob-secure")),(0,a.createElement)(n.Button,{variant:"primary",onClick:d,isBusy:i,disabled:i,icon:"update"},(0,s.__)("Refresh","nhrrob-secure"))),(0,a.createElement)("div",{className:"nhrrob-secure-setting-group"},(0,a.createElement)(n.TextControl,{label:(0,s.__)("Idle Timeout (Minutes)","nhrrob-secure"),help:(0,s.__)("Automatically log out inactive users after X minutes. Set to 0 to disable.","nhrrob-secure"),type:"number",value:e?.nhrrob_secure_idle_timeout||0,onChange:e=>r("nhrrob_secure_idle_timeout",parseInt(e)||0),min:"0"})),m&&(0,a.createElement)(n.Notice,{status:"error",isDismissible:!1},m),(0,a.createElement)("div",{className:"nhrrob-secure-sessions-list mt-4"},(0,a.createElement)("h3",{className:"text-sm font-semibold mb-3"},(0,s.__)("Active Sessions","nhrrob-secure")),0!==t.length||i?(0,a.createElement)("div",{className:"sessions-grid"},t.map((e,r)=>(0,a.createElement)("div",{key:r,className:"session-item p-3 border rounded mb-2 "+(e.is_current?"bg-blue-50 border-blue-200":"bg-gray-50 border-gray-200")},(0,a.createElement)("div",{className:"flex justify-between items-start"},(0,a.createElement)("div",{className:"session-info"},(0,a.createElement)("div",{className:"font-medium text-gray-700"},e.ip,e.is_current&&(0,a.createElement)("span",{className:"ml-2 px-2 py-0.5 text-xs bg-blue-100 text-blue-800 rounded-full"},(0,s.__)("Current Session","nhrrob-secure"))),(0,a.createElement)("div",{className:"text-xs text-gray-500 mt-1"},(0,a.createElement)("div",null,(0,s.__)("Login:","nhrrob-secure")," ",new Date(1e3*e.login).toLocaleString()),(0,a.createElement)("div",null,(0,s.__)("Expires:","nhrrob-secure")," ",new Date(1e3*e.expiration).toLocaleString()),(0,a.createElement)("div",{className:"mt-1 font-mono text-gray-400 truncate w-64",title:e.ua},e.ua))),!e.is_current&&(0,a.createElement)(n.Button,{variant:"link",isDestructive:!0,onClick:()=>(async e=>{if(confirm((0,s.__)("Are you sure you want to log out this session?","nhrrob-secure")))try{await o()({path:"/nhrrob-secure/v1/sessions/destroy",method:"POST",data:{verifier:e}}),d()}catch(e){alert(e.message||(0,s.__)("Failed to destroy session.","nhrrob-secure"))}})(e.verifier)},(0,s.__)("Logout","nhrrob-secure")))))):(0,a.createElement)("p",null,(0,s.__)("No active sessions found.","nhrrob-secure"))),t.length>1&&(0,a.createElement)("div",{className:"mt-4 pt-3 border-t"},(0,a.createElement)(n.Button,{variant:"secondary",isDestructive:!0,onClick:async()=>{if(confirm((0,s.__)("Are you sure you want to log out all other devices?","nhrrob-secure")))try{await o()({path:"/nhrrob-secure/v1/sessions/destroy-others",method:"POST"}),d(),alert((0,s.__)("All other sessions logged out.","nhrrob-secure"))}catch(e){alert(e.message||(0,s.__)("Failed to destroy sessions.","nhrrob-secure"))}},className:"justify-center h-auto py-2 text-xs"},(0,s.__)("Log Out All Other Devices","nhrrob-secure")))))},p=({settings:e,updateSetting:r})=>{const[t,c]=(0,l.useState)([]),[i,u]=(0,l.useState)(!0),[m,b]=(0,l.useState)(0),[d,h]=(0,l.useState)(1);(0,l.useEffect)(()=>{_()},[d]);const _=async()=>{u(!0);try{const e=20*(d-1),r=await o()({path:`/nhrrob-secure/v1/logs?limit=20&offset=${e}`});c(r.items),b(r.total)}catch(e){console.error(e)}finally{u(!1)}},g=Math.ceil(m/20);return(0,a.createElement)(n.Card,{className:"nhrrob-secure-card nhrrob-secure-audit-log-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)("div",{className:"nhrrob-secure-card-header-flex"},(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("Activity Audit Log","nhrrob-secure")),(0,a.createElement)("div",{className:"nhrrob-secure-card-header-actions"},e&&(0,a.createElement)(n.SelectControl,{className:"nhrrob-secure-retention-select",value:e.nhrrob_secure_log_retention_days,options:[{label:(0,s.__)("Keep logs: 7 days","nhrrob-secure"),value:7},{label:(0,s.__)("Keep logs: 30 days","nhrrob-secure"),value:30},{label:(0,s.__)("Keep logs: 90 days","nhrrob-secure"),value:90},{label:(0,s.__)("Keep logs: 1 year","nhrrob-secure"),value:365}],onChange:e=>r("nhrrob_secure_log_retention_days",parseInt(e))}),(0,a.createElement)(n.Button,{variant:"primary",onClick:_,disabled:i,isBusy:i,icon:"update",iconPosition:"right"},(0,s.__)("Refresh","nhrrob-secure")))),i&&(0,a.createElement)("div",{className:"nhrrob-secure-loading-overlay"},(0,a.createElement)(n.Spinner,null)),(0,a.createElement)("div",{className:"nhrrob-secure-audit-table-wrapper"},(0,a.createElement)("table",{className:"nhrrob-secure-audit-table"},(0,a.createElement)("thead",null,(0,a.createElement)("tr",null,(0,a.createElement)("th",null,(0,s.__)("Date","nhrrob-secure")),(0,a.createElement)("th",null,(0,s.__)("User","nhrrob-secure")),(0,a.createElement)("th",null,(0,s.__)("Context","nhrrob-secure")),(0,a.createElement)("th",null,(0,s.__)("Action","nhrrob-secure")),(0,a.createElement)("th",null,(0,s.__)("Item","nhrrob-secure")),(0,a.createElement)("th",null,(0,s.__)("IP Address","nhrrob-secure")))),(0,a.createElement)("tbody",null,t.length>0?t.map(e=>(0,a.createElement)("tr",{key:e.id,className:`severity-${e.severity}`},(0,a.createElement)("td",null,new Date(e.date).toLocaleString()),(0,a.createElement)("td",null,e.user),(0,a.createElement)("td",null,(0,a.createElement)("span",{className:"nhrrob-secure-badge"},e.context)),(0,a.createElement)("td",null,e.action),(0,a.createElement)("td",null,e.label),(0,a.createElement)("td",null,e.ip))):(0,a.createElement)("tr",null,(0,a.createElement)("td",{colSpan:"6",className:"no-logs"},!i&&(0,s.__)("No activity logs found.","nhrrob-secure")))))),g>1&&(0,a.createElement)("div",{className:"nhrrob-secure-pagination"},(0,a.createElement)(n.Button,{isSmall:!0,disabled:1===d||i,onClick:()=>h(d-1)},"« ",(0,s.__)("Prev","nhrrob-secure")),(0,a.createElement)("span",{className:"nhrrob-secure-page-info"},(0,s.__)("Page","nhrrob-secure")," ",d," ",(0,s.__)("of","nhrrob-secure")," ",g),(0,a.createElement)(n.Button,{isSmall:!0,disabled:d===g||i,onClick:()=>h(d+1)},(0,s.__)("Next","nhrrob-secure")," »"))))},E=({onApplyOneClick:e})=>{const[r,t]=(0,l.useState)(null),[c,i]=(0,l.useState)(!0),[u,m]=(0,l.useState)(!1);(0,l.useEffect)(()=>{b()},[]);const b=async()=>{try{const e=await o()({path:"/nhrrob-secure/v1/health-stats"});t(e),i(!1)}catch(e){console.error("Failed to fetch health stats",e),i(!1)}};if(c)return(0,a.createElement)("div",{className:"nhrrob-secure-card p-6 flex items-center justify-center"},(0,a.createElement)(n.Spinner,null));if(!r)return null;const{score:d,total:h,checks:_,grade:g}=r,v=Math.round(d/h*100);return(0,a.createElement)("div",{className:"nhrrob-secure-card h-full flex flex-col"},(0,a.createElement)("div",{className:"p-5 border-b border-gray-100 dark:border-gray-800 flex items-center justify-between"},(0,a.createElement)("div",null,(0,a.createElement)("h2",{className:"nhrrob-secure-card-title border-0 pb-0"},(0,s.__)("Security Health Check","nhrrob-secure")),(0,a.createElement)("p",{className:"text-xs text-gray-500 mt-1"},(0,s.__)("Overall protection status of your WordPress site","nhrrob-secure"))),(0,a.createElement)("div",{className:"text-2xl font-bold px-3 py-1 rounded-lg "+(E=g,E.startsWith("A")?"bg-green-100 text-green-700":"B"===E?"bg-yellow-100 text-yellow-700":"bg-red-100 text-red-700")},g)),(0,a.createElement)("div",{className:"p-6 flex flex-col md:flex-row items-center gap-8"},(0,a.createElement)("div",{className:"relative w-32 h-32 flex items-center justify-center"},(0,a.createElement)("svg",{className:"w-full h-full transform -rotate-90"},(0,a.createElement)("circle",{cx:"64",cy:"64",r:"58",stroke:"currentColor",strokeWidth:"10",fill:"transparent",className:"text-gray-100 dark:text-gray-800"}),(0,a.createElement)("circle",{cx:"64",cy:"64",r:"58",stroke:"currentColor",strokeWidth:"10",fill:"transparent",strokeDasharray:364,strokeDashoffset:364-364*v/100,strokeLinecap:"round",className:"transition-all duration-1000 ease-out "+(p=v,p>=80?"text-green-500":p>=60?"text-yellow-500":"text-red-500")})),(0,a.createElement)("div",{className:"absolute flex flex-col items-center"},(0,a.createElement)("span",{className:"text-3xl font-bold"},v,"%"),(0,a.createElement)("span",{className:"text-[10px] uppercase tracking-wider text-gray-400 font-semibold"},(0,s.__)("Secure","nhrrob-secure")))),(0,a.createElement)("div",{className:"flex-1 w-full"},(0,a.createElement)("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-3 mb-4"},_.map(e=>(0,a.createElement)("div",{key:e.id,className:"flex items-start gap-2 group"},(0,a.createElement)("div",{className:"mt-0.5 rounded-full p-0.5 "+(e.passed?"text-green-500":"text-red-400 opacity-60")},(0,a.createElement)(n.Icon,{icon:e.passed?"yes":"no-alt",size:16})),(0,a.createElement)("div",null,(0,a.createElement)("span",{className:"text-xs font-medium "+(e.passed?"text-gray-700 dark:text-gray-300":"text-gray-400")},e.label))))),(0,a.createElement)(n.Button,{variant:"secondary",className:"justify-center text-xs py-2 h-auto hover:bg-blue-600 hover:text-white transition-colors",onClick:async()=>{m(!0);try{const r=await o()({path:"/nhrrob-secure/v1/one-click-secure",method:"POST"});r.success&&(t(r.stats),e(r.settings))}catch(e){console.error("One-click secure failed",e)}finally{m(!1)}},isBusy:u,disabled:u},u?(0,s.__)("Applying...","nhrrob-secure"):(0,s.__)("One-Click Secure Recommendations","nhrrob-secure")))));var p,E},y=({settings:e,updateSetting:r})=>{const t=[{label:(0,s.__)("Select Countries to Block...","nhrrob-secure"),value:""},{label:"Afghanistan",value:"AF"},{label:"Albania",value:"AL"},{label:"Algeria",value:"DZ"},{label:"Argentina",value:"AR"},{label:"Australia",value:"AU"},{label:"Austria",value:"AT"},{label:"Bangladesh",value:"BD"},{label:"Belarus",value:"BY"},{label:"Belgium",value:"BE"},{label:"Brazil",value:"BR"},{label:"Bulgaria",value:"BG"},{label:"Canada",value:"CA"},{label:"Chile",value:"CL"},{label:"China",value:"CN"},{label:"Colombia",value:"CO"},{label:"Croatia",value:"HR"},{label:"Cuba",value:"CU"},{label:"Czech Republic",value:"CZ"},{label:"Denmark",value:"DK"},{label:"Egypt",value:"EG"},{label:"Estonia",value:"EE"},{label:"Ethiopia",value:"ET"},{label:"Finland",value:"FI"},{label:"France",value:"FR"},{label:"Germany",value:"DE"},{label:"Ghana",value:"GH"},{label:"Greece",value:"GR"},{label:"Hong Kong",value:"HK"},{label:"Hungary",value:"HU"},{label:"Iceland",value:"IS"},{label:"India",value:"IN"},{label:"Indonesia",value:"ID"},{label:"Iran",value:"IR"},{label:"Iraq",value:"IQ"},{label:"Ireland",value:"IE"},{label:"Israel",value:"IL"},{label:"Italy",value:"IT"},{label:"Japan",value:"JP"},{label:"Kazakhstan",value:"KZ"},{label:"Kenya",value:"KE"},{label:"Kuwait",value:"KW"},{label:"Latvia",value:"LV"},{label:"Lebanon",value:"LB"},{label:"Libya",value:"LY"},{label:"Lithuania",value:"LT"},{label:"Luxembourg",value:"LU"},{label:"Malaysia",value:"MY"},{label:"Mexico",value:"MX"},{label:"Morocco",value:"MA"},{label:"Myanmar",value:"MM"},{label:"Nepal",value:"NP"},{label:"Netherlands",value:"NL"},{label:"New Zealand",value:"NZ"},{label:"Nigeria",value:"NG"},{label:"North Korea",value:"KP"},{label:"Norway",value:"NO"},{label:"Pakistan",value:"PK"},{label:"Palestine",value:"PS"},{label:"Philippines",value:"PH"},{label:"Poland",value:"PL"},{label:"Portugal",value:"PT"},{label:"Qatar",value:"QA"},{label:"Romania",value:"RO"},{label:"Russia",value:"RU"},{label:"Saudi Arabia",value:"SA"},{label:"Serbia",value:"RS"},{label:"Singapore",value:"SG"},{label:"Slovakia",value:"SK"},{label:"Slovenia",value:"SI"},{label:"Somalia",value:"SO"},{label:"South Africa",value:"ZA"},{label:"South Korea",value:"KR"},{label:"Spain",value:"ES"},{label:"Sri Lanka",value:"LK"},{label:"Sudan",value:"SD"},{label:"Sweden",value:"SE"},{label:"Switzerland",value:"CH"},{label:"Syria",value:"SY"},{label:"Taiwan",value:"TW"},{label:"Thailand",value:"TH"},{label:"Turkey",value:"TR"},{label:"Ukraine",value:"UA"},{label:"United Arab Emirates",value:"AE"},{label:"United Kingdom",value:"GB"},{label:"United States",value:"US"},{label:"Venezuela",value:"VE"},{label:"Vietnam",value:"VN"},{label:"Yemen",value:"YE"},{label:"Zimbabwe",value:"ZW"}],l=e.nhrrob_secure_blocked_countries||[],c=e=>{if(!e)return;let t;t=l.includes(e)?l.filter(r=>r!==e):[...l,e],r("nhrrob_secure_blocked_countries",t)};return(0,a.createElement)(n.Card,{className:"nhrrob-secure-card nhrrob-secure-ip-card"},(0,a.createElement)(n.CardBody,null,(0,a.createElement)("h2",{className:"nhrrob-secure-card-title"},(0,s.__)("IP & Country Management","nhrrob-secure")),(0,a.createElement)("p",{className:"text-sm text-gray-500 dark:text-gray-400 mb-6"},(0,s.__)("Control access to your site by whitelisting safe IPs or blocking malicious ones and entire countries.","nhrrob-secure")),(0,a.createElement)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6"},(0,a.createElement)("div",{className:"nhrrob-secure-setting-group"},(0,a.createElement)("label",{className:"block text-sm font-semibold text-green-600 dark:text-green-400 mb-2"},(0,s.__)("IP Whitelist (Safe)","nhrrob-secure")),(0,a.createElement)(n.TextareaControl,{help:(0,s.__)("One IP or CIDR per line (e.g., 192.168.1.1 or 10.0.0.0/24). Whitelisted IPs bypass all security filters.","nhrrob-secure"),value:e.nhrrob_secure_ip_whitelist,onChange:e=>r("nhrrob_secure_ip_whitelist",e),rows:6,placeholder:"1.2.3.4"})),(0,a.createElement)("div",{className:"nhrrob-secure-setting-group"},(0,a.createElement)("label",{className:"block text-sm font-semibold text-red-600 dark:text-red-400 mb-2"},(0,s.__)("IP Blacklist (Blocked)","nhrrob-secure")),(0,a.createElement)(n.TextareaControl,{help:(0,s.__)("One IP or CIDR per line. Blacklisted IPs are blocked immediately from the entire site.","nhrrob-secure"),value:e.nhrrob_secure_ip_blacklist,onChange:e=>r("nhrrob_secure_ip_blacklist",e),rows:6,placeholder:"5.6.7.8"}))),(0,a.createElement)("div",{className:"mt-8 border-t border-gray-100 dark:border-gray-700"},(0,a.createElement)("h3",{className:"text-sm font-semibold mb-4 text-gray-900 dark:text-gray-100"},(0,s.__)("Country Blocking","nhrrob-secure")),(0,a.createElement)("div",{className:"flex flex-wrap gap-4 items-end"},(0,a.createElement)("div",{className:"flex-1 max-w-xs nhrrob-secure-country-select"},(0,a.createElement)(n.SelectControl,{label:(0,s.__)("Add Country to Block","nhrrob-secure"),options:t,onChange:c,className:"dark-mode-select"}))),l.length>0&&(0,a.createElement)("div",{className:"mt-4 flex flex-wrap gap-2"},l.map(e=>(0,a.createElement)("div",{key:e,className:"bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-400 px-3 py-1.5 rounded-full text-xs font-medium flex items-center gap-1 border border-red-200 dark:border-red-800/50"},t.find(r=>r.value===e)?.label||e,(0,a.createElement)("button",{onClick:()=>c(e),className:"focus:outline-none transition-colors text-sm leading-none -mr-0.5 bg-red-50 dark:bg-red-900/20 border-none cursor-pointer",title:(0,s.__)("Remove","nhrrob-secure"),"aria-label":(0,s.__)("Remove","nhrrob-secure")},"×")))),(0,a.createElement)("p",{className:"text-xs text-gray-400 dark:text-gray-500 mt-4 italic"},(0,s.__)("Note: Country blocking uses a free GeoIP lookup service with caching for performance.","nhrrob-secure")))))},f=document.getElementById("nhrrob-secure-settings-root");f&&(0,l.render)((0,a.createElement)(()=>{const[e,r]=(0,l.useState)(null),[t,c]=(0,l.useState)(!0),[d,f]=(0,l.useState)(!1),[N,k]=(0,l.useState)(null);(0,l.useEffect)(()=>{x()},[]);const x=async()=>{try{const e=await o()({path:"/nhrrob-secure/v1/settings"});r(e),c(!1)}catch(e){k({type:"error",message:(0,s.__)("Failed to load settings","nhrrob-secure")}),c(!1)}},w=(t,a)=>{r({...e,[t]:a})};return(0,l.useEffect)(()=>{e?.nhrrob_secure_dark_mode?document.body.classList.add("nhrrob-secure-dark-mode-active"):document.body.classList.remove("nhrrob-secure-dark-mode-active")},[e?.nhrrob_secure_dark_mode]),t?(0,a.createElement)("div",{className:"nhrrob-secure-loading"},(0,a.createElement)(n.Spinner,null)):(0,a.createElement)("div",{className:"nhrrob-secure-settings "+(e.nhrrob_secure_dark_mode?"dark-mode":"")},(0,a.createElement)("div",{className:"nhrrob-secure-header"},(0,a.createElement)("div",{className:"nhrrob-secure-header-main"},(0,a.createElement)("h1",null,(0,s.__)("NHR Secure Settings","nhrrob-secure")),(0,a.createElement)(n.Button,{className:"nhrrob-secure-dark-mode-toggle",icon:e.nhrrob_secure_dark_mode?(0,a.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",width:"20",height:"20"},(0,a.createElement)("path",{d:"M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zM2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1zm18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1zM11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1zm0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1zM5.99 4.58a.996.996 0 00-1.41 0 .996.996 0 000 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41L5.99 4.58zm12.37 12.37a.996.996 0 00-1.41 0 .996.996 0 000 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41l-1.06-1.06zm1.06-10.96a.996.996 0 00-1.41-1.41l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06zM7.05 18.36a.996.996 0 00-1.41-1.41l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06z"})):(0,a.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",width:"20",height:"20"},(0,a.createElement)("path",{d:"M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-.46-.04-.92-.1-1.36-.98 1.37-2.58 2.26-4.4 2.26-2.98 0-5.4-2.42-5.4-5.4 0-1.81.89-3.42 2.26-4.4-.44-.06-.9-.1-1.36-.1z"})),onClick:async()=>{const r=!e.nhrrob_secure_dark_mode;w("nhrrob_secure_dark_mode",r);try{await o()({path:"/nhrrob-secure/v1/settings",method:"POST",data:{...e,nhrrob_secure_dark_mode:r}})}catch(e){console.error("Failed to save dark mode preference",e)}},label:(0,s.__)("Toggle Dark Mode","nhrrob-secure")})),(0,a.createElement)("p",{className:"nhrrob-secure-subtitle"},(0,s.__)("Configure security features for your WordPress site","nhrrob-secure"))),N&&(0,a.createElement)(n.Notice,{status:N.type,isDismissible:!0,onRemove:()=>k(null)},N.message),(0,a.createElement)("div",{className:"nhrrob-secure-cards"},(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(E,{onApplyOneClick:e=>r(e)})),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(i,{settings:e,updateSetting:w})),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(u,{settings:e,updateSetting:w})),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(m,{settings:e,updateSetting:w})),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(g,{settings:e,updateSetting:w})),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(b,{settings:e,updateSetting:w})),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(h,null)),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(y,{settings:e,updateSetting:w})),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(_,null)),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(v,{settings:e,updateSetting:w})),(0,a.createElement)("div",{className:"md:col-span-2 lg:col-span-3"},(0,a.createElement)(p,{settings:e,updateSetting:w}))),(0,a.createElement)("div",{className:"nhrrob-secure-actions"},(0,a.createElement)(n.Button,{variant:"primary",onClick:async()=>{f(!0),k(null);try{await o()({path:"/nhrrob-secure/v1/settings",method:"POST",data:e}),k({type:"success",message:(0,s.__)("Settings saved successfully!","nhrrob-secure")})}catch(e){k({type:"error",message:(0,s.__)("Failed to save settings","nhrrob-secure")})}finally{f(!1)}},isBusy:d,disabled:d},d?(0,s.__)("Saving...","nhrrob-secure"):(0,s.__)("Save Settings","nhrrob-secure"))))},null),f)}},t={};function a(e){var l=t[e];if(void 0!==l)return l.exports;var n=t[e]={exports:{}};return r[e](n,n.exports,a),n.exports}a.m=r,e=[],a.O=(r,t,l,n)=>{if(!t){var s=1/0;for(u=0;u<e.length;u++){for(var[t,l,n]=e[u],c=!0,o=0;o<t.length;o++)(!1&n||s>=n)&&Object.keys(a.O).every(e=>a.O[e](t[o]))?t.splice(o--,1):(c=!1,n<s&&(s=n));if(c){e.splice(u--,1);var i=l();void 0!==i&&(r=i)}}return r}n=n||0;for(var u=e.length;u>0&&e[u-1][2]>n;u--)e[u]=e[u-1];e[u]=[t,l,n]},a.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return a.d(r,{a:r}),r},a.d=(e,r)=>{for(var t in r)a.o(r,t)&&!a.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},a.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),(()=>{var e={884:0,15:0};a.O.j=r=>0===e[r];var r=(r,t)=>{var l,n,[s,c,o]=t,i=0;if(s.some(r=>0!==e[r])){for(l in c)a.o(c,l)&&(a.m[l]=c[l]);if(o)var u=o(a)}for(r&&r(t);i<s.length;i++)n=s[i],a.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return a.O(u)},t=globalThis.webpackChunknhrrob_secure=globalThis.webpackChunknhrrob_secure||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})();var l=a.O(void 0,[15],()=>a(855));l=a.O(l)})(); -
nhrrob-secure/trunk/build/profile.asset.php
r3441244 r3450292 1 <?php return array('dependencies' => array(), 'version' => ' b365bbc000a0d9a2f03a');1 <?php return array('dependencies' => array(), 'version' => '8b4ecd4b3ffe54fafb7d'); -
nhrrob-secure/trunk/build/profile.css
r3441244 r3450292 268 268 line-height: 1.25rem 269 269 } 270 .absolute { 271 272 position: absolute 273 } 274 .relative { 275 276 position: relative 277 } 278 .-mr-0\.5 { 279 280 margin-right: -0.125rem 281 } 270 282 .mb-2 { 271 283 … … 280 292 margin-bottom: 1rem 281 293 } 294 .mb-6 { 295 296 margin-bottom: 1.5rem 297 } 282 298 .ml-2 { 283 299 … … 292 308 margin-top: 0px 293 309 } 310 .mt-0\.5 { 311 312 margin-top: 0.125rem 313 } 294 314 .mt-1 { 295 315 … … 300 320 margin-top: 1rem 301 321 } 322 .mt-8 { 323 324 margin-top: 2rem 325 } 302 326 .block { 303 327 … … 320 344 display: none 321 345 } 346 .h-32 { 347 348 height: 8rem 349 } 350 .h-auto { 351 352 height: auto 353 } 354 .h-full { 355 356 height: 100% 357 } 358 .w-32 { 359 360 width: 8rem 361 } 322 362 .w-64 { 323 363 … … 328 368 width: 100% 329 369 } 370 .max-w-xs { 371 372 max-width: 20rem 373 } 374 .flex-1 { 375 376 flex: 1 1 0% 377 } 378 .-rotate-90 { 379 380 --tw-rotate: -90deg; 381 382 transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) 383 } 384 .transform { 385 386 transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) 387 } 388 .cursor-pointer { 389 390 cursor: pointer 391 } 392 .grid-cols-1 { 393 394 grid-template-columns: repeat(1, minmax(0, 1fr)) 395 } 330 396 .grid-cols-2 { 331 397 332 398 grid-template-columns: repeat(2, minmax(0, 1fr)) 333 399 } 400 .flex-col { 401 402 flex-direction: column 403 } 404 .flex-wrap { 405 406 flex-wrap: wrap 407 } 334 408 .items-start { 335 409 336 410 align-items: flex-start 337 411 } 412 .items-end { 413 414 align-items: flex-end 415 } 416 .items-center { 417 418 align-items: center 419 } 338 420 .justify-center { 339 421 … … 344 426 justify-content: space-between 345 427 } 428 .gap-1 { 429 430 gap: 0.25rem 431 } 346 432 .gap-2 { 347 433 348 434 gap: 0.5rem 349 435 } 436 .gap-3 { 437 438 gap: 0.75rem 439 } 440 .gap-4 { 441 442 gap: 1rem 443 } 444 .gap-6 { 445 446 gap: 1.5rem 447 } 448 .gap-8 { 449 450 gap: 2rem 451 } 350 452 .truncate { 351 453 … … 364 466 border-radius: 9999px 365 467 } 468 .rounded-lg { 469 470 border-radius: 0.5rem 471 } 366 472 .border { 367 473 368 474 border-width: 1px 369 475 } 476 .border-0 { 477 478 border-width: 0px 479 } 480 .border-b { 481 482 border-bottom-width: 1px 483 } 370 484 .border-t { 371 485 372 486 border-top-width: 1px 373 487 } 488 .border-none { 489 490 border-style: none 491 } 374 492 .border-blue-200 { 375 493 … … 390 508 border-color: rgb(229 231 235 / var(--tw-border-opacity, 1)) 391 509 } 510 .border-red-200 { 511 512 --tw-border-opacity: 1; 513 514 border-color: rgb(254 202 202 / var(--tw-border-opacity, 1)) 515 } 392 516 .bg-blue-100 { 393 517 … … 408 532 background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1)) 409 533 } 534 .bg-green-100 { 535 536 --tw-bg-opacity: 1; 537 538 background-color: rgb(220 252 231 / var(--tw-bg-opacity, 1)) 539 } 540 .bg-red-100 { 541 542 --tw-bg-opacity: 1; 543 544 background-color: rgb(254 226 226 / var(--tw-bg-opacity, 1)) 545 } 546 .bg-red-50 { 547 548 --tw-bg-opacity: 1; 549 550 background-color: rgb(254 242 242 / var(--tw-bg-opacity, 1)) 551 } 552 .bg-yellow-100 { 553 554 --tw-bg-opacity: 1; 555 556 background-color: rgb(254 249 195 / var(--tw-bg-opacity, 1)) 557 } 558 .p-0\.5 { 559 560 padding: 0.125rem 561 } 410 562 .p-3 { 411 563 412 564 padding: 0.75rem 413 565 } 566 .p-5 { 567 568 padding: 1.25rem 569 } 570 .p-6 { 571 572 padding: 1.5rem 573 } 414 574 .px-2 { 415 575 … … 418 578 padding-right: 0.5rem 419 579 } 580 .px-3 { 581 582 padding-left: 0.75rem; 583 584 padding-right: 0.75rem 585 } 420 586 .py-0\.5 { 421 587 … … 424 590 padding-bottom: 0.125rem 425 591 } 592 .py-1 { 593 594 padding-top: 0.25rem; 595 596 padding-bottom: 0.25rem 597 } 598 .py-1\.5 { 599 600 padding-top: 0.375rem; 601 602 padding-bottom: 0.375rem 603 } 604 .py-2 { 605 606 padding-top: 0.5rem; 607 608 padding-bottom: 0.5rem 609 } 610 .pb-0 { 611 612 padding-bottom: 0px 613 } 426 614 .pt-3 { 427 615 … … 436 624 font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace 437 625 } 626 .text-2xl { 627 628 font-size: 1.5rem; 629 630 line-height: 2rem 631 } 632 .text-3xl { 633 634 font-size: 1.875rem; 635 636 line-height: 2.25rem 637 } 638 .text-\[10px\] { 639 640 font-size: 10px 641 } 438 642 .text-sm { 439 643 … … 448 652 line-height: 1rem 449 653 } 654 .font-bold { 655 656 font-weight: 700 657 } 450 658 .font-medium { 451 659 … … 456 664 font-weight: 600 457 665 } 666 .uppercase { 667 668 text-transform: uppercase 669 } 670 .italic { 671 672 font-style: italic 673 } 674 .leading-none { 675 676 line-height: 1 677 } 678 .tracking-wider { 679 680 letter-spacing: 0.05em 681 } 458 682 .text-blue-800 { 459 683 … … 462 686 color: rgb(30 64 175 / var(--tw-text-opacity, 1)) 463 687 } 688 .text-gray-100 { 689 690 --tw-text-opacity: 1; 691 692 color: rgb(243 244 246 / var(--tw-text-opacity, 1)) 693 } 464 694 .text-gray-400 { 465 695 … … 480 710 color: rgb(55 65 81 / var(--tw-text-opacity, 1)) 481 711 } 712 .text-gray-900 { 713 714 --tw-text-opacity: 1; 715 716 color: rgb(17 24 39 / var(--tw-text-opacity, 1)) 717 } 718 .text-green-500 { 719 720 --tw-text-opacity: 1; 721 722 color: rgb(34 197 94 / var(--tw-text-opacity, 1)) 723 } 724 .text-green-600 { 725 726 --tw-text-opacity: 1; 727 728 color: rgb(22 163 74 / var(--tw-text-opacity, 1)) 729 } 730 .text-green-700 { 731 732 --tw-text-opacity: 1; 733 734 color: rgb(21 128 61 / var(--tw-text-opacity, 1)) 735 } 736 .text-red-400 { 737 738 --tw-text-opacity: 1; 739 740 color: rgb(248 113 113 / var(--tw-text-opacity, 1)) 741 } 742 .text-red-500 { 743 744 --tw-text-opacity: 1; 745 746 color: rgb(239 68 68 / var(--tw-text-opacity, 1)) 747 } 748 .text-red-600 { 749 750 --tw-text-opacity: 1; 751 752 color: rgb(220 38 38 / var(--tw-text-opacity, 1)) 753 } 754 .text-red-700 { 755 756 --tw-text-opacity: 1; 757 758 color: rgb(185 28 28 / var(--tw-text-opacity, 1)) 759 } 760 .text-yellow-500 { 761 762 --tw-text-opacity: 1; 763 764 color: rgb(234 179 8 / var(--tw-text-opacity, 1)) 765 } 766 .text-yellow-700 { 767 768 --tw-text-opacity: 1; 769 770 color: rgb(161 98 7 / var(--tw-text-opacity, 1)) 771 } 772 .opacity-60 { 773 774 opacity: 0.6 775 } 482 776 .filter { 483 777 484 778 filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow) 485 779 } 780 .transition-all { 781 782 transition-property: all; 783 784 transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); 785 786 transition-duration: 150ms 787 } 788 .transition-colors { 789 790 transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; 791 792 transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); 793 794 transition-duration: 150ms 795 } 796 .duration-1000 { 797 798 transition-duration: 1000ms 799 } 800 .ease-out { 801 802 transition-timing-function: cubic-bezier(0, 0, 0.2, 1) 803 } 804 .hover\:bg-blue-600:hover { 805 806 --tw-bg-opacity: 1; 807 808 background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1)) 809 } 810 .hover\:text-white:hover { 811 812 --tw-text-opacity: 1; 813 814 color: rgb(255 255 255 / var(--tw-text-opacity, 1)) 815 } 816 .focus\:outline-none:focus { 817 818 outline: 2px solid transparent; 819 820 outline-offset: 2px 821 } 822 @media (min-width: 640px) { 823 824 .sm\:grid-cols-2 { 825 826 grid-template-columns: repeat(2, minmax(0, 1fr)) 827 } 828 } 829 @media (min-width: 768px) { 830 831 .md\:col-span-2 { 832 833 grid-column: span 2 / span 2 834 } 835 836 .md\:grid-cols-2 { 837 838 grid-template-columns: repeat(2, minmax(0, 1fr)) 839 } 840 841 .md\:flex-row { 842 843 flex-direction: row 844 } 845 } 846 @media (min-width: 1024px) { 847 848 .lg\:col-span-3 { 849 850 grid-column: span 3 / span 3 851 } 852 } 853 @media (prefers-color-scheme: dark) { 854 855 .dark\:border-gray-700 { 856 857 --tw-border-opacity: 1; 858 859 border-color: rgb(55 65 81 / var(--tw-border-opacity, 1)) 860 } 861 862 .dark\:border-gray-800 { 863 864 --tw-border-opacity: 1; 865 866 border-color: rgb(31 41 55 / var(--tw-border-opacity, 1)) 867 } 868 869 .dark\:border-red-800\/50 { 870 871 border-color: rgb(153 27 27 / 0.5) 872 } 873 874 .dark\:bg-red-900\/20 { 875 876 background-color: rgb(127 29 29 / 0.2) 877 } 878 879 .dark\:text-gray-100 { 880 881 --tw-text-opacity: 1; 882 883 color: rgb(243 244 246 / var(--tw-text-opacity, 1)) 884 } 885 886 .dark\:text-gray-300 { 887 888 --tw-text-opacity: 1; 889 890 color: rgb(209 213 219 / var(--tw-text-opacity, 1)) 891 } 892 893 .dark\:text-gray-400 { 894 895 --tw-text-opacity: 1; 896 897 color: rgb(156 163 175 / var(--tw-text-opacity, 1)) 898 } 899 900 .dark\:text-gray-500 { 901 902 --tw-text-opacity: 1; 903 904 color: rgb(107 114 128 / var(--tw-text-opacity, 1)) 905 } 906 907 .dark\:text-gray-800 { 908 909 --tw-text-opacity: 1; 910 911 color: rgb(31 41 55 / var(--tw-text-opacity, 1)) 912 } 913 914 .dark\:text-green-400 { 915 916 --tw-text-opacity: 1; 917 918 color: rgb(74 222 128 / var(--tw-text-opacity, 1)) 919 } 920 921 .dark\:text-red-400 { 922 923 --tw-text-opacity: 1; 924 925 color: rgb(248 113 113 / var(--tw-text-opacity, 1)) 926 } 927 } -
nhrrob-secure/trunk/includes/Admin/Api.php
r3441244 r3450292 118 118 'sanitize_callback' => 'absint', 119 119 ], 120 'nhrrob_secure_enable_advanced_firewall' => [ 121 'type' => 'boolean', 122 'sanitize_callback' => 'rest_sanitize_boolean', 123 ], 124 'nhrrob_secure_ip_whitelist' => [ 125 'type' => 'string', 126 'sanitize_callback' => 'sanitize_textarea_field', 127 ], 128 'nhrrob_secure_ip_blacklist' => [ 129 'type' => 'string', 130 'sanitize_callback' => 'sanitize_textarea_field', 131 ], 132 'nhrrob_secure_blocked_countries' => [ 133 'type' => 'array', 134 'items' => [ 135 'type' => 'string', 136 ], 137 'sanitize_callback' => function ($countries) { 138 return is_array($countries) ? array_map('sanitize_text_field', $countries) : []; 139 }, 140 ], 120 141 ], 121 142 ]); … … 227 248 'methods' => 'POST', 228 249 'callback' => [$this, 'destroy_other_sessions'], 250 'permission_callback' => function () { 251 return current_user_can('manage_options'); 252 }, 253 ]); 254 255 // Health check stats 256 register_rest_route('nhrrob-secure/v1', '/health-stats', [ 257 'methods' => 'GET', 258 'callback' => [$this, 'get_health_stats'], 259 'permission_callback' => function () { 260 return current_user_can('manage_options'); 261 }, 262 ]); 263 264 // One-click secure 265 register_rest_route('nhrrob-secure/v1', '/one-click-secure', [ 266 'methods' => 'POST', 267 'callback' => [$this, 'apply_one_click_secure'], 229 268 'permission_callback' => function () { 230 269 return current_user_can('manage_options'); … … 256 295 'nhrrob_secure_firewall_blocked_uas' => get_option('nhrrob_secure_firewall_blocked_uas', ''), 257 296 'nhrrob_secure_idle_timeout' => (int) get_option('nhrrob_secure_idle_timeout', 0), 297 'nhrrob_secure_enable_advanced_firewall' => (bool) get_option('nhrrob_secure_enable_advanced_firewall', false), 298 'nhrrob_secure_ip_whitelist' => get_option('nhrrob_secure_ip_whitelist', ''), 299 'nhrrob_secure_ip_blacklist' => get_option('nhrrob_secure_ip_blacklist', ''), 300 'nhrrob_secure_blocked_countries' => (array) get_option('nhrrob_secure_blocked_countries', []), 258 301 'available_roles' => $this->get_available_roles(), 259 302 ]; … … 430 473 return ['success' => true]; 431 474 } 475 476 /** 477 * Get health stats 478 */ 479 public function get_health_stats() 480 { 481 $health = new \NHRRob\Secure\HealthCheck(); 482 return $health->get_stats(); 483 } 484 485 /** 486 * Apply one-click secure 487 */ 488 public function apply_one_click_secure() 489 { 490 $health = new \NHRRob\Secure\HealthCheck(); 491 $health->apply_one_click_secure(); 492 493 return [ 494 'success' => true, 495 'settings' => $this->get_settings(), 496 'stats' => $health->get_stats(), 497 ]; 498 } 432 499 } -
nhrrob-secure/trunk/includes/TwoFactor.php
r3436910 r3450292 26 26 $this->tfa = new \RobThree\Auth\TwoFactorAuth( 27 27 new \RobThree\Auth\Providers\Qr\QRServerProvider(), 28 'NHR Secure'28 get_bloginfo('name') . ' - NHR Secure' 29 29 ); 30 30 … … 78 78 // Generate QR Code URL 79 79 $label = $user->user_email; 80 $issuer = 'NHR Secure';80 $issuer = get_bloginfo('name') . ' - NHR Secure'; 81 81 $otpauth_url = sprintf( 'otpauth://totp/%s:%s?secret=%s&issuer=%s', urlencode( $issuer ), urlencode( $label ), $secret, urlencode( $issuer ) ); 82 82 $qrCodeUrl = sprintf( 'https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=%s', urlencode( $otpauth_url ) ); -
nhrrob-secure/trunk/nhrrob-secure.php
r3441244 r3450292 6 6 * Author: Nazmul Hasan Robin 7 7 * Author URI: https://profiles.wordpress.org/nhrrob/ 8 * Version: 1. 2.08 * Version: 1.3.0 9 9 * Requires at least: 6.0 10 10 * Requires PHP: 7.4 … … 31 31 * @var string 32 32 */ 33 const version = '1. 2.0';33 const version = '1.3.0'; 34 34 35 35 /** … … 106 106 new \NHRRob\Secure\Hardening(); 107 107 108 // Initialize advanced firewall (IPS) 109 new \NHRRob\Secure\Firewall(); 110 111 // Initialize IP & Country manager 112 new \NHRRob\Secure\IPManager(); 113 108 114 // Initialize session manager 109 115 new \NHRRob\Secure\SessionManager(); -
nhrrob-secure/trunk/readme.txt
r3441244 r3450292 5 5 Tested up to: 6.9 6 6 Requires PHP: 7.4 7 Stable tag: 1. 2.07 Stable tag: 1.3.0 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 19 19 - Add 2FA to your WordPress site. 20 20 - Scan core files, plugins, and themes for known vulnerabilities. 21 - Monitor site health with one-click security recommendations. 22 - Protect against SQL injection, XSS, and LFI attacks. 23 - Block malicious IPs and entire countries. 21 24 22 25 ### **Features at a glance:** … … 75 78 - View user, IP, and event details. 76 79 - Configurable log retention policy. 80 81 ### 🏥 Security Health Check & One-Click Secure 82 Get an instant overview of your site's security posture. 83 - **Security Score:** View your overall protection percentage and grade (A+ to F). 84 - **Health Dashboard:** See which security features are active and which need attention. 85 - **One-Click Secure:** Apply recommended security settings instantly. 86 - **11 Security Checks:** Comprehensive analysis of your security status. 87 88 ### 🛡️ Advanced Firewall (IPS) 89 Proactive intrusion prevention system that blocks malicious requests in real-time. 90 - **SQL Injection Protection:** Detect and block SQLi attacks automatically. 91 - **XSS Prevention:** Stop cross-site scripting attempts. 92 - **LFI Protection:** Prevent local file inclusion attacks. 93 - **Pattern Matching:** Advanced regex-based detection for common attack vectors. 94 - **Automatic Blocking:** Suspicious requests are blocked before they reach WordPress. 95 96 ### 🌍 IP & Country Management 97 Control access to your site with granular IP and geographic filtering. 98 - **IP Whitelist:** Allow trusted IPs to bypass all security filters. 99 - **IP Blacklist:** Block malicious IPs permanently from your site. 100 - **CIDR Support:** Use CIDR notation for blocking entire IP ranges (e.g., 192.168.1.0/24). 101 - **Country Blocking:** Block access from 90+ countries using GeoIP lookup. 102 - **Smart Caching:** GeoIP lookups are cached for 24 hours for optimal performance. 103 - **Private IP Detection:** Automatically skip local/private IPs. 77 104 78 105 ### ⚡ Lightweight & Minimal … … 124 151 == Changelog == 125 152 153 = 1.3.0 - 28/01/2026 = 154 - Added: Security Health Check with scoring system (A+ to F grade) 155 - Added: One-Click Secure feature to apply recommended settings instantly 156 - Added: Advanced Firewall (IPS) with real-time protection against SQL Injection, XSS, and LFI attacks 157 - Added: IP Management with Whitelist and Blacklist (CIDR support) 158 - Added: Country Blocking for 90+ countries using GeoIP lookup with caching 159 - Improved: Dark mode styling for all components 160 - Improved: Overall security dashboard UI/UX 161 126 162 = 1.2.0 - 17/01/2026 = 127 163 - Added: User Session Management (View active sessions, remote logout, idle timeout)
Note: See TracChangeset
for help on using the changeset viewer.