/* Unggoy Loader - React Frontend */ const { useState, useEffect, useRef, useCallback } = React; const { createPortal } = ReactDOM; const APP_BUILD = 'web'; const API_BASE = '/api'; // ===== Auth Token Storage ===== function getToken() { return localStorage.getItem('unggoy_token'); } function setToken(token) { localStorage.setItem('unggoy_token', token); } function clearToken() { localStorage.removeItem('unggoy_token'); localStorage.removeItem('unggoy_username'); localStorage.removeItem('unggoy_role'); localStorage.removeItem('unggoy_tier'); } function getStoredUsername() { return localStorage.getItem('unggoy_username') || ''; } function setStoredUsername(username) { localStorage.setItem('unggoy_username', username); } function getStoredRole() { return localStorage.getItem('unggoy_role') || 'viewer'; } function setStoredRole(role) { localStorage.setItem('unggoy_role', role); } function getStoredTier() { return parseInt(localStorage.getItem('unggoy_tier') || '1', 10); } function setStoredTier(tier) { localStorage.setItem('unggoy_tier', String(tier)); } // ===== Tier helpers ===== var TIER_BADGE_NAMES = {1: 'BASIC', 2: 'STANDARD', 3: 'PREMIUM', 4: 'VIP'}; function TierBadge({ tier }) { var name = TIER_BADGE_NAMES[tier] || 'BASIC'; return ( {name} ); } function TierRequiredTag({ tier }) { var name = TIER_BADGE_NAMES[tier] || 'BASIC'; return ( {'\uD83D\uDD12'} {name} ); } // ===== API Helpers ===== async function apiFetch(path, options) { const token = getToken(); const headers = (options && options.headers) ? { ...options.headers } : {}; if (token) { headers['Authorization'] = 'Bearer ' + token; } const mergedOptions = { ...options, headers }; const resp = await fetch(API_BASE + path, mergedOptions); // On 401, clear token and trigger re-render if (resp.status === 401) { clearToken(); window.dispatchEvent(new Event('unggoy-auth-expired')); const err = await resp.json().catch(() => ({ error: 'Not authenticated' })); throw new Error(err.detail?.error || err.error || 'Not authenticated'); } if (!resp.ok) { const err = await resp.json().catch(() => ({ error: resp.statusText })); throw new Error(err.detail?.error || err.error || resp.statusText); } return resp.json(); } // Authenticated raw fetch (for FormData uploads) async function authFetch(url, options) { const token = getToken(); const headers = (options && options.headers) ? { ...options.headers } : {}; if (token) { headers['Authorization'] = 'Bearer ' + token; } const mergedOptions = { ...options, headers }; const resp = await fetch(url, mergedOptions); if (resp.status === 401) { clearToken(); window.dispatchEvent(new Event('unggoy-auth-expired')); throw new Error('Not authenticated'); } return resp; } async function downloadWithAuth(url, filename) { try { var resp = await authFetch(url, {}); if (!resp.ok) throw new Error('Download failed: ' + resp.status); var blob = await resp.blob(); var blobUrl = URL.createObjectURL(blob); var a = document.createElement('a'); a.href = blobUrl; a.download = filename || 'download'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(blobUrl); } catch (err) { console.error('Download error:', err); } } function pad(n) { return n < 10 ? '0' + n : '' + n; } function timestamp() { const now = new Date(); return '[' + pad(now.getHours()) + ':' + pad(now.getMinutes()) + ':' + pad(now.getSeconds()) + ']'; } function getFileSubtitle(filename) { const ext = filename.split('.').pop().toLowerCase(); switch (ext) { case 'exe': return 'Main Executable'; case 'bmp': return 'Steganography Payload Container'; case 'dll': return 'Dynamic Library'; case 'bin': return 'Binary Data'; default: return 'Supplementary File'; } } function formatDate(ts) { if (!ts) return '--'; const d = new Date(ts * 1000); return d.toLocaleDateString() + ' ' + d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); } // ===== Role helpers ===== function canBuild(role) { return role === 'admin' || role === 'operator' || role === 'user'; } function isAdmin(role) { return role === 'admin'; } function isTierRestricted(role) { return role === 'user'; } // ===== Login Screen ===== function LoginScreen({ onLogin }) { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(''); const [loading, setLoading] = useState(false); const usernameRef = useRef(null); useEffect(() => { if (usernameRef.current) usernameRef.current.focus(); }, []); async function handleSubmit(e) { e.preventDefault(); if (!username.trim() || !password) { setError('Username and password are required.'); return; } setLoading(true); setError(''); try { const resp = await fetch(API_BASE + '/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: username.trim(), password }), }); if (!resp.ok) { const err = await resp.json().catch(() => ({})); throw new Error(err.detail?.error || 'Login failed'); } const data = await resp.json(); setToken(data.token); setStoredUsername(data.username); setStoredRole(data.role || 'viewer'); setStoredTier(data.tier || 1); onLogin(data.username, data.role || 'viewer', data.tier || 1, data.must_change_password || false); } catch (err) { setError(err.message || 'Login failed'); } finally { setLoading(false); } } return (

UNGGOY LOADER

AUTHENTICATION REQUIRED
{error && (
{'\u26A0'} {error}
)}
setUsername(e.target.value)} autoComplete="username" spellCheck={false} disabled={loading} />
setPassword(e.target.value)} autoComplete="current-password" disabled={loading} />
SECURE ACCESS ONLY
); } // ===== Reusable Components ===== function SectionHeader({ title, style }) { return (
{'\u25B8'} {title}
); } function Divider({ style }) { return
; } function RoleBadge({ role }) { return ( {role.toUpperCase()} ); } function FileInput({ label, accept, fileState, onFileChange, displayName, disabled, children }) { const inputRef = useRef(null); const handleChange = (e) => { if (e.target.files && e.target.files.length > 0) { onFileChange(e.target.files[0]); } else { onFileChange(null); } }; return (
{displayName || 'No file selected'} {children}
); } // ===== File Manager ===== function formatFileSize(bytes) { if (bytes === 0) return '0 B'; var units = ['B', 'KB', 'MB', 'GB']; var i = Math.floor(Math.log(bytes) / Math.log(1024)); if (i >= units.length) i = units.length - 1; return (bytes / Math.pow(1024, i)).toFixed(i === 0 ? 0 : 1) + ' ' + units[i]; } var FILE_CATEGORIES = [ { key: 'payload', label: 'PAYLOAD' }, { key: 'cover', label: 'COVER' }, { key: 'icon', label: 'ICON' }, { key: 'host_pe', label: 'HOST PE' }, { key: 'signature', label: 'SIGNATURE' }, ]; function FileManager({ serverDefaults, onDefaultsChanged, disabled }) { var [collapsed, setCollapsed] = useState(true); var [activeCategory, setActiveCategory] = useState('payload'); var [files, setFiles] = useState([]); var [defaults, setDefaults] = useState(serverDefaults || {}); var [loading, setLoading] = useState(false); var [uploading, setUploading] = useState(false); var [dragover, setDragover] = useState(false); var [deleteConfirm, setDeleteConfirm] = useState(null); var fileInputRef = useRef(null); // Sync defaults from parent useEffect(function() { setDefaults(serverDefaults || {}); }, [serverDefaults]); // Load files when category changes useEffect(function() { loadFiles(); }, [activeCategory]); function loadFiles() { setLoading(true); apiFetch('/files?category=' + encodeURIComponent(activeCategory)) .then(function(data) { setFiles(data.files || []); }) .catch(function(err) { console.error('Failed to load files:', err); setFiles([]); }) .finally(function() { setLoading(false); }); } function loadDefaults() { apiFetch('/files/defaults/me') .then(function(data) { var d = data.defaults || {}; setDefaults(d); if (onDefaultsChanged) onDefaultsChanged(d); }) .catch(function() {}); } function handleUpload(fileObj) { if (!fileObj || disabled) return; setUploading(true); var fd = new FormData(); fd.append('file', fileObj); fd.append('category', activeCategory); authFetch(API_BASE + '/files/upload', { method: 'POST', body: fd }) .then(function(resp) { if (!resp.ok) throw new Error('Upload failed'); return resp.json(); }) .then(function() { loadFiles(); }) .catch(function(err) { console.error('Upload error:', err); }) .finally(function() { setUploading(false); }); } function handleFileInputChange(e) { if (e.target.files && e.target.files.length > 0) { handleUpload(e.target.files[0]); e.target.value = ''; } } function handleDrop(e) { e.preventDefault(); e.stopPropagation(); setDragover(false); if (disabled) return; if (e.dataTransfer.files && e.dataTransfer.files.length > 0) { handleUpload(e.dataTransfer.files[0]); } } function handleDragOver(e) { e.preventDefault(); e.stopPropagation(); if (!disabled) setDragover(true); } function handleDragLeave(e) { e.preventDefault(); e.stopPropagation(); setDragover(false); } function handleSetDefault(fileId) { if (disabled) return; var body = {}; body[activeCategory] = fileId; apiFetch('/files/defaults', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }).then(function(data) { var d = data.defaults || {}; setDefaults(d); if (onDefaultsChanged) onDefaultsChanged(d); }).catch(function(err) { console.error('Set default error:', err); }); } function handleClearDefault() { if (disabled) return; var body = {}; body[activeCategory] = null; apiFetch('/files/defaults', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }).then(function(data) { var d = data.defaults || {}; setDefaults(d); if (onDefaultsChanged) onDefaultsChanged(d); }).catch(function(err) { console.error('Clear default error:', err); }); } function handleDelete(fileId) { if (disabled) return; apiFetch('/files/' + fileId, { method: 'DELETE' }) .then(function() { setDeleteConfirm(null); loadFiles(); loadDefaults(); }) .catch(function(err) { console.error('Delete error:', err); }); } var currentDefault = defaults[activeCategory]; return (
{'\u25B8'} FILE MANAGER
{!collapsed &&
{FILE_CATEGORIES.map(function(cat) { var isActive = cat.key === activeCategory; var hasDefault = !!defaults[cat.key]; return ( ); })}
{/* Upload zone */}
{uploading ? (
{'\u23F3'} UPLOADING...
) : (
{'\u2B06'} DROP FILE HERE OR CLICK TO BROWSE Max 50 MB
)}
{/* File list */} {loading ? (
Loading...
) : files.length === 0 ? (
No files uploaded for this category
) : (
{files.map(function(f) { var isDefault = currentDefault === f.id; return ( ); })}
NAME SIZE UPLOADED DEFAULT ACTIONS
{f.original_name} {formatFileSize(f.file_size)} {formatDate(f.uploaded_at)} {isDefault ? ( {'\u2605'} ) : ( )} {isDefault && ( )} {deleteConfirm === f.id ? ( ) : ( )}
)}
}
); } function LogEntry({ entry }) { return (
{entry.time} {'\u00BB'} {entry.message}
); } function DownloadCard({ file }) { const isPrimary = file.type === 'primary'; return (
{isPrimary ? '\u25C6' : '\u25C7'}
{file.filename} {file.subtitle}
); } function DownloadArea({ files, onDownloadAll }) { if (!files || files.length === 0) return null; return (
{files.map((f) => ( ))}
{files.length > 1 && ( )}
); } function InfoTooltip({ visible, moduleKey, anchorRect, modules, infoTexts, stealthRatings, onClose }) { const tooltipRef = useRef(null); useEffect(() => { if (!visible) return; const handleClick = (e) => { if (tooltipRef.current && !tooltipRef.current.contains(e.target) && !e.target.classList.contains('btn-info')) { onClose(); } }; const handleKey = (e) => { if (e.key === 'Escape') onClose(); }; document.addEventListener('click', handleClick); document.addEventListener('keydown', handleKey); return () => { document.removeEventListener('click', handleClick); document.removeEventListener('keydown', handleKey); }; }, [visible, onClose]); if (!visible || !moduleKey || !anchorRect) return null; const mod = modules[moduleKey] || {}; const infoText = infoTexts[moduleKey] || 'No description available.'; const rating = stealthRatings[moduleKey] || 0; let stealthStars = ''; if (rating > 0) { for (let i = 0; i < 5; i++) { stealthStars += i < rating ? '\u2605' : '\u2606'; } } // Position calculation const tooltipWidth = 360; let left = anchorRect.right + 10; if (left + tooltipWidth > window.innerWidth) { left = anchorRect.left - tooltipWidth - 10; } if (left < 8) left = 8; let top = anchorRect.top; // Clamp top so tooltip doesn't overflow bottom const maxTop = window.innerHeight - 200; if (top > maxTop) top = maxTop; return createPortal(
{mod.name || moduleKey}
{stealthStars && (
(Stealth: {stealthStars})
)}
{infoText}
, document.body ); } // ===== Admin Panel Components ===== function ConfirmModal({ title, message, onConfirm, onCancel }) { return (

{title}

{message}

); } function ResetPasswordModal({ username, onClose }) { const [newPw, setNewPw] = useState(''); const [confirmPw, setConfirmPw] = useState(''); const [error, setError] = useState(''); const [success, setSuccess] = useState(false); const [loading, setLoading] = useState(false); async function handleSubmit(e) { e.preventDefault(); setError(''); if (newPw.length < 8) { setError('Password must be at least 8 characters'); return; } if (newPw !== confirmPw) { setError('Passwords do not match'); return; } setLoading(true); try { await apiFetch('/admin/users/' + encodeURIComponent(username) + '/reset-password', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ new_password: newPw }), }); setSuccess(true); setTimeout(onClose, 1200); } catch (err) { setError(err.message || 'Failed to reset password'); } finally { setLoading(false); } } return (

RESET PASSWORD

User: {username}

{success ? (

Password reset successfully!

) : (
{error &&
{error}
}
)}
); } function AdminPanel({ currentUsername }) { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); // Create user form const [newUsername, setNewUsername] = useState(''); const [newPassword, setNewPassword] = useState(''); const [newRole, setNewRole] = useState('operator'); const [newTier, setNewTier] = useState(1); const [createError, setCreateError] = useState(''); const [createLoading, setCreateLoading] = useState(false); // Modals const [deleteTarget, setDeleteTarget] = useState(null); const [resetTarget, setResetTarget] = useState(null); async function loadUsers() { try { const data = await apiFetch('/admin/users'); setUsers(data.users || []); setError(''); } catch (err) { setError(err.message); } finally { setLoading(false); } } useEffect(() => { loadUsers(); }, []); async function handleCreateUser(e) { e.preventDefault(); setCreateError(''); if (!newUsername.trim() || !newPassword) { setCreateError('Username and password required'); return; } if (newPassword.length < 8) { setCreateError('Password must be at least 8 characters'); return; } setCreateLoading(true); try { await apiFetch('/auth/register', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: newUsername.trim(), password: newPassword, role: newRole, tier: newTier }), }); setNewUsername(''); setNewPassword(''); setNewRole('user'); setNewTier(1); loadUsers(); } catch (err) { setCreateError(err.message || 'Failed to create user'); } finally { setCreateLoading(false); } } async function handleRoleChange(username, role) { try { await apiFetch('/admin/users/' + encodeURIComponent(username) + '/role', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ role: role }), }); loadUsers(); } catch (err) { setError(err.message); } } async function handleTierChange(username, tier) { try { await apiFetch('/admin/users/' + encodeURIComponent(username) + '/tier', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ tier: parseInt(tier, 10) }), }); loadUsers(); } catch (err) { setError(err.message); } } async function handleDeleteUser() { if (!deleteTarget) return; try { await apiFetch('/admin/users/' + encodeURIComponent(deleteTarget), { method: 'DELETE', }); setDeleteTarget(null); loadUsers(); } catch (err) { setError(err.message); setDeleteTarget(null); } } return (
{/* Create User Form */}
{createError &&
{createError}
}
{/* Error display */} {error &&
{error}
} {/* User Table */} {loading ? (
Loading users...
) : (
{users.map(function(user) { const isSelf = user.username === currentUsername; return ( ); })}
USERNAME ROLE TIER CREATED ACTIONS
{user.username} {isSelf && YOU} {isSelf ? ( ) : ( )} {isSelf ? ( ) : ( )} {formatDate(user.created_at)} {!isSelf && ( )}
)} {/* Delete Confirm Modal */} {deleteTarget && ( )} {/* Reset Password Modal */} {resetTarget && ( )}
); } // ===== Main App ===== function App() { // --- Auth state --- const [authed, setAuthed] = useState(!!getToken()); const [currentUsername, setCurrentUsername] = useState(getStoredUsername()); const [currentRole, setCurrentRole] = useState(getStoredRole()); const [currentTier, setCurrentTier] = useState(getStoredTier()); const [mustChangePassword, setMustChangePassword] = useState(false); // Listen for auth expiration events (401 responses) useEffect(() => { function handleExpired() { setAuthed(false); setCurrentUsername(''); setCurrentRole('viewer'); setCurrentTier(1); setMustChangePassword(false); } window.addEventListener('unggoy-auth-expired', handleExpired); return () => window.removeEventListener('unggoy-auth-expired', handleExpired); }, []); // On mount, fetch fresh role and tier from /auth/me useEffect(() => { if (!authed) return; apiFetch('/auth/me').then(function(data) { setCurrentRole(data.role || 'viewer'); setStoredRole(data.role || 'viewer'); setCurrentTier(data.tier || 1); setStoredTier(data.tier || 1); if (data.must_change_password) setMustChangePassword(true); }).catch(function() { // ignore - token may be expired, handled by 401 }); }, [authed]); function handleLogin(username, role, tier, mustChange) { setCurrentUsername(username); setCurrentRole(role || 'viewer'); setCurrentTier(tier || 1); setAuthed(true); if (mustChange) setMustChangePassword(true); } function handleLogout() { clearToken(); setAuthed(false); setCurrentUsername(''); setCurrentRole('viewer'); setCurrentTier(1); setMustChangePassword(false); } if (!authed) { return ; } // Force password change before allowing access if (mustChangePassword) { return (

UNGGOY LOADER

{'\u26A0'} PASSWORD CHANGE REQUIRED
You must change your default password before continuing.
); } return ; } function ChangePasswordModal({ onClose, forced }) { const [oldPw, setOldPw] = useState(''); const [newPw, setNewPw] = useState(''); const [confirmPw, setConfirmPw] = useState(''); const [error, setError] = useState(''); const [success, setSuccess] = useState(false); async function handleSubmit(e) { e.preventDefault(); setError(''); if (newPw.length < 8) { setError('New password must be at least 8 characters'); return; } if (newPw !== confirmPw) { setError('Passwords do not match'); return; } try { var resp = await authFetch(API_BASE + '/auth/change-password', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ old_password: oldPw, new_password: newPw }) }); if (!resp.ok) { var data = await resp.json().catch(function() { return {}; }); setError(data.detail?.error || data.detail || data.error || 'Failed to change password'); return; } setSuccess(true); setTimeout(onClose, 1500); } catch (err) { setError('Network error'); } } function handleBackdropClick(e) { if (!forced && e.target === e.currentTarget) onClose(); } return (
{!forced &&

CHANGE PASSWORD

} {success ? (

Password changed successfully!

) : (
{error &&
{error}
}
{!forced && }
)}
); } function MainApp({ username, role, tier, onLogout }) { // --- Connection state --- const [status, setStatus] = useState('connecting'); const [version, setVersion] = useState('v--'); const [showChangePw, setShowChangePw] = useState(false); const [mingwAvailable, setMingwAvailable] = useState(false); // --- User menu --- const [showUserMenu, setShowUserMenu] = useState(false); const userMenuRef = useRef(null); // --- View routing --- const [currentView, setCurrentView] = useState('main'); // --- Profile delete --- const [profileDeleteConfirm, setProfileDeleteConfirm] = useState(false); // --- Module definitions --- const [modules, setModules] = useState({}); const [stealthRatings, setStealthRatings] = useState({}); const [infoTexts, setInfoTexts] = useState({}); const [exclusiveGroups, setExclusiveGroups] = useState({}); const [checkboxGroups, setCheckboxGroups] = useState([]); const [paramsMap, setParamsMap] = useState({}); const [techniqueTiers, setTechniqueTiers] = useState({}); const [tierNames, setTierNames] = useState({}); // --- User selections --- const [files, setFiles] = useState({ payload: null, cover: null, icon: null, host_pe: null, sig_source: null }); const [outputName, setOutputName] = useState('Unggoy.exe'); const [overrideIcon, setOverrideIcon] = useState(false); const [debugMode, setDebugMode] = useState(true); const [dropdownSelections, setDropdownSelections] = useState({}); // groupName -> displayName const [checkboxStates, setCheckboxStates] = useState({}); // moduleKey -> boolean const [paramValues, setParamValues] = useState({}); // paramKey -> string value // --- Stealth --- const [stealthScore, setStealthScore] = useState(0); const [stealthStars, setStealthStars] = useState(''); // --- Build --- const [buildStatus, setBuildStatus] = useState('idle'); const [buildId, setBuildId] = useState(null); const [logs, setLogs] = useState([]); const [downloadFiles, setDownloadFiles] = useState([]); const buildWsRef = useRef(null); const consoleRef = useRef(null); // --- Profiles --- const [profiles, setProfiles] = useState([]); const [selectedProfile, setSelectedProfile] = useState(''); // --- Server file defaults --- const [serverDefaults, setServerDefaults] = useState({}); // {category: file_id} const [serverDefaultInfo, setServerDefaultInfo] = useState({}); // {category: {id, original_name, ...}} // --- Tooltip --- const [tooltip, setTooltip] = useState({ visible: false, moduleKey: null, anchorRect: null }); // --- Derived: which dropdown options map to which module keys --- const dropdownOptionsMap = useRef({}); // { groupName: { displayName: moduleKey } } // --- Role checks --- const userCanBuild = canBuild(role); const userIsAdmin = isAdmin(role); const isViewer = role === 'viewer'; const userTier = tier || 1; function isTechniqueLocked(moduleKey) { // Only "user" role is restricted by tier. Admin and operator have full access. if (!isTierRestricted(role)) return false; var reqTier = techniqueTiers[moduleKey]; if (reqTier === undefined) return false; return userTier < reqTier; } function getTechniqueRequiredTier(moduleKey) { return techniqueTiers[moduleKey] || 1; } // ===== INIT ===== useEffect(() => { async function init() { try { const [health, modulesData] = await Promise.all([ apiFetch('/health'), apiFetch('/modules'), ]); setVersion('v' + health.version); setMingwAvailable(health.mingw); setStatus(health.mingw ? 'online' : 'online'); const mods = modulesData.modules || {}; const sr = modulesData.stealth_ratings || {}; const it = modulesData.info_texts || {}; const eg = modulesData.exclusive_groups || {}; const cg = modulesData.checkbox_groups || []; const pm = modulesData.params_map || {}; const tt = modulesData.technique_tiers || {}; const tn = modulesData.tier_names || {}; setModules(mods); setStealthRatings(sr); setInfoTexts(it); setExclusiveGroups(eg); setCheckboxGroups(cg); setParamsMap(pm); setTechniqueTiers(tt); setTierNames(tn); // Init dropdown selections with defaults const dSel = {}; const dOpts = {}; Object.keys(eg).forEach((groupName) => { const options = eg[groupName]; const optNames = Object.keys(options); dOpts[groupName] = options; let defaultName = optNames[0]; for (let i = 0; i < optNames.length; i++) { const modKey = options[optNames[i]]; if (mods[modKey] && mods[modKey].default) { defaultName = optNames[i]; break; } } dSel[groupName] = defaultName; }); dropdownOptionsMap.current = dOpts; setDropdownSelections(dSel); // Init checkbox states with defaults const cStates = {}; cg.forEach((group) => { const keys = group[1]; keys.forEach((key) => { if (mods[key]) { cStates[key] = !!mods[key].default; } }); }); setCheckboxStates(cStates); // Init param values with defaults const pVals = {}; Object.keys(pm).forEach((moduleKey) => { pm[moduleKey].forEach((p) => { pVals[p[1]] = p[2]; // paramKey = default value }); }); setParamValues(pVals); // Load profiles and server file defaults loadProfileList(); loadServerDefaults(); } catch (err) { setStatus('offline'); console.error('Init failed:', err); } } init(); }, []); // ===== Auto-scroll console ===== useEffect(() => { if (consoleRef.current) { consoleRef.current.scrollTop = consoleRef.current.scrollHeight; } }, [logs]); // ===== Stealth calculation ===== useEffect(() => { if (Object.keys(modules).length === 0) return; computeStealth(); }, [dropdownSelections, checkboxStates, modules, stealthRatings]); function computeStealth() { let totalScore = 0; let count = 0; const opts = dropdownOptionsMap.current; Object.keys(dropdownSelections).forEach((groupName) => { const displayName = dropdownSelections[groupName]; const options = opts[groupName] || {}; const moduleKey = options[displayName] || ''; totalScore += stealthRatings[moduleKey] || 0; count += 1; }); Object.keys(checkboxStates).forEach((key) => { if (checkboxStates[key]) { totalScore += stealthRatings[key] || 0; count += 1; } }); const avg = count > 0 ? totalScore / count : 0; const rounded = Math.round(avg); let stars = ''; for (let i = 0; i < 5; i++) { stars += i < rounded ? '\u2605' : '\u2606'; } setStealthScore(avg); setStealthStars(stars); } // ===== Host PE logic ===== const hasHostPe = files.host_pe !== null || !!serverDefaults['host_pe']; const iconDisabled = hasHostPe && !overrideIcon; function handleHostPeChange(file) { setFiles((prev) => ({ ...prev, host_pe: file })); if (file && !checkboxStates['pe_run']) { setCheckboxStates((prev) => ({ ...prev, pe_run: true })); } } // ===== Param activity: is a param's parent module active? ===== function isParamActive(moduleKey) { // Check checkbox if (checkboxStates[moduleKey] !== undefined) { return checkboxStates[moduleKey]; } // Check if selected in a dropdown const opts = dropdownOptionsMap.current; for (const groupName of Object.keys(opts)) { const displayName = dropdownSelections[groupName]; const selectedKey = opts[groupName][displayName]; if (selectedKey === moduleKey) return true; } return false; } // ===== Logging ===== function addLog(message, tag) { setLogs((prev) => [...prev, { message, tag: tag || 'dim', time: timestamp() }]); } // ===== User menu: close on outside click ===== useEffect(function() { if (!showUserMenu) return; function handleClickOutside(e) { if (userMenuRef.current && !userMenuRef.current.contains(e.target)) { setShowUserMenu(false); } } document.addEventListener('mousedown', handleClickOutside); return function() { document.removeEventListener('mousedown', handleClickOutside); }; }, [showUserMenu]); // ===== Profile management ===== async function loadProfileList() { try { const data = await apiFetch('/profiles'); setProfiles(data.profiles || []); } catch (err) { console.error('Failed to load profiles:', err); } } async function handleDeleteProfile() { if (!selectedProfile || isViewer) return; try { await apiFetch('/profiles/' + encodeURIComponent(selectedProfile), { method: 'DELETE', }); addLog("Profile deleted: '" + selectedProfile + "'", 'info'); setSelectedProfile(''); setProfileDeleteConfirm(false); loadProfileList(); } catch (err) { addLog('Failed to delete profile: ' + err.message, 'error'); setProfileDeleteConfirm(false); } } async function loadServerDefaults() { try { var data = await apiFetch('/files/defaults/me'); var defs = data.defaults || {}; setServerDefaults(defs); // Fetch metadata for each default file var info = {}; var promises = Object.keys(defs).map(async function(cat) { try { var meta = await apiFetch('/files/' + defs[cat]); info[cat] = meta; } catch (e) { /* ignore missing */ } }); await Promise.all(promises); setServerDefaultInfo(info); } catch (err) { // ignore } } function handleServerDefaultsChanged(newDefaults) { setServerDefaults(newDefaults); // Re-fetch metadata var info = {}; var promises = Object.keys(newDefaults).map(async function(cat) { try { var meta = await apiFetch('/files/' + newDefaults[cat]); info[cat] = meta; } catch (e) { /* ignore */ } }); Promise.all(promises).then(function() { setServerDefaultInfo(info); }); // Auto-enable pe_run when host_pe default is set, disable when cleared if (newDefaults['host_pe']) { setCheckboxStates(function(prev) { return Object.assign({}, prev, { pe_run: true }); }); } else { // Only auto-disable if no local host_pe file either if (!files.host_pe) { setCheckboxStates(function(prev) { return Object.assign({}, prev, { pe_run: false }); }); } } } function getFileDisplayName(category) { // If local file selected, show it if (files[category]) return files[category].name; // Map local state keys to server category keys var serverCat = category === 'sig_source' ? 'signature' : category; // If server default exists, show server file indicator var info = serverDefaultInfo[serverCat]; if (info) return '\u2601 ' + info.original_name; return 'No file selected'; } function hasFileForCategory(category) { return !!files[category] || !!serverDefaults[category]; } function clearLocalFile(category) { setFiles(function(prev) { var next = Object.assign({}, prev); next[category] = null; return next; }); // Also clear server default if one is set for this category var serverCat = category === 'sig_source' ? 'signature' : category; if (serverDefaults[serverCat]) { var body = {}; body[serverCat] = null; apiFetch('/files/defaults', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }).then(function(data) { handleServerDefaultsChanged(data.defaults || {}); }).catch(function(err) { console.error('Failed to clear server default:', err); }); } // If clearing host_pe, deactivate pe_run if (category === 'host_pe') { setCheckboxStates(function(prev) { return Object.assign({}, prev, { pe_run: false }); }); } } async function handleLoadProfile() { if (!selectedProfile) { addLog('No profile selected.', 'error'); return; } try { const config = await apiFetch('/profiles/' + encodeURIComponent(selectedProfile)); applyProfile(config); addLog("Profile loaded: '" + selectedProfile + "'", 'info'); } catch (err) { addLog('Failed to load profile: ' + err.message, 'error'); } } function applyProfile(config) { const gs = config.global_settings || {}; if (gs.out_name) setOutputName(gs.out_name); if (typeof config.build_mode === 'boolean') { setDebugMode(config.build_mode); } // Dropdowns const dropdowns = config.dropdowns || {}; setDropdownSelections((prev) => { const next = { ...prev }; Object.keys(dropdowns).forEach((groupName) => { if (next[groupName] !== undefined) { next[groupName] = dropdowns[groupName]; } }); return next; }); // Checkboxes const checkboxes = config.checkboxes || {}; setCheckboxStates((prev) => { const next = { ...prev }; Object.keys(checkboxes).forEach((key) => { if (next[key] !== undefined) { next[key] = !!checkboxes[key]; } }); return next; }); // Params const params = config.params || {}; setParamValues((prev) => { const next = { ...prev }; Object.keys(params).forEach((pk) => { if (next[pk] !== undefined) { next[pk] = params[pk]; } }); return next; }); // Server files from profile if (config.server_files) { // Apply server_files as defaults apiFetch('/files/defaults', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(config.server_files), }).then(function(data) { handleServerDefaultsChanged(data.defaults || {}); }).catch(function() {}); } } async function handleSaveProfile() { if (isViewer) return; const name = prompt('Enter profile name:'); if (!name || !name.trim()) return; const trimmed = name.trim(); const config = collectConfig(); try { await apiFetch('/profiles/' + encodeURIComponent(trimmed), { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(config), }); addLog("Profile saved: '" + trimmed + "'", 'info'); loadProfileList(); } catch (err) { addLog('Failed to save profile: ' + err.message, 'error'); } } // ===== Reset Defaults ===== function handleResetDefaults() { // Reset dropdowns const opts = dropdownOptionsMap.current; const dSel = {}; Object.keys(opts).forEach((groupName) => { const options = opts[groupName]; const optNames = Object.keys(options); let defaultName = optNames[0]; for (let i = 0; i < optNames.length; i++) { const modKey = options[optNames[i]]; if (modules[modKey] && modules[modKey].default) { defaultName = optNames[i]; break; } } dSel[groupName] = defaultName; }); setDropdownSelections(dSel); // Reset checkboxes const cStates = {}; checkboxGroups.forEach((group) => { group[1].forEach((key) => { cStates[key] = modules[key] ? !!modules[key].default : false; }); }); setCheckboxStates(cStates); // Reset params const pVals = {}; Object.keys(paramsMap).forEach((moduleKey) => { paramsMap[moduleKey].forEach((p) => { pVals[p[1]] = p[2]; }); }); setParamValues(pVals); } // ===== Collect Config ===== function collectConfig() { const opts = dropdownOptionsMap.current; // Dropdown selections as moduleKey const dSelKeys = {}; Object.keys(dropdownSelections).forEach((groupName) => { const displayName = dropdownSelections[groupName]; dSelKeys[groupName] = opts[groupName][displayName] || ''; }); // Active checkboxes const activeModules = []; Object.keys(checkboxStates).forEach((key) => { if (checkboxStates[key]) activeModules.push(key); }); // Params with sleep_time/gargoyle_sleep conversion (sec -> ms) const buildParams = {}; Object.keys(paramValues).forEach((pk) => { let val = paramValues[pk]; if (pk === 'sleep_time') { try { val = String(Math.round(parseFloat(val) * 1000)); } catch (e) { val = '5000'; } } if (pk === 'gargoyle_sleep') { try { val = String(Math.round(parseFloat(val) * 1000)); } catch (e) { val = '30000'; } } buildParams[pk] = val; }); // Build server_files mapping for categories without a local file var sfMap = {}; var catKeys = ['payload', 'cover', 'icon', 'host_pe', 'signature']; var fileCatMap = { payload: 'payload', cover: 'cover', icon: 'icon', host_pe: 'host_pe', sig_source: 'signature' }; catKeys.forEach(function(cat) { if (serverDefaults[cat]) { sfMap[cat] = serverDefaults[cat]; } }); return { global_settings: { payload_path: files.payload ? files.payload.name : '', cover_path: files.cover ? files.cover.name : '', icon_path: files.icon ? files.icon.name : '', host_pe_path: files.host_pe ? files.host_pe.name : '', sig_path: files.sig_source ? files.sig_source.name : '', out_name: outputName, }, build_mode: debugMode, dropdowns: { ...dropdownSelections }, checkboxes: { ...checkboxStates }, params: { ...paramValues }, // raw values for profile save active_modules: activeModules, dropdown_selections: dSelKeys, debug_mode: debugMode, override_icon: overrideIcon, output_name: outputName, build_params: buildParams, server_files: sfMap, }; } // ===== Build ===== async function handleBuild() { if (!userCanBuild) return; if (!files.payload && !serverDefaults['payload']) { addLog('No payload file selected. Please select a .bin file or set a server default.', 'error'); return; } // Tier validation: check all active techniques before building var _bOpts = dropdownOptionsMap.current; var _tierBlocked = false; Object.keys(dropdownSelections).forEach(function(_gn) { var _dn = dropdownSelections[_gn]; var _gopts = _bOpts[_gn] || {}; var _mk = _gopts[_dn] || ''; if (isTechniqueLocked(_mk)) { var _rt = getTechniqueRequiredTier(_mk); addLog('Technique "' + _mk + '" requires ' + (TIER_BADGE_NAMES[_rt] || '') + ' tier', 'error'); _tierBlocked = true; } }); Object.keys(checkboxStates).forEach(function(_ck) { if (checkboxStates[_ck] && isTechniqueLocked(_ck)) { var _rt2 = getTechniqueRequiredTier(_ck); addLog('Technique "' + _ck + '" requires ' + (TIER_BADGE_NAMES[_rt2] || '') + ' tier', 'error'); _tierBlocked = true; } }); if (_tierBlocked) return; setBuildStatus('building'); setLogs([]); setDownloadFiles([]); const config = collectConfig(); const fd = new FormData(); fd.append('config', JSON.stringify(config)); if (files.payload) fd.append('payload', files.payload); if (files.cover) fd.append('cover', files.cover); if (files.icon && (!hasHostPe || overrideIcon)) { fd.append('icon', files.icon); } if (files.host_pe) fd.append('host_pe', files.host_pe); if (files.sig_source) fd.append('sig_source', files.sig_source); try { const resp = await authFetch(API_BASE + '/build', { method: 'POST', body: fd }); if (!resp.ok) { const errData = await resp.json().catch(() => ({})); throw new Error(errData.detail?.error || 'Build request failed'); } const data = await resp.json(); setBuildId(data.build_id); addLog('Build started (ID: ' + data.build_id + ')', 'info'); connectBuildWebSocket(data.build_id); } catch (err) { addLog('Build failed: ' + err.message, 'error'); setBuildStatus('idle'); } } function connectBuildWebSocket(id) { const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; const token = getToken(); const wsUrl = protocol + '//' + window.location.host + API_BASE + '/build/' + id + '/logs?token=' + encodeURIComponent(token || ''); if (buildWsRef.current) { buildWsRef.current.close(); } const ws = new WebSocket(wsUrl); buildWsRef.current = ws; ws.onmessage = function (event) { let entry; try { entry = JSON.parse(event.data); } catch (e) { return; } if (entry.done) { if (entry.status === 'success') { setLogs((prev) => [...prev, { message: 'Build completed successfully!', tag: 'ok', time: timestamp() }]); // Build download files list const dlFiles = []; const mainFilename = outputName.endsWith('.exe') ? outputName : outputName + '.exe'; dlFiles.push({ filename: mainFilename, downloadUrl: API_BASE + '/build/' + id + '/download', type: 'primary', subtitle: 'Main Executable', }); if (entry.extra_files && entry.extra_files.length > 0) { entry.extra_files.forEach((filename) => { dlFiles.push({ filename: filename, downloadUrl: API_BASE + '/build/' + id + '/download/' + encodeURIComponent(filename), type: 'secondary', subtitle: getFileSubtitle(filename), }); }); } setDownloadFiles(dlFiles); setBuildStatus('success'); } else { setLogs((prev) => [...prev, { message: 'Build failed.', tag: 'error', time: timestamp() }]); setBuildStatus('error'); } return; } // Regular log message setLogs((prev) => [...prev, { message: entry.message || '', tag: entry.tag || 'dim', time: timestamp(), }]); }; ws.onerror = function () { setLogs((prev) => [...prev, { message: 'WebSocket connection error.', tag: 'error', time: timestamp() }]); setBuildStatus('error'); }; ws.onclose = function () { buildWsRef.current = null; }; } function handleDownloadAll() { downloadFiles.forEach((file, i) => { setTimeout(() => { downloadWithAuth(file.downloadUrl, file.filename); }, i * 500); }); } // ===== Tooltip ===== function handleInfoClick(e, moduleKey) { e.stopPropagation(); if (tooltip.visible && tooltip.moduleKey === moduleKey) { setTooltip({ visible: false, moduleKey: null, anchorRect: null }); } else { const rect = e.currentTarget.getBoundingClientRect(); setTooltip({ visible: true, moduleKey, anchorRect: rect }); } } // ===== RENDER ===== const statusClass = status === 'online' ? 'online' : status === 'offline' ? 'offline' : ''; const statusLabel = status === 'online' ? (mingwAvailable ? 'SYS READY' : 'NO COMPILER') : status === 'offline' ? 'OFFLINE' : 'CONNECTING...'; const isBuilding = buildStatus === 'building'; // --- Shared header renderer --- function renderHeader(showBackButton) { return (
{showBackButton && ( )}

UNGGOY LOADER

{showBackButton ? 'ADMIN PANEL' : 'WEB EDITION \u00B7 ' + version}
{!showBackButton && (
STEALTH
{stealthStars} {stealthScore.toFixed(1)}
)}
{username} {'\u25BE'}
{showUserMenu && (
{username}
{userIsAdmin && ( )}
)}
{statusLabel}
); } // --- Admin view --- if (currentView === 'admin') { return ( {renderHeader(true)}
{showChangePw && }
); } return ( {/* HEADER */} {renderHeader(false)}
{/* GLOBAL SETTINGS */}
{/* Profiles */}
{profileDeleteConfirm ? ( ) : ( )}
{/* File Inputs */} setFiles((prev) => ({ ...prev, payload: f }))} disabled={isViewer} > {(files.payload || serverDefaults['payload']) && ( )} setFiles((prev) => ({ ...prev, cover: f }))} disabled={isViewer} > {(files.cover || serverDefaults['cover']) && ( )} setFiles((prev) => ({ ...prev, icon: f }))} disabled={isViewer || iconDisabled} > {(files.icon || serverDefaults['icon']) && ( )} {(files.host_pe || serverDefaults['host_pe']) && ( )} setFiles((prev) => ({ ...prev, sig_source: f }))} disabled={isViewer} > {(files.sig_source || serverDefaults['signature']) && ( )}
setOutputName(e.target.value)} spellCheck={false} disabled={isViewer} />
{/* FILE MANAGER */} {/* BUILD MODE */}
{/* TECHNIQUE SELECTION */}
SELECT ACTIVE TECHNIQUES
{/* Dropdowns */} {Object.keys(exclusiveGroups).map((groupName) => { const options = exclusiveGroups[groupName]; const optionNames = Object.keys(options); return (
{groupName}
); })} {/* Checkbox groups */} {checkboxGroups.map((group) => { const groupName = group[0]; const keys = group[1]; return (
{groupName}
{keys.map((key) => { const mod = modules[key]; if (!mod) return null; const checked = !!checkboxStates[key]; const params = paramsMap[key] || []; const locked = isTechniqueLocked(key); const reqTier = getTechniqueRequiredTier(key); return (
{ if (!isViewer && !locked) { setCheckboxStates((prev) => ({ ...prev, [key]: !prev[key] })); } }} > {mod.name.toUpperCase()} {locked && } {params.length > 0 && !locked && (
{params.map((p) => { const paramLabel = p[0]; const paramKey = p[1]; const paramDefault = p[2]; const active = isParamActive(key); const w = Math.max((paramValues[paramKey] || paramDefault).length + 3, 8); return ( {paramLabel} { setParamValues((prev) => ({ ...prev, [paramKey]: e.target.value })); }} disabled={!active || isViewer} spellCheck={false} style={{ width: (w * 8) + 'px' }} /> ); })}
)}
); })}
); })}
{/* BUILD SECTION */}
{isViewer && (
Viewer role — contact admin for build access
)}
{logs.length === 0 ? ( Awaiting build command... ) : ( logs.map((entry, i) => ) )}
{/* Download Area */} {buildStatus === 'success' && downloadFiles.length > 0 && ( )}
{/* Info Tooltip Portal */} setTooltip({ visible: false, moduleKey: null, anchorRect: null })} /> {showChangePw && }
); } // ===== Mount ===== const root = ReactDOM.createRoot(document.getElementById('root')); root.render();