Spaces:
Paused
Paused
| import os | |
| import subprocess | |
| import urllib.request | |
| import json | |
| import time | |
| def run_cmd(cmd): | |
| try: | |
| return subprocess.check_output(cmd, shell=True, text=True, stderr=subprocess.STDOUT) | |
| except subprocess.CalledProcessError as e: | |
| return e.output | |
| with open("raw_snapshot.txt", "w", encoding="utf-8") as out: | |
| out.write("=== SECTION 1: CURRENT CODEBASE STATE ===\n") | |
| out.write("Git Log:\n") | |
| out.write(run_cmd("git log --oneline -10")) | |
| out.write("\nGit Status:\n") | |
| out.write(run_cmd("git status")) | |
| out.write("\nLines of Code:\n") | |
| counts = {'py': 0, 'ts': 0, 'js': 0, 'jsx': 0, 'html': 0} | |
| for root, dirs, files in os.walk('.'): | |
| dirs[:] = [d for d in dirs if d not in ['node_modules', '.git', 'dist', '__pycache__']] | |
| for f in files: | |
| ext = f.split('.')[-1] | |
| if ext in counts: | |
| try: | |
| with open(os.path.join(root, f), encoding='utf-8', errors='ignore') as file: | |
| counts[ext] += sum(1 for _ in file) | |
| except: pass | |
| for ext, count in counts.items(): | |
| out.write(f'{ext}: {count} lines\n') | |
| out.write(f'Total: {sum(counts.values())} lines\n') | |
| out.write("\n=== SECTION 2: LIVE ENDPOINT STATUS ===\n") | |
| PYTHON = 'https://opticparse-python-sg.onrender.com' | |
| NODE = 'https://opticparse-1opticparse-node-sg.onrender.com' | |
| endpoints = [ | |
| ('GET', f'{PYTHON}/health', None), | |
| ('GET', f'{NODE}/health', None), | |
| ('POST', f'{NODE}/api/phish-detect', json.dumps({'url': 'https://google.com'}).encode()), | |
| ] | |
| for method, url, data in endpoints: | |
| try: | |
| start = time.time() | |
| req = urllib.request.Request(url, method=method, data=data, headers={'Content-Type': 'application/json'}) | |
| res = urllib.request.urlopen(req, timeout=60) | |
| elapsed = time.time() - start | |
| body = res.read().decode()[:300] | |
| out.write(f'β {method} {url.split(".com")[1]} β {res.status} ({elapsed:.1f}s)\n') | |
| out.write(f' Body: {body}\n') | |
| except urllib.error.HTTPError as e: | |
| out.write(f'β {method} {url.split(".com")[1]} β {e.code}\n') | |
| out.write(f' Error: {e.read().decode()[:200]}\n') | |
| except Exception as e: | |
| out.write(f'β {url.split(".com")[1]} β {str(e)[:100]}\n') | |
| out.write("\n=== SECTION 3: SECURITY FEATURES STATUS ===\n") | |
| with open('server.py', 'r', encoding='utf-8') as f: py = f.read() | |
| with open('opticparse-js/src/phish-server.ts', 'r', encoding='utf-8') as f: ts = f.read() | |
| checks = { | |
| 'SSRF isSafeUrl (Node)': 'isSafeUrl' in ts, | |
| 'SSRF url validation (Python)': 'Internal network URLs not allowed' in py, | |
| 'Input validation ScrapeRequest': '@validator' in py or 'BaseModel' in py, | |
| 'API key format check (op_live_)': 'op_live_' in py, | |
| 'Rate limiting (Python slowapi)': 'slowapi' in py or 'limiter' in py, | |
| 'Rate limiting (Node express-rate-limit)': 'rate' in ts.lower(), | |
| 'Trust proxy (Node)': 'trust proxy' in ts, | |
| 'Webhook HMAC verification': 'hmac' in py.lower(), | |
| 'CORS middleware (Python)': 'CORSMiddleware' in py or 'cors' in py.lower(), | |
| 'Helmet security headers (Node)': 'helmet' in ts.lower(), | |
| 'Browser hardening args (Node)': 'disable-extensions' in ts, | |
| 'Browserless integration': 'connect_over_cdp' in py or 'browserless' in py.lower(), | |
| 'Graceful DB fallback': 'watch feature' in py.lower() or 'Database init failed' in py, | |
| 'AI Gateway URLs': 'gateway.ai.cloudflare.com' in py, | |
| 'Usage limit enforcement': 'monthly_limit' in py, | |
| 'PhishVision full JSON response': 'confidence_score_percentage' in ts, | |
| 'wait_until load default': 'wait_until: str = "load"' in py or "wait_until = 'load'" in py or 'load' in py, | |
| } | |
| all_pass = True | |
| for check, result in checks.items(): | |
| status = 'β ' if result else 'β' | |
| if not result: all_pass = False | |
| out.write(f' {status} {check}\n') | |
| out.write(f'\nOverall: {"β ALL CHECKS PASSED" if all_pass else "β SOME CHECKS FAILED"}\n') | |
| out.write("\n=== SECTION 4: ENVIRONMENT & CONFIG CHECK ===\n") | |
| files = ['server.py', 'requirements.txt', 'Dockerfile', 'render.yaml', 'opticparse-js/src/phish-server.ts', 'opticparse-js/package.json', 'dashboard/src/App.jsx', 'dashboard/.env.production', 'docs/index.html', 'docs/privacy.html', 'docs/terms.html', 'docs/404.html', 'docs/sitemap.xml', 'docs/robots.txt', 'docs/_headers', 'supabase/migrations/001_initial_schema.sql', 'supabase/migrations/002_rls_watches_monitors.sql'] | |
| for f in files: | |
| status = 'β ' if os.path.exists(f) else 'β' | |
| out.write(f' {status} {f}\n') | |
| out.write('\n=== render.yaml Environment Variables ===\n') | |
| if os.path.exists('render.yaml'): | |
| import re | |
| with open('render.yaml') as f: content = f.read() | |
| keys = re.findall(r'key:\s*(\S+)', content) | |
| for k in sorted(set(keys)): out.write(f' - {k}\n') | |
| out.write("\n=== SECTION 5: DEPENDENCY SECURITY ===\n") | |
| out.write("Python audit:\n") | |
| out.write(run_cmd("pip-audit -r requirements.txt | Select-Object -Last 20")) | |
| out.write("\nNode audit (opticparse-js):\n") | |
| out.write(run_cmd("cd opticparse-js ; npm audit --audit-level=high | Select-Object -Last 20")) | |
| out.write("\nDashboard audit:\n") | |
| out.write(run_cmd("cd dashboard ; npm audit --audit-level=high | Select-Object -Last 20")) | |
| out.write("\n=== SECTION 6: LANDING PAGE AUDIT ===\n") | |
| if os.path.exists('docs/index.html'): | |
| with open('docs/index.html', 'r', encoding='utf-8') as f: content = f.read() | |
| checks = { | |
| 'No GPT-4o claim': 'GPT-4o' not in content, | |
| 'opticparse.com domain used': 'opticparse.com' in content, | |
| 'Dashboard link correct': 'dashboard.opticparse.com' in content, | |
| 'Privacy policy linked': 'privacy' in content.lower(), | |
| 'Terms of service linked': 'terms' in content.lower(), | |
| 'LemonSqueezy checkout URL': 'lemonsqueezy.com' in content, | |
| 'No 2s false claim': '<2s' not in content, | |
| 'No RapidAPI buttons': 'Try Free on RapidAPI' not in content, | |
| 'Schema accuracy stat': 'Schema Accuracy' in content, | |
| 'Copyright 2026': '2026' in content, | |
| 'Google verification tag': 'google-site-verification' in content, | |
| 'Cloudflare analytics': 'cloudflareinsights' in content or 'cf-beacon' in content, | |
| 'Open Graph tags': 'og:title' in content, | |
| 'Twitter card tags': 'twitter:card' in content, | |
| 'DNS prefetch tags': 'dns-prefetch' in content, | |
| 'PhishVision mentioned': 'PhishVision' in content, | |
| 'Sitemap linked': 'sitemap' in content.lower(), | |
| } | |
| all_pass = True | |
| for check, result in checks.items(): | |
| status = 'β ' if result else 'β' | |
| if not result: all_pass = False | |
| out.write(f' {status} {check}\n') | |
| out.write(f' Overall: {"ALL PASS" if all_pass else "SOME FAILED"}\n') | |
| out.write("\n=== SECTION 7: DATABASE SECURITY ===\n") | |
| SUPABASE_URL = 'https://xxmvhvxeglsjbewlouqg.supabase.co' | |
| anon_key = "" | |
| if os.path.exists('dashboard/.env.production'): | |
| with open('dashboard/.env.production') as f: | |
| for line in f: | |
| if 'VITE_SUPABASE_ANON_KEY' in line: | |
| anon_key = line.split('=', 1)[1].strip().strip('"').strip("'") | |
| if anon_key: | |
| try: | |
| req = urllib.request.Request(f'{SUPABASE_URL}/rest/v1/users?select=*', headers={'apikey': anon_key, 'Authorization': f'Bearer {anon_key}'}) | |
| res = urllib.request.urlopen(req) | |
| data = json.loads(res.read()) | |
| if len(data) == 0: out.write(' β RLS on users: ENFORCED\n') | |
| else: out.write(f' β RLS BREACH: {len(data)} users exposed\n') | |
| except Exception as e: | |
| out.write(f' β RLS on users: ENFORCED ({str(e)[:50]})\n') | |
| try: | |
| req2 = urllib.request.Request(f'{SUPABASE_URL}/rest/v1/api_keys?select=*', headers={'apikey': anon_key, 'Authorization': f'Bearer {anon_key}'}) | |
| res2 = urllib.request.urlopen(req2) | |
| data2 = json.loads(res2.read()) | |
| if len(data2) == 0: out.write(' β RLS on api_keys: ENFORCED\n') | |
| else: out.write(f' β RLS BREACH: {len(data2)} keys exposed\n') | |
| except Exception as e: | |
| out.write(f' β RLS on api_keys: ENFORCED ({str(e)[:50]})\n') | |
| else: | |
| out.write(" β Could not find anon key for RLS testing\n") | |
| out.write("\n=== SECTION 8: WHAT IS MISSING/TODO ===\n") | |
| missing = [ | |
| ('Bank account', 'No Indian bank account β blocks payments'), | |
| ('LemonSqueezy live mode', 'Test mode only β no real payments'), | |
| ('MCA Incorporation', 'Not incorporated β blocks govt grants'), | |
| ('DPIIT Recognition', 'Needs incorporation first'), | |
| ('Twitter/X account', 'No social media presence'), | |
| ('First blog post', 'No content marketing yet'), | |
| ('ProductHunt preparation', 'Not started'), | |
| ('First paying customer', 'Zero revenue'), | |
| ('AWS Activate', 'Application pending β email issue'), | |
| ('Google Cloud Startups', 'Not submitted yet'), | |
| ('NVIDIA Inception', 'Needs incorporation'), | |
| ('Payment security prompt', 'Deferred until LemonSqueezy live'), | |
| ] | |
| for item, reason in missing: | |
| out.write(f' β {item}: {reason}\n') | |