import { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { useAuth } from '../components/AuthContext'; import toast from 'react-hot-toast'; export const NewScan = () => { const [targetUrl, setTargetUrl] = useState(''); const [scanType, setScanType] = useState('Quick'); const [error, setError] = useState(''); const [loading, setLoading] = useState(false); const [customHeaders, setCustomHeaders] = useState(''); const [crawlDepth, setCrawlDepth] = useState('3'); const [excludePaths, setExcludePaths] = useState(''); const [enableRedTeam, setEnableRedTeam] = useState(false); const [scanConfig, setScanConfig] = useState([]); const [showAdvanced, setShowAdvanced] = useState(false); const [showUpgradeModal, setShowUpgradeModal] = useState(false); const [showQuotaExceededModal, setShowQuotaExceededModal] = useState(false); const [attemptedScan, setAttemptedScan] = useState(''); const [quotas, setQuotas] = useState([]); const [isScheduled, setIsScheduled] = useState(false); const [scheduleFrequency, setScheduleFrequency] = useState('daily'); const [scheduleTime, setScheduleTime] = useState('02:00'); // Legal & Confirmation Modal States const [showConfirmModal, setShowConfirmModal] = useState(false); const [showPolicyModal, setShowPolicyModal] = useState(false); const [hasReadPolicy, setHasReadPolicy] = useState(false); const [policyCheck1, setPolicyCheck1] = useState(false); const [policyCheck2, setPolicyCheck2] = useState(false); const [isConfirmedChecked, setIsConfirmedChecked] = useState(false); const { token, user } = useAuth(); const navigate = useNavigate(); useEffect(() => { fetch('/api/scans/config') .then(res => res.json()) .then(data => { if (data.config) { setScanConfig(data.config); } }) .catch(err => console.error("Failed to fetch scan config", err)); }, []); useEffect(() => { if (user?.org_id && token) { fetch(`/api/auth/organizations/${user.org_id}/quotas`, { headers: { 'Authorization': `Bearer ${token}` } }) .then(res => res.json()) .then(data => { if (Array.isArray(data)) { setQuotas(data); } else if (data.quotas) { setQuotas(data.quotas); } }) .catch(console.error); } }, [user?.org_id, token]); useEffect(() => { if (scanType === 'Deep') { setEnableRedTeam(true); setCrawlDepth('20'); } else if (scanType === 'Advanced') { setEnableRedTeam(true); setCrawlDepth('10'); } else if (scanType === 'Quick') { setEnableRedTeam(false); setCrawlDepth('3'); } }, [scanType]); const hasQuota = (methodId) => { if (user?.role === 'admin' || user?.role === 'super_admin') return true; if (!quotas || quotas.length === 0) return true; const q = quotas.find(q => q.scan_type.toLowerCase() === methodId.toLowerCase()); if (!q) return true; if (q.allocated_count === -1) return true; return (q.allocated_count - q.used_count) > 0; }; const handleLaunch = (e) => { e.preventDefault(); setError(''); if (!hasQuota(scanType)) { setAttemptedScan(scanType); setShowQuotaExceededModal(true); return; } if (!targetUrl) { setError('Please provide a target host URL.'); return; } try { const urlObj = new URL(targetUrl); if (urlObj.protocol !== 'http:' && urlObj.protocol !== 'https:') { setError('Please enter a valid website URL (must start with http:// or https://)'); return; } if (!urlObj.hostname.includes('.')) { setError('Please enter a valid website URL (must have a valid domain structure)'); return; } } catch (_) { setError('Please enter a valid website URL (must start with http:// or https://)'); return; } // Open confirmation modal before actual launch setShowConfirmModal(true); }; const executeScan = async () => { setShowConfirmModal(false); setLoading(true); try { let parsedAuthHeaders = {}; if (customHeaders) { const lines = customHeaders.split('\n'); lines.forEach(line => { const parts = line.split(':'); if (parts.length >= 2) { const key = parts[0].trim(); const value = parts.slice(1).join(':').trim(); if (key && value) parsedAuthHeaders[key] = value; } }); } if (isScheduled) { const res = await fetch('/api/scans/schedule', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ target_url: targetUrl, scan_type: scanType, frequency: scheduleFrequency, schedule_time: scheduleTime }) }); const data = await res.json(); if (res.ok) { toast.success('Scan scheduled successfully!'); navigate('/dashboard'); } else { if (res.status === 403 || res.status === 402 || data.message?.toLowerCase().includes('quota')) { setAttemptedScan(scanType); setShowQuotaExceededModal(true); } else { toast.error(data.message || 'Failed to schedule scan.'); } } } else { const res = await fetch('/api/scans/new', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ target_url: targetUrl, scan_type: scanType, auth_headers: parsedAuthHeaders, custom_headers: customHeaders, crawl_depth: crawlDepth, exclude_paths: excludePaths, enable_red_team: enableRedTeam }) }); const data = await res.json(); if (res.ok) { if (data.scan) { const existingActive = localStorage.getItem('wss_active_scan'); if (!existingActive) { localStorage.setItem('wss_active_scan', JSON.stringify(data.scan)); } } toast.success('Scan pipeline initiated successfully!'); navigate('/dashboard'); } else { if (res.status === 403 || res.status === 402 || data.message?.toLowerCase().includes('quota')) { setAttemptedScan(scanType); setShowQuotaExceededModal(true); } else { setError(data.message || 'Failed to initialize vulnerability scanning thread.'); } } } } catch (err) { setError('Connection timeout. Scanner microservice unavailable.'); console.error(err); } finally { setLoading(false); } }; const scanMethodologies = [ { id: 'Quick', title: 'Quick Scan', icon: 'bolt', desc: 'Rapid recon: HTTP headers audit, Nmap top-100 ports, SSLyze TLS check, technology fingerprinting & DNS lookup.', tools: ['Nmap', 'SSLyze', 'Headers', 'WHOIS'], duration: '~2-5 mins', price: '$4.99', colorClass: 'text-primary', requiredTier: 'free' }, { id: 'Advanced', title: 'Advanced Scan', icon: 'security', desc: 'Comprehensive deep crawl: All security modules, XSS/SQLi fuzzing, path traversal, Nuclei templates & OWASP ZAP passive analysis.', tools: ['Nuclei', 'ZAP Passive', 'Fuzzer', 'Dir Scan', 'Subfinder', 'Amass'], duration: '~20-40 mins', price: '$44.99', colorClass: 'text-primary', requiredTier: 'pro' }, { id: 'Deep', title: 'Deep Scan', icon: 'radar', desc: 'Exhaustive audit: All-port Nmap with vuln scripts, full TLS audit, OWASP ZAP active spider + active attack simulation.', tools: ['Nmap Full', 'ZAP Active', 'NSE Scripts', 'All Modules'], duration: '~1 hour+', price: '$99.99', colorClass: 'text-primary', requiredTier: 'enterprise' } ]; const getTierLevel = (tier) => { if (tier === 'enterprise') return 3; if (tier === 'pro') return 2; return 1; }; const userTierLevel = (user?.role === 'admin' || user?.role === 'super_admin') ? 3 : getTierLevel(user?.subscription_tier || 'free'); return (
{/* Page Header */}

Initiate Scan

Configure target parameters and execution methodology for a new vulnerability assessment.

{/* Configuration Form Card */}
{/* Error Alert Display */} {error && (
error
{error}
)} {/* Target Configuration */}
link setTargetUrl(e.target.value)} />

Ensure you have authorization to scan the specified domain or IP address.


{/* Scan Methodology Section */}

Select your scanning depth profile. Standard tiers include allocated vulnerability audit quotas.

{scanMethodologies.map((method) => { const config = scanConfig.find(c => c.scan_type === method.id); const requiredTier = config ? config.required_tier : method.requiredTier; const isEnabled = config ? config.is_enabled : true; const isSelected = scanType === method.id; const isQuotaAvailable = hasQuota(method.id); const isTierLocked = !isQuotaAvailable && (userTierLevel < getTierLevel(requiredTier)); const isQuotaExceeded = !isQuotaAvailable; const isLocked = isTierLocked || isQuotaExceeded; if (!isEnabled) { return (
block
Disabled
{method.title} Currently unavailable.
); } return (
{ if (isTierLocked) { setAttemptedScan(method.title); setShowUpgradeModal(true); return; } if (isQuotaExceeded) { setAttemptedScan(method.title); setShowQuotaExceededModal(true); return; } setScanType(method.id); }} className={`border rounded-lg p-md cursor-pointer transition-all flex flex-col gap-sm relative group ${ isLocked ? 'border-outline-variant bg-surface-container/50 hover:bg-surface-container opacity-70' : isSelected ? 'border-primary bg-primary/5 shadow-[0_0_0_1px_#2563eb]' : 'border-outline-variant bg-surface-container-lowest hover:bg-surface-container-low' }`} >
{isLocked ? (isQuotaExceeded ? 'workspace_premium' : 'lock') : method.icon}
{!isLocked && ( check_circle )} {isLocked && ( {isQuotaExceeded ? '0 Quota' : requiredTier} )}
{method.title} {method.price}
{method.desc} {method.tools && (
{method.tools.map(tool => ( {tool} ))}
)}
⏱ {method.duration} {method.id === 'Quick' ? '13 modules' : method.id === 'Advanced' ? '36 modules' : '89 modules'}
); })}

{/* Schedule Scan Section */}
{isScheduled && (
setScheduleTime(e.target.value)} />
)}

{/* Legal Warning Notice */}
Operator Notice & Policy Compliance Conducting vulnerability analysis scans against networks or hosts without explicit, verified written authorization is illegal. By executing this scan, you certify that you possess the necessary regulatory clearance to target this host.
{/* Action Area */}
{/* Subscription Tier Required Modal */} {showUpgradeModal && (
setShowUpgradeModal(false)}>

lock Subscription Required

You cannot use the {attemptedScan} methodology on your current plan.

If you need to use this feature, please upgrade your subscription plan to unlock advanced vulnerability scanning capabilities.

)} {/* Scan Quota Exceeded Modal Popup */} {showQuotaExceededModal && (
{/* Backdrop */}
setShowQuotaExceededModal(false)} >
{/* Modal Content */}
{/* Top Glowing Icon Circle */}
workspace_premium
{/* Header Badge */}
Quota Limit Reached (0 Scans Left)
{/* Modal Title */}

Scanning Quota Exhausted

{/* Modal Description */}

Your organization has used all allocated scan credits for {attemptedScan || scanType} Scans. To execute additional vulnerability scans, please upgrade your plan or purchase scan credits.

{/* Action Buttons */}
)} {/* Confirm Scan Execution Modal Popup */} {showConfirmModal && (
{/* Backdrop */}
setShowConfirmModal(false)} >
{/* Modal Content */}
{/* Header */}
alternate_email

Confirm Scan Execution

Review target parameters before starting the scan pipeline

{/* Target Parameters Card */}
TARGET URL {targetUrl}
SCAN INTENSITY {scanType} Scan
EXECUTION TYPE {isScheduled ? 'Scheduled Execution' : 'Immediate Execution'}
{/* Confirmation Checkbox & Policy Link */}
{hasReadPolicy ? ( check_circle Security Policy Read & Accepted ) : ( )}
{/* Warning Alert Box */}
help_outline
Are you sure you want to run this scan on {targetUrl}? If you are sure, read the security policy to enable the confirmation box, check it, and click Yes, Start Scan.
{/* Action Buttons */}
)} {/* Security Policy & Legal Disclaimer Modal */} {showPolicyModal && (
{/* Backdrop */}
setShowPolicyModal(false)} >
{/* Modal Content */}
{/* Modal Header */}
gavel

Security Policy & Legal Disclaimer

{/* Modal Body - Policy Content (Scrollable) */}
Effective Date: August 15, 2026
Applies to: All users of the Larshield vulnerability scanning platform ("the Service")

1. Explicit Authorization and Legal Compliance

By initiating any scan, probe, or assessment through Larshield, you explicitly certify, represent, and warrant that you possess full, documented, and legally verifiable authorization from the owner of the target system to conduct active security assessments, penetration testing, or vulnerability scanning against it.

You acknowledge that scanning any computer, network, or application without proper authorization is illegal under applicable law — including, without limitation, the Computer Fraud and Abuse Act (US), the Computer Misuse Act (UK), the Information Technology Act (India), and equivalent statutes in other jurisdictions. Larshield is intended strictly for authorized security testing, such as systems you own, systems within a scope you have been contractually engaged to test, or environments explicitly designated for security research (e.g., CTF ranges, bug bounty programs with defined scope).

2. Assumption of Risk & Potential Impact

You acknowledge that vulnerability scanning and penetration testing are inherently intrusive activities. Depending on configuration, they may involve port scanning, service fingerprinting, exploitation simulation, or payload delivery, any of which could cause service degradation, data loss, or downtime on the target system.

By using Larshield, you accept full responsibility for any operational impact resulting from your use of the tool, and you agree to take reasonable precautions (e.g., scheduling scans during maintenance windows, using rate-limited or passive modes where appropriate) when testing production systems.

3. Indemnification and Hold Harmless

You agree to indemnify, defend, and hold harmless the Larshield project, its developer(s), contributors, and affiliates from any claims, damages, liabilities, costs, or losses (including reasonable legal fees) arising from your use of the Service — including any unauthorized or improper use.

Larshield is provided on an "AS IS" and "AS AVAILABLE" basis, without warranties of any kind, express or implied, including but not limited to fitness for a particular purpose or non-infringement. Larshield and its creators shall not be liable for any direct, indirect, incidental, or consequential damages resulting from use or misuse of the Service.

4. Audit Logging and Cooperation with Authorities

Larshield logs scan activity, including origin IP address, timestamp, scan configuration, and target parameters, for security, abuse-prevention, and accountability purposes.

In the event of an investigation into unauthorized access, abuse, or a legal inquiry, Larshield reserves the right to share relevant audit logs with law enforcement, hosting providers, or the affected system owner, as required or permitted by law.

5. Acceptable Use

You agree not to use Larshield to:

  • Scan or test any system without documented authorization from its owner
  • Deliver malicious payloads intended to cause damage beyond what is necessary for a legitimate, authorized assessment
  • Circumvent rate limits or access controls of third-party systems outside an agreed testing scope

6. Data Handling

Scan results are stored per-user and are not shared with third parties except as required under Section 4.

7. Changes to This Policy

Larshield may update this policy from time to time. Continued use of the Service after changes are posted constitutes acceptance of the revised policy.

By clicking "I Accept" below, you confirm that you have read, understood, and agree to be bound by this Security Policy & EULA.

{/* Checkbox Section inside Modal */}
{/* Modal Footer */}
)}
); };