UNPKG

klioso

Version:

Multi-Service Provider Management System for WordPress and Web Development with Enhanced Scanner

2 lines (1 loc) 16.3 kB
import{a as u,j as e,H as V}from"./app-DZ07njAd.js";import{A as B}from"./AuthenticatedLayout-BKOGad_C.js";import{B as P}from"./Button-D6Jcp-tA.js";import{F as S}from"./Form-DWGkysrX.js";import"./ApplicationLogo-GDc3W5ND.js";import"./transition-BCwV6od8.js";function G({websites:W=[]}){const[N,$]=u.useState("url"),[o,w]=u.useState({url:"",scanType:"plugins",autoSync:!1}),[F,z]=u.useState(""),[T,_]=u.useState(!1),[n,b]=u.useState(null),[C,c]=u.useState(""),[f,j]=u.useState(null),[h,x]=u.useState(new Set),[k,y]=u.useState(""),[O,A]=u.useState(!1);u.useEffect(()=>{if(k){const s=setTimeout(()=>y(""),5e3);return()=>clearTimeout(s)}},[k]),u.useEffect(()=>{if(C){const s=setTimeout(()=>c(""),8e3);return()=>clearTimeout(s)}},[C]);const R=()=>{const s=[{percent:15,stage:"Connecting to website...",duration:1e3},{percent:30,stage:"Detecting WordPress installation...",duration:1500},{percent:55,stage:"Scanning plugins and themes...",duration:2e3},{percent:75,stage:"Checking security vulnerabilities...",duration:1500},{percent:90,stage:"Analyzing results...",duration:1e3},{percent:100,stage:"Finalizing scan...",duration:500}],a=s.reduce((t,i)=>t+i.duration,0);let l=0,d=0;j({percent:0,stage:"Initializing scan...",timeLeft:a});const r=setInterval(()=>{if(l<s.length){const t=s[l],i=a-d;j({percent:t.percent,stage:t.stage,timeLeft:Math.max(0,i)}),d+=t.duration,l++}else clearInterval(r),j(null)},800);return r},E=async s=>{var l;if(s.preventDefault(),!o.url){c("URL is required to perform the scan.");return}_(!0),c(""),b(null),y(""),x(new Set);const a=R();try{const d=(l=document.querySelector('meta[name="csrf-token"]'))==null?void 0:l.getAttribute("content");if(!d)throw new Error("CSRF token not found. Please refresh the page.");const r=await fetch("/scan",{method:"POST",headers:{"Content-Type":"application/json","X-CSRF-TOKEN":d,Accept:"application/json"},body:JSON.stringify({url:o.url,scan_type:o.scanType})}),t=await r.json();if(r.ok&&t.success){b(t.data);const i=t.data.plugins?t.data.plugins.length:0,p=t.data.themes?t.data.themes.length:0;let g=`Scan completed successfully! Found ${i} plugins`;if(p>0&&(g+=` and ${p} themes`),g+=".",o.autoSync&&t.data.auto_sync_results){const m=t.data.auto_sync_results.synced_plugins||0;g+=` Auto-sync added ${m} new plugins to the database.`}y(g),!o.autoSync&&t.data.plugins&&x(new Set(t.data.plugins.map((m,v)=>v)))}else if(r.status===422){const i=t.errors?Object.values(t.errors).flat().join(", "):t.message||"Validation failed";c("Validation error: "+i)}else c(t.message||`Request failed with status ${r.status}`)}catch(d){c("Failed to perform scan: "+d.message)}finally{_(!1),clearInterval(a),j(null)}},I=async s=>{var l;if(s.preventDefault(),!F)return;_(!0),c(""),b(null),y(""),x(new Set);const a=R();try{const d=(l=document.querySelector('meta[name="csrf-token"]'))==null?void 0:l.getAttribute("content");if(!d)throw new Error("CSRF token not found. Please refresh the page.");const t=await(await fetch(`/websites/${F}/scan`,{method:"POST",headers:{"Content-Type":"application/json","X-CSRF-TOKEN":d,Accept:"application/json"},body:JSON.stringify({scan_type:o.scanType,auto_sync:o.autoSync})})).json();if(t.success){b(t.data);const i=t.data.plugins?t.data.plugins.length:0,p=t.data.themes?t.data.themes.length:0;let g=`Website scan completed successfully! Found ${i} plugins`;if(p>0&&(g+=` and ${p} themes`),g+=".",o.autoSync&&t.data.auto_sync_results){const m=t.data.auto_sync_results.synced_plugins||0;g+=` Auto-sync added ${m} new plugins to the website database.`}y(g),!o.autoSync&&t.data.plugins&&x(new Set(t.data.plugins.map((m,v)=>v)))}else c(t.message||"Scan failed")}catch(d){c("Failed to perform scan: "+d.message)}finally{_(!1),clearInterval(a),j(null)}},L=async s=>{var a;try{const l=(a=document.querySelector('meta[name="csrf-token"]'))==null?void 0:a.getAttribute("content");if(!l){alert("CSRF token not found. Please refresh the page.");return}const r=await(await fetch("/scanner/add-plugin",{method:"POST",headers:{"Content-Type":"application/json","X-CSRF-TOKEN":l,Accept:"application/json"},body:JSON.stringify({name:s.name,description:s.description,slug:s.slug})})).json();r.success?b(t=>({...t,plugins:t.plugins.map(i=>i.name===s.name?{...i,in_database:!0,database_id:r.plugin.id}:i)})):alert("Failed to add plugin to database")}catch(l){alert("Failed to add plugin: "+l.message)}},D=(s,a)=>{const l=new Set(h);a?l.add(s):l.delete(s),x(l)},q=s=>{s&&(n!=null&&n.plugins)?x(new Set(n.plugins.map((a,l)=>l))):x(new Set)},M=async()=>{var s;if(h.size===0){c("Please select plugins to add to database.");return}A(!0),c("");try{const a=Array.from(h).map(t=>({index:t,plugin:n.plugins[t]})).filter(t=>!t.plugin.in_database);if(a.length===0){c("All selected plugins are already in the database."),A(!1);return}const l=(s=document.querySelector('meta[name="csrf-token"]'))==null?void 0:s.getAttribute("content");if(!l){c("CSRF token not found. Please refresh the page."),A(!1);return}const r=await(await fetch("/scanner/bulk-add-plugins",{method:"POST",headers:{"Content-Type":"application/json","X-CSRF-TOKEN":l,Accept:"application/json"},body:JSON.stringify({plugins:a.map(t=>({name:t.plugin.name,description:t.plugin.description,slug:t.plugin.slug}))})})).json();r.success?(b(t=>({...t,plugins:t.plugins.map((i,p)=>{if(a.find(m=>m.index===p)){const m=r.plugins.find(v=>v.name===i.name);return{...i,in_database:!0,database_id:m==null?void 0:m.id}}return i})})),x(new Set),y(`Successfully added ${r.plugins.length} plugins to the database!`)):c(r.message||"Failed to add plugins to database")}catch(a){c("Failed to add plugins: "+a.message)}finally{A(!1)}};return e.jsxs(B,{children:[e.jsx(V,{title:"WordPress Scanner"}),e.jsx("div",{className:"py-12",children:e.jsx("div",{className:"max-w-7xl mx-auto sm:px-6 lg:px-8",children:e.jsx("div",{className:"bg-white overflow-hidden shadow-sm sm:rounded-lg",children:e.jsxs("div",{className:"p-6 bg-white border-b border-gray-200",children:[e.jsx("div",{className:"flex justify-between items-center mb-6",children:e.jsx("h2",{className:"text-xl font-semibold text-gray-900",children:"WordPress Scanner"})}),e.jsx("div",{className:"border-b border-gray-200 mb-6",children:e.jsxs("nav",{className:"-mb-px flex space-x-8",children:[e.jsx("button",{onClick:()=>$("url"),className:`py-2 px-1 border-b-2 font-medium text-sm ${N==="url"?"border-indigo-500 text-indigo-600":"border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300"}`,children:"URL Scan"}),e.jsx("button",{onClick:()=>$("website"),className:`py-2 px-1 border-b-2 font-medium text-sm ${N==="website"?"border-indigo-500 text-indigo-600":"border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300"}`,children:"Website Scan"})]})}),N==="url"&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium text-gray-900 mb-4",children:"Scan WordPress Website"}),e.jsx("p",{className:"text-sm text-gray-600 mb-4",children:"Enter a website URL to scan for WordPress installation, plugins, themes, and security vulnerabilities."})]}),e.jsxs("form",{onSubmit:E,className:"space-y-4",children:[e.jsx(S.Input,{id:"url",label:"Website URL",type:"url",value:o.url,onChange:s=>w(a=>({...a,url:s.target.value})),placeholder:"https://example.com",required:!0}),e.jsxs(S.Select,{id:"scan-type",label:"Scan Type",value:o.scanType,onChange:s=>w(a=>({...a,scanType:s.target.value})),children:[e.jsx("option",{value:"plugins",children:"Plugins Only"}),e.jsx("option",{value:"themes",children:"Themes Only"}),e.jsx("option",{value:"vulnerabilities",children:"Vulnerabilities Only"}),e.jsx("option",{value:"all",children:"All (Comprehensive)"})]}),e.jsx(P,{type:"submit",disabled:T,children:T?"Scanning...":"Start Scan"})]})]}),N==="website"&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium text-gray-900 mb-4",children:"Scan Existing Website"}),e.jsx("p",{className:"text-sm text-gray-600 mb-4",children:"Select a website from your database to scan and optionally sync the results."})]}),e.jsxs("form",{onSubmit:I,className:"space-y-4",children:[e.jsxs(S.Select,{id:"website-select",label:"Website",value:F,onChange:s=>z(s.target.value),required:!0,children:[e.jsx("option",{value:"",children:"Select a website"}),W.map(s=>e.jsxs("option",{value:s.id,children:[s.domain_name," ",s.client_name&&`(${s.client_name})`]},s.id))]}),e.jsxs(S.Select,{id:"website-scan-type",label:"Scan Type",value:o.scanType,onChange:s=>w(a=>({...a,scanType:s.target.value})),children:[e.jsx("option",{value:"plugins",children:"Plugins Only"}),e.jsx("option",{value:"themes",children:"Themes Only"}),e.jsx("option",{value:"vulnerabilities",children:"Vulnerabilities Only"}),e.jsx("option",{value:"all",children:"All (Comprehensive)"})]}),e.jsx(S.Checkbox,{id:"auto-sync",label:"Auto-sync discovered plugins to website","aria-describedby":"auto-sync-description",checked:o.autoSync,onChange:s=>w(a=>({...a,autoSync:s.target.checked}))}),e.jsx("p",{id:"auto-sync-description",className:"text-xs text-gray-500 -mt-2",children:"Automatically synchronize discovered plugins with the selected website's database."}),e.jsx(P,{type:"submit",disabled:T,children:T?"Scanning...":"Start Scan"})]})]}),f&&e.jsxs("div",{className:"mt-6 p-4 bg-blue-50 border border-blue-200 rounded-md",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("h4",{className:"text-sm font-medium text-blue-900",children:"Scanning in Progress"}),e.jsxs("div",{className:"flex items-center text-sm text-blue-700",children:[e.jsx("div",{className:"animate-spin rounded-full h-4 w-4 border-b-2 border-blue-600 mr-2"}),Math.floor(f.timeLeft/1e3),"s remaining"]})]}),e.jsx("div",{className:"w-full bg-blue-200 rounded-full h-2.5 mb-2",children:e.jsx("div",{className:"bg-blue-600 h-2.5 rounded-full transition-all duration-500 ease-out",style:{width:`${f.percent}%`}})}),e.jsxs("p",{className:"text-sm text-blue-700",children:[f.stage," (",f.percent,"%)"]})]}),k&&e.jsx("div",{className:"mt-6 p-4 bg-green-50 border border-green-200 rounded-md",children:e.jsxs("div",{className:"flex",children:[e.jsx("div",{className:"flex-shrink-0",children:e.jsx("svg",{className:"h-5 w-5 text-green-400",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z",clipRule:"evenodd"})})}),e.jsx("div",{className:"ml-3",children:e.jsx("p",{className:"text-sm font-medium text-green-800",children:k})})]})}),C&&e.jsx("div",{className:"mt-6 p-4 bg-red-50 border border-red-200 rounded-md",children:e.jsx("div",{className:"flex",children:e.jsxs("div",{className:"ml-3",children:[e.jsx("h3",{className:"text-sm font-medium text-red-800",children:"Error"}),e.jsx("div",{className:"mt-2 text-sm text-red-700",children:e.jsx("p",{children:C})})]})})}),n&&e.jsxs("div",{className:"mt-8 space-y-6",children:[e.jsxs("div",{className:"bg-gray-50 p-4 rounded-lg",children:[e.jsx("h3",{className:"text-lg font-medium text-gray-900 mb-2",children:"Scan Results"}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4 text-sm",children:[e.jsxs("div",{children:[e.jsx("span",{className:"font-medium",children:"WordPress Detected:"}),e.jsx("span",{className:`ml-2 px-2 py-1 rounded text-xs ${n.wordpress_detected?"bg-green-100 text-green-800":"bg-red-100 text-red-800"}`,children:n.wordpress_detected?"Yes":"No"})]}),n.wordpress_version&&e.jsxs("div",{children:[e.jsx("span",{className:"font-medium",children:"Version:"}),e.jsx("span",{className:"ml-2",children:n.wordpress_version})]}),e.jsxs("div",{children:[e.jsx("span",{className:"font-medium",children:"Scan Time:"}),e.jsx("span",{className:"ml-2",children:new Date().toLocaleString()})]})]})]}),n.plugins&&n.plugins.length>0&&e.jsxs("div",{children:[e.jsxs("div",{className:"flex justify-between items-center mb-4",children:[e.jsxs("h4",{className:"text-lg font-medium text-gray-900",children:["Detected Plugins (",n.plugins.length,")"]}),e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs("div",{className:"flex items-center text-sm text-gray-600",children:[e.jsx("input",{type:"checkbox",id:"select-all-plugins",className:"mr-2 h-4 w-4 text-indigo-600 border-gray-300 rounded focus:ring-indigo-500",checked:h.size===n.plugins.length&&n.plugins.length>0,onChange:s=>q(s.target.checked)}),e.jsxs("label",{htmlFor:"select-all-plugins",children:["Select All (",h.size," selected)"]})]}),h.size>0&&e.jsx(P,{onClick:M,disabled:O,size:"sm",variant:"outline",children:O?`Adding ${h.size} plugins...`:`Add ${h.size} to Database`})]})]}),e.jsx("div",{className:"space-y-3",children:n.plugins.map((s,a)=>e.jsx("div",{className:"bg-white border rounded-lg p-4",children:e.jsxs("div",{className:"flex justify-between items-start",children:[e.jsxs("div",{className:"flex items-start gap-3 flex-1",children:[e.jsx("input",{type:"checkbox",id:`plugin-${a}`,className:"mt-1 h-4 w-4 text-indigo-600 border-gray-300 rounded focus:ring-indigo-500",checked:h.has(a),onChange:l=>D(a,l.target.checked)}),e.jsxs("div",{className:"flex-1",children:[e.jsx("h5",{className:"font-medium",children:s.name}),s.description&&e.jsx("p",{className:"text-sm text-gray-600 mt-1",children:s.description}),e.jsxs("div",{className:"flex gap-4 mt-2 text-sm",children:[s.version&&e.jsxs("span",{children:[e.jsx("strong",{children:"Version:"})," ",s.version]}),s.slug&&e.jsxs("span",{children:[e.jsx("strong",{children:"Slug:"})," ",s.slug]}),e.jsx("span",{className:`px-2 py-1 rounded text-xs ${s.status==="active"?"bg-green-100 text-green-800":"bg-gray-100 text-gray-800"}`,children:s.status}),s.in_database!==void 0&&e.jsx("span",{className:`px-2 py-1 rounded text-xs ${s.in_database?"bg-blue-100 text-blue-800":"bg-yellow-100 text-yellow-800"}`,children:s.in_database?"In Database":"Not in Database"}),s.is_paid!==void 0&&e.jsx("span",{className:`px-2 py-1 rounded text-xs ${s.is_paid?"bg-purple-100 text-purple-800":"bg-green-100 text-green-800"}`,children:s.is_paid?"Paid":"Free"})]})]})]}),e.jsx("div",{className:"ml-4",children:!s.in_database&&e.jsx(P,{onClick:()=>L(s),size:"sm",variant:"outline",children:"Add to Database"})})]})},a))})]}),n.themes&&n.themes.length>0&&e.jsxs("div",{children:[e.jsxs("h4",{className:"text-lg font-medium text-gray-900 mb-4",children:["Detected Themes (",n.themes.length,")"]}),e.jsx("div",{className:"space-y-3",children:n.themes.map((s,a)=>e.jsx("div",{className:"bg-white border rounded-lg p-4",children:e.jsx("div",{className:"flex justify-between items-start",children:e.jsxs("div",{children:[e.jsx("h5",{className:"font-medium",children:s.name}),e.jsxs("div",{className:"flex gap-4 mt-2 text-sm",children:[s.slug&&e.jsxs("span",{children:[e.jsx("strong",{children:"Slug:"})," ",s.slug]}),e.jsx("span",{className:`px-2 py-1 rounded text-xs ${s.status==="active"?"bg-green-100 text-green-800":"bg-gray-100 text-gray-800"}`,children:s.status})]})]})})},a))})]}),n.vulnerabilities&&n.vulnerabilities.length>0&&e.jsxs("div",{children:[e.jsxs("h4",{className:"text-lg font-medium text-gray-900 mb-4",children:["Security Vulnerabilities (",n.vulnerabilities.length,")"]}),e.jsx("div",{className:"space-y-3",children:n.vulnerabilities.map((s,a)=>e.jsx("div",{className:"bg-red-50 border border-red-200 rounded-lg p-4",children:e.jsx("div",{className:"flex justify-between items-start",children:e.jsxs("div",{children:[e.jsx("h5",{className:"font-medium text-red-900",children:s.title}),e.jsx("p",{className:"text-sm text-red-700 mt-1",children:s.description}),e.jsx("div",{className:"flex gap-4 mt-2 text-sm",children:e.jsxs("span",{className:`px-2 py-1 rounded text-xs ${s.severity==="high"?"bg-red-100 text-red-800":s.severity==="medium"?"bg-yellow-100 text-yellow-800":"bg-blue-100 text-blue-800"}`,children:[s.severity," severity"]})})]})})},a))})]}),(!n.plugins||n.plugins.length===0)&&(!n.themes||n.themes.length===0)&&(!n.vulnerabilities||n.vulnerabilities.length===0)&&e.jsx("div",{className:"text-center py-8",children:e.jsx("p",{className:"text-gray-500",children:"No plugins, themes, or vulnerabilities found."})})]})]})})})})]})}export{G as default};