import React, { useState, useEffect, useRef } from 'react'; import { Terminal, Wifi, ShieldCheck, AlertCircle, HelpCircle, X } from 'lucide-react'; const RecordTypes = { 1: 'A', 2: 'NS', 5: 'CNAME', 6: 'SOA', 12: 'PTR', 15: 'MX', 16: 'TXT', 28: 'AAAA', }; // Simple mapping for reverse lookups in arguments const RecordTypeStr = { 'a': 'A', 'aaaa': 'AAAA', 'mx': 'MX', 'txt': 'TXT', 'ns': 'NS', 'cname': 'CNAME', 'ptr': 'PTR', 'soa': 'SOA' }; export default function App() { const [history, setHistory] = useState([ { type: 'system', content: 'Initializing Virtual DNS Terminal v1.0.4...' }, { type: 'system', content: 'Connecting to DNS-over-HTTPS Gateway...' }, { type: 'success', content: 'Connection Established (via dns.google).' }, { type: 'info', content: 'Type "help" for available commands.' }, { type: 'break', content: '' }, ]); const [input, setInput] = useState(''); const [isLoading, setIsLoading] = useState(false); const [showHints, setShowHints] = useState(false); const endRef = useRef(null); const inputRef = useRef(null); // Auto-scroll to bottom useEffect(() => { endRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [history]); // Focus input on click const handleContainerClick = () => { // Only focus if text is not being selected if (!window.getSelection().toString()) { inputRef.current?.focus(); } }; const addToHistory = (type, content) => { setHistory(prev => [...prev, { type, content }]); }; const performNslookup = async (args) => { if (args.length === 0) { addToHistory('error', 'usage: nslookup [type]'); return; } const domain = args[0]; let type = 'A'; // Default // Check for optional type argument (e.g., nslookup google.com mx) if (args.length > 1) { const requestedType = args[1].toLowerCase(); if (RecordTypeStr[requestedType]) { type = RecordTypeStr[requestedType]; } } setIsLoading(true); // Mimic network latency slightly for realism await new Promise(r => setTimeout(r, 400)); try { const response = await fetch(`https://dns.google/resolve?name=${domain}&type=${type}`); const data = await response.json(); // Mimic standard nslookup output header addToHistory('output', `Server:\t\tdns.google`); addToHistory('output', `Address:\t8.8.8.8#53`); addToHistory('break', ''); if (data.Status !== 0) { addToHistory('error', `** server can't find ${domain}: NXDOMAIN (Non-Existent Domain)`); } else { addToHistory('output', `Non-authoritative answer:`); if (data.Answer) { data.Answer.forEach(record => { const rType = RecordTypes[record.type] || record.type; // Format output based on record type to match nslookup style if (rType === 'MX') { addToHistory('output', `Name:\t${record.name}`); addToHistory('output', `MX preference = ${record.data.split(' ')[0]}, mail exchanger = ${record.data.split(' ')[1]}`); } else if (rType === 'A' || rType === 'AAAA') { addToHistory('output', `Name:\t${record.name}`); addToHistory('output', `Address:\t${record.data}`); } else if (rType === 'CNAME') { addToHistory('output', `${record.name}\tcanonical name = ${record.data}.`); } else if (rType === 'TXT') { addToHistory('output', `${record.name}\ttext = "${record.data.replace(/"/g, '')}"`); // Clean quotes } else { addToHistory('output', `Name:\t${record.name}`); addToHistory('output', `${rType}:\t${record.data}`); } addToHistory('break', ''); }); } else { // Sometimes Authority section has info even if no Answer addToHistory('info', `No ${type} records found for ${domain}.`); } } } catch (err) { addToHistory('error', `DNS request failed: ${err.message}`); } finally { setIsLoading(false); } }; const handleCommand = async (e) => { if (e.key === 'Enter') { const cmdLine = input.trim(); if (!cmdLine) return; // Add the command itself to history setHistory(prev => [...prev, { type: 'command', content: cmdLine }]); setInput(''); const parts = cmdLine.split(/\s+/); const command = parts[0].toLowerCase(); const args = parts.slice(1); switch (command) { case 'clear': case 'cls': setHistory([]); break; case 'help': addToHistory('info', 'Available commands:'); addToHistory('info', ' nslookup [type] - Query DNS records (A, MX, TXT, etc)'); addToHistory('info', ' clear - Clear terminal'); addToHistory('info', ' whoami - Display current user'); addToHistory('info', ' ip - Show your public IP (simulated)'); break; case 'nslookup': await performNslookup(args); break; case 'whoami': addToHistory('output', 'visitor@virtual-terminal'); break; case 'ip': addToHistory('output', 'Requesting public IP...'); try { const ipRes = await fetch('https://api.ipify.org?format=json'); const ipData = await ipRes.json(); addToHistory('success', `Your IP: ${ipData.ip}`); } catch (e) { addToHistory('error', 'Could not resolve public IP.'); } break; default: addToHistory('error', `Command not found: ${command}. Type 'help' for options.`); } } }; const renderContent = (item, index) => { switch (item.type) { case 'command': return (
visitor@term:~$ {item.content}
); case 'system': return
{item.content}
; case 'success': return
{item.content}
; case 'error': return
{item.content}
; case 'info': return
{item.content}
; case 'break': return
; case 'output': default: // Pre-wrap preserves whitespace/tabs for columns return
{item.content}
; } }; return (
{/* Title Bar */}
bash — 80x24
Connected
{/* Terminal Body */}
{/* Hints Overlay */} {showHints && (

Quick Reference

DNS & System Commands

Look up an IP:

nslookup google.com

Check Mail Servers (MX):

nslookup github.com mx

Check Text Records (TXT):

nslookup openai.com txt

Other Utilities:

  • whoami - Current user
  • ip - Your public IP
  • clear - Reset screen
)} {history.map((item, idx) => renderContent(item, idx))} {/* Active Input Line */}
visitor@term:~$
setInput(e.target.value)} onKeyDown={handleCommand} disabled={isLoading} autoFocus className="w-full bg-transparent border-none outline-none text-gray-100 font-mono p-0 m-0 z-10 relative" autoComplete="off" spellCheck="false" />
{isLoading && (
Requesting records...
)}

This is a virtual terminal. DNS queries are performed via the Google DNS-over-HTTPS API.

); }