Files
AetherForge/server/web/src/help/screenshotDownload.ts
AetherForge 5fc601b564 feat: fleet ops, KEV scan, tunnels, beacon fallback, persistence
Extend owned-fleet control with scheduled tasks, audit log, file browser,
HTTPS beacon when WS drops, protocol tunnels, registry/autostart forge
options, KEV exposure in full sys check with Telegram alerts, and UI/tests.
2026-06-04 09:34:33 -07:00

47 lines
1.5 KiB
TypeScript

/** Strip whitespace and download a remote desktop capture as a JPEG file. */
export function sanitizeScreenshotBase64(raw: string): string {
const trimmed = raw.trim().replace(/^\uFEFF/, '');
let best = '';
for (const part of trimmed.split(/\s+/)) {
const cleaned = part.replace(/[^A-Za-z0-9+/=]/g, '');
if (cleaned.length > best.length && cleaned.length >= 100) {
best = cleaned;
}
}
if (best.length >= 100) return best;
const fallback = trimmed.replace(/[^A-Za-z0-9+/=]/g, '');
return fallback.length >= 100 ? fallback : '';
}
export type CaptureDownloadKind = 'screenshot' | 'camera';
export function downloadScreenshotFromBase64(
base64: string,
agentLabel: string,
kind: CaptureDownloadKind = 'screenshot'
): boolean {
const clean = sanitizeScreenshotBase64(base64);
if (clean.length < 100) return false;
const safeName = agentLabel.replace(/[^\w.-]+/g, '_').slice(0, 64) || 'agent';
const stamp = new Date().toISOString().replace(/[:.]/g, '-');
const blob = base64ToBlob(clean, 'image/jpeg');
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${kind}-${safeName}-${stamp}.jpg`;
a.rel = 'noopener';
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
return true;
}
function base64ToBlob(b64: string, mime: string): Blob {
const binary = atob(b64);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
return new Blob([bytes], { type: mime });
}