// Admin views: Dashboard, Domains, Keys, Firehose, Abuse, Health, Audit, Settings // Wired to backend via window.tmApi (lib/tm-browser.js) // ================= DASHBOARD ================= const AdminDashboard = ({ toast }) => { const [data, setData] = React.useState(null); const [err, setErr] = React.useState(null); React.useEffect(() => { let cancel = false; tmApi.admin.overview().then((d) => { if (!cancel) setData(d); }).catch((e) => !cancel && setErr(e)); return () => { cancel = true; }; }, []); if (err) return ; if (!data) return ; const { stats, volumeHourly, topDomains } = data; return ( <>
{/* Stats grid */}
{stats.map((s) => (
{s.label}
{s.value}
{s.trend === 'up' ? '↗' : '↘'} {s.delta} 24h
))}
{/* Volume chart + Top domains */}
EMAIL VOLUME · 24H
16,482
{['1H', '24H', '7D', '30D'].map((t, i) => ( {t} ))}
00:0006:0012:0018:00NOW
TOP DOMAINS · 24H
{topDomains.map((d) => (
@{d.domain} {d.count.toLocaleString()}
))}
{/* Recent activity preview */}
RECENT FIREHOSE
LIVE
); }; const DashboardRecentFirehose = () => { const [items, setItems] = React.useState(null); React.useEffect(() => { let cancel = false; tmApi.admin.firehose.list({ limit: 5 }).then((r) => !cancel && setItems(r)).catch(() => !cancel && setItems([])); return () => { cancel = true; }; }, []); if (!items) return
Loading…
; if (items.length === 0) return
No mail yet
; return (
{items.map((f) => (
{f.ts} {f.from} {f.subject} {f.hasCode && ⚡ {f.code}} {!f.hasCode && }
))}
); }; // Shared loading + empty placeholders const AdminLoading = () => (
LOADING…
); const AdminEmpty = ({ title, detail }) => (
{title}
{detail &&
{detail}
}
); // ================= DOMAINS ================= const AdminDomains = ({ toast }) => { const [domains, setDomains] = React.useState(null); const [adding, setAdding] = React.useState(false); const [newDomain, setNewDomain] = React.useState(''); const [dnsModalDomain, setDnsModalDomain] = React.useState(null); const reload = () => tmApi.admin.domains.list().then(setDomains).catch((e) => toast('Load failed: ' + e.message)); React.useEffect(() => { reload(); }, []); if (!domains) return ; const toggle = async (id, enabled) => { try { await tmApi.admin.domains.patch(id, { enabled: !enabled }); reload(); toast('Domain toggled'); } catch (e) { toast('Toggle failed: ' + e.message); } }; const remove = async (id) => { try { await tmApi.admin.domains.remove(id); reload(); toast('Domain removed'); } catch (e) { toast('Remove failed: ' + e.message); } }; const add = async () => { if (!/^[a-z0-9][a-z0-9-]*(\.[a-z0-9][a-z0-9-]*)+$/i.test(newDomain)) return; const target = newDomain; try { await tmApi.admin.domains.create({ domain: target }); toast(`@${target} added`); setNewDomain(''); setAdding(false); reload(); setDnsModalDomain(target); // show DNS instructions } catch (e) { toast('Add failed: ' + e.message); } }; return ( <> d.enabled).length} enabled`}> setAdding(true)}> Add domain
{adding && (
setNewDomain(e.target.value.toLowerCase().trim())} onKeyDown={(e) => e.key === 'Enter' && add()} placeholder="example.com" style={{ flex: 1, background: '#0a0a0a', border: '1px solid #262626', color: '#EDEDED', fontFamily: "'JetBrains Mono', monospace", fontSize: 13, padding: '8px 12px', borderRadius: 5, outline: 'none' }} /> Add { setAdding(false); setNewDomain(''); }}>Cancel
)} {domains.map((d) => ( ))}
DOMAINSTATUSINBOXESEMAILS 24HSPAM SCORESTORAGEBADGESACTIONS
{d.premium && } @{d.domain}
{d.enabled ? 'ENABLED' : 'DISABLED'} {d.inboxes.toLocaleString()} {d.emails24h.toLocaleString()} 0.1 ? '#DC2626' : d.spamScore > 0.05 ? '#F59E0B' : '#10B981' }}>{d.spamScore.toFixed(2)} {d.storage}
{d.badges.map((b) => )}
setDnsModalDomain(d.domain)}>DNS toggle(d.id, d.enabled)}>{d.enabled ? 'Disable' : 'Enable'} remove(d.id)}>Remove
setDnsModalDomain(null)} toast={toast} /> ); }; // Shows the DNS records the operator must add at the domain's registrar so // inbound mail reaches the relay. Each field rendered separately because most // registrar UIs (Namecheap, Cloudflare, Route 53) have distinct inputs for // Type / Host / Mail Server / Priority — pasting `10 mx.example.com.` into // a single "Mail Server" field doesn't work. const SharedDomainDnsModal = ({ domain, onClose, toast }) => { if (!domain) return null; const relayHost = (typeof window !== 'undefined' && window.location.hostname) || 'zeromailer.cloud'; const mxTarget = 'mx.' + relayHost; const copy = (txt) => { navigator.clipboard?.writeText(txt); toast && toast('Copied'); }; // Color-coded label chips so each DNS field maps unambiguously to the // matching column in registrar UIs. const LABEL_COLORS = { TYPE: { bg: '#3a0e0e', border: '#5a1a1a', color: '#F87171' }, // red HOST: { bg: '#3a2a08', border: '#5c3e08', color: '#F59E0B' }, // orange VALUE: { bg: '#2a3a08', border: '#3e5c08', color: '#FACC15' }, // yellow 'MAIL SERVER': { bg: '#2a3a08', border: '#3e5c08', color: '#FACC15' }, // yellow (same family as value) PRIORITY: { bg: '#0c2a4a', border: '#1e3f6b', color: '#60A5FA' }, // blue }; const Chip = ({ label }) => { const c = LABEL_COLORS[label] || { bg: '#1a1a1a', border: '#262626', color: '#8A8A8A' }; return ( {label} ); }; const Field = ({ label, value }) => { const [copied, setCopied] = React.useState(false); const doCopy = () => { copy(value); setCopied(true); setTimeout(() => setCopied(false), 1200); }; return (
{value}
); }; const Card = ({ type, children, note }) => (
{children} {note &&
{note}
}
); return ( <>

DNS records for @{domain}

SET THESE AT THE REGISTRAR — MAIL WON'T FLOW UNTIL THEN

Open the DNS panel for {domain} at whichever registrar holds it (Namecheap, Cloudflare, Route 53, etc.) and add the records below. The relay will accept mail to anything@{domain} as soon as MX propagates (~5-30 min).

VERIFY WITH
dig {domain} MX +short dig {domain} TXT +short
); }; const Th = ({ children, style }) => {children}; const Label = ({ children }) => {children}; const td = { padding: '11px 16px', fontSize: 12, color: '#EDEDED' }; const tdMono = { ...td, fontFamily: "'JetBrains Mono', monospace", color: '#8A8A8A' }; // ================= KEYS ================= const AdminKeys = ({ toast, onInspect }) => { const [keys, setKeys] = React.useState(null); const [showGen, setShowGen] = React.useState(false); const [newLabel, setNewLabel] = React.useState(''); const [newExp, setNewExp] = React.useState('30d'); const [justCreatedCode, setJustCreatedCode] = React.useState(null); const reload = () => tmApi.admin.keys.list().then(setKeys).catch((e) => toast('Load failed: ' + e.message)); React.useEffect(() => { reload(); }, []); if (!keys) return ; const addKey = async () => { try { const result = await tmApi.admin.keys.create(newLabel, newExp); setJustCreatedCode(result.codeFull); // show full code ONCE reload(); setShowGen(false); setNewLabel(''); setNewExp('30d'); } catch (e) { toast('Generate failed: ' + e.message); } }; const revoke = async (id) => { try { await tmApi.admin.keys.revoke(id); reload(); toast('Key revoked'); } catch (e) { toast('Revoke failed: ' + e.message); } }; const copy = (code) => { navigator.clipboard?.writeText(code); toast('Code copied'); }; return ( <> k.status==='active').length} active`}> Export CSV setShowGen(true)}> Generate key {showGen && (
setNewLabel(e.target.value)} placeholder="Label (optional) — e.g. Alex beta" style={{ background: '#0a0a0a', border: '1px solid #262626', color: '#EDEDED', fontSize: 13, padding: '8px 12px', borderRadius: 5, outline: 'none' }} /> Generate setShowGen(false)}>Cancel
)} setJustCreatedCode(null)} toast={toast} />
{keys.map((k) => ( e.currentTarget.style.background = '#101010'} onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'} > ))}
CODELABELSTATUSCREATEDEXPIRESINBOXESEMAILSLAST SEENACTIONS
{k.code} {k.hasFullCode && ( )}
{k.label || } {k.created} {k.expires} {k.inboxes} {k.emails} {k.lastSeen}
onInspect(k)}> Activity {k.status === 'active' && revoke(k.id)}>Revoke}
); }; // Modal shown ONCE when a fresh access key is generated. The full code is // argon2-hashed in the DB so this is the only chance to copy it. const NewKeyModal = ({ code, onClose, toast }) => { const [acknowledged, setAcknowledged] = React.useState(false); const [copied, setCopied] = React.useState(false); React.useEffect(() => { if (code) { setAcknowledged(false); setCopied(false); } }, [code]); if (!code) return null; const doCopy = () => { navigator.clipboard?.writeText(code); setCopied(true); toast && toast('Code copied to clipboard'); }; return ( <>
FULL CODE — SHOWN ONCE

Copy this access code now. It's argon2-hashed in the database — once you close this dialog there is no way to retrieve it. If you lose it, you'll need to revoke this key and generate a new one.

{code}

The keys list will only show the redacted preview {code.slice(0,4)}-XXXX-XXXX-{code.slice(-4)} from now on.

); }; const StatusPill = ({ status }) => { const map = { active: { bg: '#0a1f1a', border: '#1a3f33', color: '#10B981' }, revoked: { bg: '#2a0e0e', border: '#5a1a1a', color: '#DC2626' }, expired: { bg: '#1a1a1a', border: '#262626', color: '#8A8A8A' }, unused: { bg: '#0c2a4a', border: '#1e3f6b', color: '#60A5FA' }, }; const s = map[status] || map.expired; return ( {status.toUpperCase()} ); }; // ================= FIREHOSE ================= const AdminFirehose = ({ toast }) => { const [stream, setStream] = React.useState([]); const [paused, setPaused] = React.useState(false); const [filter, setFilter] = React.useState(''); const [selected, setSelected] = React.useState(null); const [loaded, setLoaded] = React.useState(false); // Initial load React.useEffect(() => { let cancel = false; tmApi.admin.firehose.list({ limit: 50 }).then((r) => { if (cancel) return; setStream(r); setSelected(r[0] || null); setLoaded(true); }).catch((e) => { setLoaded(true); toast('Firehose load failed: ' + e.message); }); return () => { cancel = true; }; }, []); // Live WS stream React.useEffect(() => { if (paused) return; const conn = tmApi.openFirehose({ onEntry: (entry) => setStream((p) => [{ ...entry, isNew: true }, ...p].slice(0, 200)), onError: () => { /* will be retried on next mount */ }, }); return () => conn.close(); }, [paused]); const filtered = filter ? stream.filter(f => (f.from + f.subject + f.to + f.domain).toLowerCase().includes(filter.toLowerCase())) : stream; if (!loaded) return ; return ( <>
setFilter(e.target.value)} placeholder="Filter sender / subject / domain" style={{ background: '#141414', border: '1px solid #262626', color: '#EDEDED', fontFamily: "'JetBrains Mono', monospace", fontSize: 11, padding: '7px 10px 7px 26px', borderRadius: 5, outline: 'none', width: 260 }} />
setPaused(!paused)}> {paused ? <> Resume : <> Pause}
{/* Stream */}
{filtered.map((f) => (
setSelected(f)} style={{ display: 'grid', gridTemplateColumns: '70px 1fr auto 70px', gap: 10, padding: '9px 16px', borderBottom: '1px solid #141414', cursor: 'pointer', alignItems: 'center', background: selected?.id === f.id ? '#141414' : 'transparent', borderLeft: `2px solid ${selected?.id === f.id ? '#F59E0B' : f.flagged ? '#DC2626' : 'transparent'}`, animation: f.isNew ? 'newMail 1.8s ease' : 'none', }} onMouseEnter={(e) => selected?.id !== f.id && (e.currentTarget.style.background = '#101010')} onMouseLeave={(e) => selected?.id !== f.id && (e.currentTarget.style.background = 'transparent')} > {f.ts}
{f.flagged && } {f.from} {f.to}
{f.subject}
{f.hasCode ? ( ⚡ {f.code} ) : } {f.size}
))}
{/* Inspector */}
{selected ? ( <>
INSPECTION · {selected.id}
{selected.ts} {selected.from} {selected.to} {selected.domain} {selected.keyId} {selected.size} {selected.flagged ? 'YES' : 'NO'} {selected.hasCode && (<>{selected.code})}
SUBJECT
{selected.subject}
BODY PREVIEW

Hello,

{selected.hasCode ? `Your verification code is ${selected.code}.` : 'Thanks for using our service. This is a preview of the message body as it would appear to the recipient.'}

— {selected.from}

Full MIME Flag Block sender
) :
Select a message
}
); }; // ================= ABUSE ================= const AdminAbuse = ({ toast }) => { const [blocks, setBlocks] = React.useState(null); const [adding, setAdding] = React.useState(false); const [pattern, setPattern] = React.useState(''); const [reason, setReason] = React.useState(''); const reload = () => tmApi.admin.blocks.list().then(setBlocks).catch((e) => toast('Load failed: ' + e.message)); React.useEffect(() => { reload(); }, []); if (!blocks) return ; const add = async () => { if (!pattern) return; try { await tmApi.admin.blocks.create({ pattern, reason }); toast('Block rule added'); setAdding(false); setPattern(''); setReason(''); reload(); } catch (e) { toast('Add failed: ' + e.message); } }; const remove = async (id) => { try { await tmApi.admin.blocks.remove(id); reload(); toast('Block removed'); } catch (e) { toast('Remove failed: ' + e.message); } }; return ( <> setAdding(true)}> Add block {adding && (
setPattern(e.target.value)} placeholder="spammer@example.com or @*.ml" style={{ background: '#0a0a0a', border: '1px solid #262626', color: '#EDEDED', fontFamily: "'JetBrains Mono', monospace", fontSize: 13, padding: '8px 12px', borderRadius: 5, outline: 'none' }} /> setReason(e.target.value)} placeholder="Reason" style={{ background: '#0a0a0a', border: '1px solid #262626', color: '#EDEDED', fontSize: 13, padding: '8px 12px', borderRadius: 5, outline: 'none' }} /> Block setAdding(false)}>Cancel
)}
{blocks.map((b) => ( ))}
KINDPATTERNHITSREASONADDEDACTIONS
{b.kind.toUpperCase()} {b.pattern} {b.hits} {b.reason || } {b.added} remove(b.id)}>Remove
); }; // ================= HEALTH ================= const AdminHealth = () => { const [health, setHealth] = React.useState(null); React.useEffect(() => { tmApi.admin.health().then(setHealth).catch(() => setHealth([])); const t = setInterval(() => tmApi.admin.health().then(setHealth).catch(() => {}), 30000); return () => clearInterval(t); }, []); if (!health) return ; return ( <> h.status==='ok').length}/${health.length} ok`} />
{health.map((h) => (
{h.label}
{h.detail}
{h.uptime}
))}
); }; // ================= AUDIT ================= const AdminAudit = () => { const [events, setEvents] = React.useState(null); React.useEffect(() => { tmApi.admin.audit({ limit: 100 }).then(setEvents).catch(() => setEvents([])); }, []); if (!events) return ; return ( <>
{events.map((a) => ( ))}
TIMESTAMPACTORACTIONTARGETMETA
{a.ts} {a.actor} {a.action} {a.target} {a.meta}
); }; // ================= SETTINGS ================= const AdminSettings = ({ toast }) => { const [s, setS] = React.useState(null); React.useEffect(() => { tmApi.admin.settings.get().then(setS).catch((e) => toast('Load failed: ' + e.message)); }, []); if (!s) return ; const save = async () => { try { const updated = await tmApi.admin.settings.update(s); setS(updated); toast('Settings saved'); } catch (e) { toast('Save failed: ' + e.message); } }; return ( <> Save changes
setS({...s, sharedRetention: v})} /> setS({...s, customRetention: v})} /> setS({...s, maxAttempts: v})} /> setS({...s, rateLimitWin: v})} /> setS({...s, sessionTTL: v})} /> setS({...s, smtpHost: v})} /> setS({...s, maxAttachMB: v})} /> setS({...s, autoFlagSpam: v})} /> setS({...s, webhookUrl: v})} placeholder="https://…" />
); }; const SettingsGroup = ({ label, children }) => (
{label}
{children}
); const SRow = ({ label, children }) => (
{label}{children}
); const NumInput = ({ value, onChange }) => onChange(Number(e.target.value))} style={{ background: '#0a0a0a', border: '1px solid #262626', color: '#EDEDED', fontFamily: "'JetBrains Mono', monospace", fontSize: 12, padding: '6px 10px', borderRadius: 4, outline: 'none', width: 100, textAlign: 'right' }} />; const TxtInput = ({ value, onChange, placeholder }) => onChange(e.target.value)} placeholder={placeholder} style={{ background: '#0a0a0a', border: '1px solid #262626', color: '#EDEDED', fontFamily: "'JetBrains Mono', monospace", fontSize: 12, padding: '6px 10px', borderRadius: 4, outline: 'none', width: 280 }} />; // ================= KEY ACTIVITY DRAWER ================= const KeyActivityDrawer = ({ keyObj, onClose, toast }) => { if (!keyObj) return null; const [selected, setSelected] = React.useState(null); const [keyFirehose, setKeyFirehose] = React.useState([]); React.useEffect(() => { let cancel = false; tmApi.admin.keys.activity(keyObj.id).then((r) => !cancel && setKeyFirehose(r.messages || [])) .catch(() => !cancel && setKeyFirehose([])); return () => { cancel = true; }; }, [keyObj.id]); return ( <>
KEY ACTIVITY
{keyObj.code}
{keyObj.label &&
{keyObj.label}
}
{/* Stat strip */}
{[['INBOXES', keyObj.inboxes], ['EMAILS', keyObj.emails], ['LAST IP', keyObj.ip], ['LAST SEEN', keyObj.lastSeen]].map(([l, v]) => (
{l}
{v}
))}
ALL MESSAGES · {keyFirehose.length}
{keyFirehose.length === 0 ? (
No activity yet
) : keyFirehose.map((f) => (
setSelected(f)} style={{ padding: '10px 24px', borderBottom: '1px solid #151515', cursor: 'pointer', background: selected?.id === f.id ? '#141414' : 'transparent' }}>
{f.from}{f.ts}
{f.subject}
))}
{selected && (
MESSAGE INSPECT
FROM: {selected.from}
TO: {selected.to}
TS: {selected.ts}

{selected.subject}

{selected.hasCode ? `Your verification code is ${selected.code}.` : 'Full email body would render here, sanitized and sandboxed.'}

)}
); }; Object.assign(window, { AdminDashboard, AdminDomains, AdminKeys, AdminFirehose, AdminAbuse, AdminHealth, AdminAudit, AdminSettings, KeyActivityDrawer });