Plugin Directory

Changeset 3450292


Ignore:
Timestamp:
01/30/2026 09:40:47 AM (2 months ago)
Author:
nhrrob
Message:

Update to version 1.3.0 from GitHub

Location:
nhrrob-secure
Files:
10 added
26 edited
1 copied

Legend:

Unmodified
Added
Removed
  • nhrrob-secure/tags/1.3.0/assets/src/components/Hardening.js

    r3441244 r3450292  
    4343                    <h3 className="nhrrob-secure-setting-subtitle">{__('Firewall Rules', 'nhrrob-secure')}</h3>
    4444
     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
    4552                    <TextareaControl
    4653                        label={__('Block User Agents', 'nhrrob-secure')}
  • nhrrob-secure/tags/1.3.0/assets/src/components/SessionManager.js

    r3441244 r3450292  
    133133                            isDestructive
    134134                            onClick={destroyOtherSessions}
    135                             className="w-full justify-center"
     135                            className="justify-center h-auto py-2 text-xs"
    136136                        >
    137137                            {__('Log Out All Other Devices', 'nhrrob-secure')}
  • nhrrob-secure/tags/1.3.0/assets/src/index.js

    r3441244 r3450292  
    1616import SessionManager from './components/SessionManager';
    1717import AuditLog from './components/AuditLog';
     18import HealthCheck from './components/HealthCheck';
     19import IPManager from './components/IPManager';
    1820import './style.css';
    1921
     
    124126
    125127            <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>
    135161            </div>
    136162
  • nhrrob-secure/tags/1.3.0/assets/src/style.css

    r3441244 r3450292  
    8383
    8484    .nhrrob-secure-cards {
    85         @apply grid gap-5 mb-6;
     85        @apply grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5 mb-6;
    8686    }
    8787
     
    124124    .dark-mode .components-placeholder__instructions,
    125125    .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 {
    127130        color: var(--nhrrob-secure-text) !important;
    128131    }
    129132
     133    .
    130134    .dark-mode .components-placeholder {
    131135        background-color: var(--nhrrob-secure-vuln-bg) !important;
     
    135139
    136140    .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 {
    138150        background-color: #2c3338 !important;
    139151        border-color: #43494e !important;
     
    265277
    266278    .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;
    268288    }
    269289
     
    332352
    333353    .nhrrob-result-list {
    334         @apply divide-y;
     354        @apply divide-y overflow-y-auto max-h-[400px];
    335355    }
    336356
  • 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  
    116116        margin-bottom: 1.5rem;
    117117        display: grid;
     118        grid-template-columns: repeat(1, minmax(0, 1fr));
    118119        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        }
    119134}
    120135
     
    177192    .dark-mode .components-placeholder__instructions,
    178193    .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 {
    180198        color: var(--nhrrob-secure-text) !important;
    181199    }
    182200
     201    .
    183202    .dark-mode .components-placeholder {
    184203        background-color: var(--nhrrob-secure-vuln-bg) !important;
     
    188207
    189208    .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 {
    191218        background-color: #2c3338 !important;
    192219        border-color: #43494e !important;
     
    371398    .nhrrob-scan-controls {
    372399        display: flex;
     400        flex-shrink: 0;
    373401        align-items: center;
    374402        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;
    375420}
    376421
     
    518563}
    519564
     565    .nhrrob-result-list {
     566        max-height: 400px;
     567}
     568
    520569    .nhrrob-result-list > :not([hidden]) ~ :not([hidden]) {
    521570        --tw-divide-y-reverse: 0;
    522571        border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
    523572        border-bottom-width: calc(1px * var(--tw-divide-y-reverse));
     573}
     574
     575    .nhrrob-result-list {
     576        overflow-y: auto;
    524577}
    525578
     
    605658        border-color: var(--nhrrob-secure-border);
    606659}
     660.absolute {
     661        position: absolute;
     662}
     663.relative {
     664        position: relative;
     665}
     666.-mr-0\.5 {
     667        margin-right: -0.125rem;
     668}
    607669.mb-2 {
    608670        margin-bottom: 0.5rem;
     
    614676        margin-bottom: 1rem;
    615677}
     678.mb-6 {
     679        margin-bottom: 1.5rem;
     680}
    616681.ml-2 {
    617682        margin-left: 0.5rem;
     
    623688        margin-top: 0px;
    624689}
     690.mt-0\.5 {
     691        margin-top: 0.125rem;
     692}
    625693.mt-1 {
    626694        margin-top: 0.25rem;
     
    629697        margin-top: 1rem;
    630698}
     699.mt-8 {
     700        margin-top: 2rem;
     701}
    631702.block {
    632703        display: block;
     
    644715        display: none;
    645716}
     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}
    646729.w-64 {
    647730        width: 16rem;
     
    650733        width: 100%;
    651734}
     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}
    652754.grid-cols-2 {
    653755        grid-template-columns: repeat(2, minmax(0, 1fr));
    654756}
     757.flex-col {
     758        flex-direction: column;
     759}
     760.flex-wrap {
     761        flex-wrap: wrap;
     762}
    655763.items-start {
    656764        align-items: flex-start;
    657765}
     766.items-end {
     767        align-items: flex-end;
     768}
     769.items-center {
     770        align-items: center;
     771}
    658772.justify-center {
    659773        justify-content: center;
     
    662776        justify-content: space-between;
    663777}
     778.gap-1 {
     779        gap: 0.25rem;
     780}
    664781.gap-2 {
    665782        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;
    666795}
    667796.truncate {
     
    676805        border-radius: 9999px;
    677806}
     807.rounded-lg {
     808        border-radius: 0.5rem;
     809}
    678810.border {
    679811        border-width: 1px;
    680812}
     813.border-0 {
     814        border-width: 0px;
     815}
     816.border-b {
     817        border-bottom-width: 1px;
     818}
    681819.border-t {
    682820        border-top-width: 1px;
     821}
     822.border-none {
     823        border-style: none;
    683824}
    684825.border-blue-200 {
     
    694835        border-color: rgb(229 231 235 / var(--tw-border-opacity, 1));
    695836}
     837.border-red-200 {
     838        --tw-border-opacity: 1;
     839        border-color: rgb(254 202 202 / var(--tw-border-opacity, 1));
     840}
    696841.bg-blue-100 {
    697842        --tw-bg-opacity: 1;
     
    705850        --tw-bg-opacity: 1;
    706851        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;
    707871}
    708872.p-3 {
    709873        padding: 0.75rem;
     874}
     875.p-5 {
     876        padding: 1.25rem;
     877}
     878.p-6 {
     879        padding: 1.5rem;
    710880}
    711881.px-2 {
     
    713883        padding-right: 0.5rem;
    714884}
     885.px-3 {
     886        padding-left: 0.75rem;
     887        padding-right: 0.75rem;
     888}
    715889.py-0\.5 {
    716890        padding-top: 0.125rem;
    717891        padding-bottom: 0.125rem;
    718892}
     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}
    719908.pt-3 {
    720909        padding-top: 0.75rem;
     
    725914.font-mono {
    726915        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;
    727927}
    728928.text-sm {
     
    734934        line-height: 1rem;
    735935}
     936.font-bold {
     937        font-weight: 700;
     938}
    736939.font-medium {
    737940        font-weight: 500;
     
    740943        font-weight: 600;
    741944}
     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}
    742957.text-blue-800 {
    743958        --tw-text-opacity: 1;
    744959        color: rgb(30 64 175 / var(--tw-text-opacity, 1));
    745960}
     961.text-gray-100 {
     962        --tw-text-opacity: 1;
     963        color: rgb(243 244 246 / var(--tw-text-opacity, 1));
     964}
    746965.text-gray-400 {
    747966        --tw-text-opacity: 1;
     
    755974        --tw-text-opacity: 1;
    756975        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;
    7571019}
    7581020.filter {
    7591021        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);
    7601038}
    7611039
     
    9231201        border-left-color: rgb(220 38 38 / var(--tw-border-opacity, 1));
    9241202}
     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  
    268268    line-height: 1.25rem
    269269}
     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}
    270282.mb-2 {
    271283
     
    280292    margin-bottom: 1rem
    281293}
     294.mb-6 {
     295
     296    margin-bottom: 1.5rem
     297}
    282298.ml-2 {
    283299
     
    292308    margin-top: 0px
    293309}
     310.mt-0\.5 {
     311
     312    margin-top: 0.125rem
     313}
    294314.mt-1 {
    295315
     
    300320    margin-top: 1rem
    301321}
     322.mt-8 {
     323
     324    margin-top: 2rem
     325}
    302326.block {
    303327
     
    320344    display: none
    321345}
     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}
    322362.w-64 {
    323363
     
    328368    width: 100%
    329369}
     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}
    330396.grid-cols-2 {
    331397
    332398    grid-template-columns: repeat(2, minmax(0, 1fr))
    333399}
     400.flex-col {
     401
     402    flex-direction: column
     403}
     404.flex-wrap {
     405
     406    flex-wrap: wrap
     407}
    334408.items-start {
    335409
    336410    align-items: flex-start
    337411}
     412.items-end {
     413
     414    align-items: flex-end
     415}
     416.items-center {
     417
     418    align-items: center
     419}
    338420.justify-center {
    339421
     
    344426    justify-content: space-between
    345427}
     428.gap-1 {
     429
     430    gap: 0.25rem
     431}
    346432.gap-2 {
    347433
    348434    gap: 0.5rem
    349435}
     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}
    350452.truncate {
    351453
     
    364466    border-radius: 9999px
    365467}
     468.rounded-lg {
     469
     470    border-radius: 0.5rem
     471}
    366472.border {
    367473
    368474    border-width: 1px
    369475}
     476.border-0 {
     477
     478    border-width: 0px
     479}
     480.border-b {
     481
     482    border-bottom-width: 1px
     483}
    370484.border-t {
    371485
    372486    border-top-width: 1px
    373487}
     488.border-none {
     489
     490    border-style: none
     491}
    374492.border-blue-200 {
    375493
     
    390508    border-color: rgb(229 231 235 / var(--tw-border-opacity, 1))
    391509}
     510.border-red-200 {
     511
     512    --tw-border-opacity: 1;
     513
     514    border-color: rgb(254 202 202 / var(--tw-border-opacity, 1))
     515}
    392516.bg-blue-100 {
    393517
     
    408532    background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1))
    409533}
     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}
    410562.p-3 {
    411563
    412564    padding: 0.75rem
    413565}
     566.p-5 {
     567
     568    padding: 1.25rem
     569}
     570.p-6 {
     571
     572    padding: 1.5rem
     573}
    414574.px-2 {
    415575
     
    418578    padding-right: 0.5rem
    419579}
     580.px-3 {
     581
     582    padding-left: 0.75rem;
     583
     584    padding-right: 0.75rem
     585}
    420586.py-0\.5 {
    421587
     
    424590    padding-bottom: 0.125rem
    425591}
     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}
    426614.pt-3 {
    427615
     
    436624    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace
    437625}
     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}
    438642.text-sm {
    439643
     
    448652    line-height: 1rem
    449653}
     654.font-bold {
     655
     656    font-weight: 700
     657}
    450658.font-medium {
    451659
     
    456664    font-weight: 600
    457665}
     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}
    458682.text-blue-800 {
    459683
     
    462686    color: rgb(30 64 175 / var(--tw-text-opacity, 1))
    463687}
     688.text-gray-100 {
     689
     690    --tw-text-opacity: 1;
     691
     692    color: rgb(243 244 246 / var(--tw-text-opacity, 1))
     693}
    464694.text-gray-400 {
    465695
     
    480710    color: rgb(55 65 81 / var(--tw-text-opacity, 1))
    481711}
     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}
    482776.filter {
    483777
    484778    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)
    485779}
     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  
    118118                    'sanitize_callback' => 'absint',
    119119                ],
     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                ],
    120141            ],
    121142        ]);
     
    227248            'methods' => 'POST',
    228249            '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'],
    229268            'permission_callback' => function () {
    230269                return current_user_can('manage_options');
     
    256295            'nhrrob_secure_firewall_blocked_uas' => get_option('nhrrob_secure_firewall_blocked_uas', ''),
    257296            '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', []),
    258301            'available_roles' => $this->get_available_roles(),
    259302        ];
     
    430473        return ['success' => true];
    431474    }
     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    }
    432499}
  • nhrrob-secure/tags/1.3.0/includes/TwoFactor.php

    r3436910 r3450292  
    2626        $this->tfa = new \RobThree\Auth\TwoFactorAuth(
    2727            new \RobThree\Auth\Providers\Qr\QRServerProvider(),
    28             'NHR Secure'
     28            get_bloginfo('name') . ' - NHR Secure'
    2929        );
    3030
     
    7878        // Generate QR Code URL
    7979        $label = $user->user_email;
    80         $issuer = 'NHR Secure';
     80        $issuer = get_bloginfo('name') . ' - NHR Secure';
    8181        $otpauth_url = sprintf( 'otpauth://totp/%s:%s?secret=%s&issuer=%s', urlencode( $issuer ), urlencode( $label ), $secret, urlencode( $issuer ) );
    8282        $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  
    66 * Author: Nazmul Hasan Robin
    77 * Author URI: https://profiles.wordpress.org/nhrrob/
    8  * Version: 1.2.0
     8 * Version: 1.3.0
    99 * Requires at least: 6.0
    1010 * Requires PHP: 7.4
     
    3131     * @var string
    3232     */
    33     const version = '1.2.0';
     33    const version = '1.3.0';
    3434
    3535    /**
     
    106106        new \NHRRob\Secure\Hardening();
    107107
     108        // Initialize advanced firewall (IPS)
     109        new \NHRRob\Secure\Firewall();
     110
     111        // Initialize IP & Country manager
     112        new \NHRRob\Secure\IPManager();
     113
    108114        // Initialize session manager
    109115        new \NHRRob\Secure\SessionManager();
  • nhrrob-secure/tags/1.3.0/readme.txt

    r3441244 r3450292  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 1.2.0
     7Stable tag: 1.3.0
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    1919- Add 2FA to your WordPress site.
    2020- 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.
    2124
    2225### **Features at a glance:**
     
    7578- View user, IP, and event details.
    7679- Configurable log retention policy.
     80
     81### 🏥 Security Health Check & One-Click Secure
     82Get 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)
     89Proactive 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
     97Control 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.
    77104
    78105### ⚡ Lightweight & Minimal
     
    124151== Changelog ==
    125152
     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
    126162= 1.2.0 - 17/01/2026 =
    127163- Added: User Session Management (View active sessions, remote logout, idle timeout)
  • nhrrob-secure/trunk/assets/src/components/Hardening.js

    r3441244 r3450292  
    4343                    <h3 className="nhrrob-secure-setting-subtitle">{__('Firewall Rules', 'nhrrob-secure')}</h3>
    4444
     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
    4552                    <TextareaControl
    4653                        label={__('Block User Agents', 'nhrrob-secure')}
  • nhrrob-secure/trunk/assets/src/components/SessionManager.js

    r3441244 r3450292  
    133133                            isDestructive
    134134                            onClick={destroyOtherSessions}
    135                             className="w-full justify-center"
     135                            className="justify-center h-auto py-2 text-xs"
    136136                        >
    137137                            {__('Log Out All Other Devices', 'nhrrob-secure')}
  • nhrrob-secure/trunk/assets/src/index.js

    r3441244 r3450292  
    1616import SessionManager from './components/SessionManager';
    1717import AuditLog from './components/AuditLog';
     18import HealthCheck from './components/HealthCheck';
     19import IPManager from './components/IPManager';
    1820import './style.css';
    1921
     
    124126
    125127            <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>
    135161            </div>
    136162
  • nhrrob-secure/trunk/assets/src/style.css

    r3441244 r3450292  
    8383
    8484    .nhrrob-secure-cards {
    85         @apply grid gap-5 mb-6;
     85        @apply grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5 mb-6;
    8686    }
    8787
     
    124124    .dark-mode .components-placeholder__instructions,
    125125    .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 {
    127130        color: var(--nhrrob-secure-text) !important;
    128131    }
    129132
     133    .
    130134    .dark-mode .components-placeholder {
    131135        background-color: var(--nhrrob-secure-vuln-bg) !important;
     
    135139
    136140    .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 {
    138150        background-color: #2c3338 !important;
    139151        border-color: #43494e !important;
     
    265277
    266278    .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;
    268288    }
    269289
     
    332352
    333353    .nhrrob-result-list {
    334         @apply divide-y;
     354        @apply divide-y overflow-y-auto max-h-[400px];
    335355    }
    336356
  • 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  
    116116        margin-bottom: 1.5rem;
    117117        display: grid;
     118        grid-template-columns: repeat(1, minmax(0, 1fr));
    118119        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        }
    119134}
    120135
     
    177192    .dark-mode .components-placeholder__instructions,
    178193    .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 {
    180198        color: var(--nhrrob-secure-text) !important;
    181199    }
    182200
     201    .
    183202    .dark-mode .components-placeholder {
    184203        background-color: var(--nhrrob-secure-vuln-bg) !important;
     
    188207
    189208    .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 {
    191218        background-color: #2c3338 !important;
    192219        border-color: #43494e !important;
     
    371398    .nhrrob-scan-controls {
    372399        display: flex;
     400        flex-shrink: 0;
    373401        align-items: center;
    374402        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;
    375420}
    376421
     
    518563}
    519564
     565    .nhrrob-result-list {
     566        max-height: 400px;
     567}
     568
    520569    .nhrrob-result-list > :not([hidden]) ~ :not([hidden]) {
    521570        --tw-divide-y-reverse: 0;
    522571        border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
    523572        border-bottom-width: calc(1px * var(--tw-divide-y-reverse));
     573}
     574
     575    .nhrrob-result-list {
     576        overflow-y: auto;
    524577}
    525578
     
    605658        border-color: var(--nhrrob-secure-border);
    606659}
     660.absolute {
     661        position: absolute;
     662}
     663.relative {
     664        position: relative;
     665}
     666.-mr-0\.5 {
     667        margin-right: -0.125rem;
     668}
    607669.mb-2 {
    608670        margin-bottom: 0.5rem;
     
    614676        margin-bottom: 1rem;
    615677}
     678.mb-6 {
     679        margin-bottom: 1.5rem;
     680}
    616681.ml-2 {
    617682        margin-left: 0.5rem;
     
    623688        margin-top: 0px;
    624689}
     690.mt-0\.5 {
     691        margin-top: 0.125rem;
     692}
    625693.mt-1 {
    626694        margin-top: 0.25rem;
     
    629697        margin-top: 1rem;
    630698}
     699.mt-8 {
     700        margin-top: 2rem;
     701}
    631702.block {
    632703        display: block;
     
    644715        display: none;
    645716}
     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}
    646729.w-64 {
    647730        width: 16rem;
     
    650733        width: 100%;
    651734}
     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}
    652754.grid-cols-2 {
    653755        grid-template-columns: repeat(2, minmax(0, 1fr));
    654756}
     757.flex-col {
     758        flex-direction: column;
     759}
     760.flex-wrap {
     761        flex-wrap: wrap;
     762}
    655763.items-start {
    656764        align-items: flex-start;
    657765}
     766.items-end {
     767        align-items: flex-end;
     768}
     769.items-center {
     770        align-items: center;
     771}
    658772.justify-center {
    659773        justify-content: center;
     
    662776        justify-content: space-between;
    663777}
     778.gap-1 {
     779        gap: 0.25rem;
     780}
    664781.gap-2 {
    665782        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;
    666795}
    667796.truncate {
     
    676805        border-radius: 9999px;
    677806}
     807.rounded-lg {
     808        border-radius: 0.5rem;
     809}
    678810.border {
    679811        border-width: 1px;
    680812}
     813.border-0 {
     814        border-width: 0px;
     815}
     816.border-b {
     817        border-bottom-width: 1px;
     818}
    681819.border-t {
    682820        border-top-width: 1px;
     821}
     822.border-none {
     823        border-style: none;
    683824}
    684825.border-blue-200 {
     
    694835        border-color: rgb(229 231 235 / var(--tw-border-opacity, 1));
    695836}
     837.border-red-200 {
     838        --tw-border-opacity: 1;
     839        border-color: rgb(254 202 202 / var(--tw-border-opacity, 1));
     840}
    696841.bg-blue-100 {
    697842        --tw-bg-opacity: 1;
     
    705850        --tw-bg-opacity: 1;
    706851        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;
    707871}
    708872.p-3 {
    709873        padding: 0.75rem;
     874}
     875.p-5 {
     876        padding: 1.25rem;
     877}
     878.p-6 {
     879        padding: 1.5rem;
    710880}
    711881.px-2 {
     
    713883        padding-right: 0.5rem;
    714884}
     885.px-3 {
     886        padding-left: 0.75rem;
     887        padding-right: 0.75rem;
     888}
    715889.py-0\.5 {
    716890        padding-top: 0.125rem;
    717891        padding-bottom: 0.125rem;
    718892}
     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}
    719908.pt-3 {
    720909        padding-top: 0.75rem;
     
    725914.font-mono {
    726915        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;
    727927}
    728928.text-sm {
     
    734934        line-height: 1rem;
    735935}
     936.font-bold {
     937        font-weight: 700;
     938}
    736939.font-medium {
    737940        font-weight: 500;
     
    740943        font-weight: 600;
    741944}
     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}
    742957.text-blue-800 {
    743958        --tw-text-opacity: 1;
    744959        color: rgb(30 64 175 / var(--tw-text-opacity, 1));
    745960}
     961.text-gray-100 {
     962        --tw-text-opacity: 1;
     963        color: rgb(243 244 246 / var(--tw-text-opacity, 1));
     964}
    746965.text-gray-400 {
    747966        --tw-text-opacity: 1;
     
    755974        --tw-text-opacity: 1;
    756975        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;
    7571019}
    7581020.filter {
    7591021        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);
    7601038}
    7611039
     
    9231201        border-left-color: rgb(220 38 38 / var(--tw-border-opacity, 1));
    9241202}
     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  
    268268    line-height: 1.25rem
    269269}
     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}
    270282.mb-2 {
    271283
     
    280292    margin-bottom: 1rem
    281293}
     294.mb-6 {
     295
     296    margin-bottom: 1.5rem
     297}
    282298.ml-2 {
    283299
     
    292308    margin-top: 0px
    293309}
     310.mt-0\.5 {
     311
     312    margin-top: 0.125rem
     313}
    294314.mt-1 {
    295315
     
    300320    margin-top: 1rem
    301321}
     322.mt-8 {
     323
     324    margin-top: 2rem
     325}
    302326.block {
    303327
     
    320344    display: none
    321345}
     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}
    322362.w-64 {
    323363
     
    328368    width: 100%
    329369}
     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}
    330396.grid-cols-2 {
    331397
    332398    grid-template-columns: repeat(2, minmax(0, 1fr))
    333399}
     400.flex-col {
     401
     402    flex-direction: column
     403}
     404.flex-wrap {
     405
     406    flex-wrap: wrap
     407}
    334408.items-start {
    335409
    336410    align-items: flex-start
    337411}
     412.items-end {
     413
     414    align-items: flex-end
     415}
     416.items-center {
     417
     418    align-items: center
     419}
    338420.justify-center {
    339421
     
    344426    justify-content: space-between
    345427}
     428.gap-1 {
     429
     430    gap: 0.25rem
     431}
    346432.gap-2 {
    347433
    348434    gap: 0.5rem
    349435}
     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}
    350452.truncate {
    351453
     
    364466    border-radius: 9999px
    365467}
     468.rounded-lg {
     469
     470    border-radius: 0.5rem
     471}
    366472.border {
    367473
    368474    border-width: 1px
    369475}
     476.border-0 {
     477
     478    border-width: 0px
     479}
     480.border-b {
     481
     482    border-bottom-width: 1px
     483}
    370484.border-t {
    371485
    372486    border-top-width: 1px
    373487}
     488.border-none {
     489
     490    border-style: none
     491}
    374492.border-blue-200 {
    375493
     
    390508    border-color: rgb(229 231 235 / var(--tw-border-opacity, 1))
    391509}
     510.border-red-200 {
     511
     512    --tw-border-opacity: 1;
     513
     514    border-color: rgb(254 202 202 / var(--tw-border-opacity, 1))
     515}
    392516.bg-blue-100 {
    393517
     
    408532    background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1))
    409533}
     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}
    410562.p-3 {
    411563
    412564    padding: 0.75rem
    413565}
     566.p-5 {
     567
     568    padding: 1.25rem
     569}
     570.p-6 {
     571
     572    padding: 1.5rem
     573}
    414574.px-2 {
    415575
     
    418578    padding-right: 0.5rem
    419579}
     580.px-3 {
     581
     582    padding-left: 0.75rem;
     583
     584    padding-right: 0.75rem
     585}
    420586.py-0\.5 {
    421587
     
    424590    padding-bottom: 0.125rem
    425591}
     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}
    426614.pt-3 {
    427615
     
    436624    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace
    437625}
     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}
    438642.text-sm {
    439643
     
    448652    line-height: 1rem
    449653}
     654.font-bold {
     655
     656    font-weight: 700
     657}
    450658.font-medium {
    451659
     
    456664    font-weight: 600
    457665}
     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}
    458682.text-blue-800 {
    459683
     
    462686    color: rgb(30 64 175 / var(--tw-text-opacity, 1))
    463687}
     688.text-gray-100 {
     689
     690    --tw-text-opacity: 1;
     691
     692    color: rgb(243 244 246 / var(--tw-text-opacity, 1))
     693}
    464694.text-gray-400 {
    465695
     
    480710    color: rgb(55 65 81 / var(--tw-text-opacity, 1))
    481711}
     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}
    482776.filter {
    483777
    484778    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)
    485779}
     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  
    118118                    'sanitize_callback' => 'absint',
    119119                ],
     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                ],
    120141            ],
    121142        ]);
     
    227248            'methods' => 'POST',
    228249            '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'],
    229268            'permission_callback' => function () {
    230269                return current_user_can('manage_options');
     
    256295            'nhrrob_secure_firewall_blocked_uas' => get_option('nhrrob_secure_firewall_blocked_uas', ''),
    257296            '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', []),
    258301            'available_roles' => $this->get_available_roles(),
    259302        ];
     
    430473        return ['success' => true];
    431474    }
     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    }
    432499}
  • nhrrob-secure/trunk/includes/TwoFactor.php

    r3436910 r3450292  
    2626        $this->tfa = new \RobThree\Auth\TwoFactorAuth(
    2727            new \RobThree\Auth\Providers\Qr\QRServerProvider(),
    28             'NHR Secure'
     28            get_bloginfo('name') . ' - NHR Secure'
    2929        );
    3030
     
    7878        // Generate QR Code URL
    7979        $label = $user->user_email;
    80         $issuer = 'NHR Secure';
     80        $issuer = get_bloginfo('name') . ' - NHR Secure';
    8181        $otpauth_url = sprintf( 'otpauth://totp/%s:%s?secret=%s&issuer=%s', urlencode( $issuer ), urlencode( $label ), $secret, urlencode( $issuer ) );
    8282        $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  
    66 * Author: Nazmul Hasan Robin
    77 * Author URI: https://profiles.wordpress.org/nhrrob/
    8  * Version: 1.2.0
     8 * Version: 1.3.0
    99 * Requires at least: 6.0
    1010 * Requires PHP: 7.4
     
    3131     * @var string
    3232     */
    33     const version = '1.2.0';
     33    const version = '1.3.0';
    3434
    3535    /**
     
    106106        new \NHRRob\Secure\Hardening();
    107107
     108        // Initialize advanced firewall (IPS)
     109        new \NHRRob\Secure\Firewall();
     110
     111        // Initialize IP & Country manager
     112        new \NHRRob\Secure\IPManager();
     113
    108114        // Initialize session manager
    109115        new \NHRRob\Secure\SessionManager();
  • nhrrob-secure/trunk/readme.txt

    r3441244 r3450292  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 1.2.0
     7Stable tag: 1.3.0
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    1919- Add 2FA to your WordPress site.
    2020- 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.
    2124
    2225### **Features at a glance:**
     
    7578- View user, IP, and event details.
    7679- Configurable log retention policy.
     80
     81### 🏥 Security Health Check & One-Click Secure
     82Get 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)
     89Proactive 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
     97Control 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.
    77104
    78105### ⚡ Lightweight & Minimal
     
    124151== Changelog ==
    125152
     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
    126162= 1.2.0 - 17/01/2026 =
    127163- Added: User Session Management (View active sessions, remote logout, idle timeout)
Note: See TracChangeset for help on using the changeset viewer.