/** * Node-side multipart upload helper. Lets adversarial specs post arbitrary * bytes with arbitrary `Content-Type` claims to /api/v1/upload without * driving the UI. Crucial for MIME-spoofing, oversize, polyglot, and * filename-injection tests. * * Field shape matches [backend/src/handlers/upload.rs]: * - file (binary; carries filename + content_type in the part headers) * - caption (text, optional) * - hashtags (CSV text, optional) */ // Node 22+ ships FormData and Blob as globals — no import needed. const BASE = process.env.E2E_FRONTEND_URL ?? 'http://localhost:3101'; export type UploadOptions = { filename?: string; contentType?: string; caption?: string; hashtags?: string; }; export async function uploadRaw(token: string, body: Uint8Array | Buffer, opts: UploadOptions = {}) { const form = new FormData(); const blob = new Blob([body as any], { type: opts.contentType ?? 'application/octet-stream' }); form.append('file', blob as any, opts.filename ?? 'upload.bin'); if (opts.caption !== undefined) form.append('caption', opts.caption); if (opts.hashtags !== undefined) form.append('hashtags', opts.hashtags); return fetch(`${BASE}/api/v1/upload`, { method: 'POST', headers: { Authorization: `Bearer ${token}` }, body: form as any, }); } /** Convenience: read a fixture from disk and upload it. */ export async function uploadFile(token: string, path: string, opts: UploadOptions = {}) { const { readFile } = await import('node:fs/promises'); const body = await readFile(path); return uploadRaw(token, body, opts); } /** Tiny valid JPEG header — magic bytes only, useful for "claim image but is N MB of zeros" tests. */ export const JPEG_MAGIC = new Uint8Array([0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46]); /** Tiny valid PNG magic bytes. */ export const PNG_MAGIC = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]); /** ELF header — the magic bytes of a Linux executable. `infer` reports `application/x-executable`. */ export const ELF_MAGIC = new Uint8Array([0x7f, 0x45, 0x4c, 0x46]);