/** * Detect a MIME type from the first chunk of a file. Returns the * detected MIME (e.g. `'image/png'`) or `null` if the bytes don't * match any known signature. * * Intentionally narrow — only the well-known binary formats that * appear in `presignedUploadUrl`'s extension map are detected. Text * formats are not covered because their signatures are ambiguous. */ export declare function detectMimeFromMagicBytes(bytes: Uint8Array | ArrayBuffer): string | null; /** * Verify that a file's actual contents match the claimed content type. * Returns `{ ok, expected, detected }` so callers can branch on the * result and produce useful error messages. * * Reads up to 32 bytes from the file (enough for every signature we * check), then matches against `detectMimeFromMagicBytes`. * * @example * ```ts * // After a presigned upload completes: * const result = await verifyUploadedMime('uploads/avatar.jpg', 'image/jpeg') * if (!result.ok) { * await Storage.disk().deleteFile('uploads/avatar.jpg') * return Response.json({ error: 'content type mismatch', ...result }, { status: 400 }) * } * ``` */ export declare function verifyUploadedMime(path: string, expectedContentType: string, options?: { disk?: string }): Promise; /** * MIME re-verification helpers (stacksjs/stacks#1873 S-3). * * Background: `presignedUploadUrl({ contentType })` lets the caller * declare what they're going to upload, and AWS signs the URL against * that exact `Content-Type` header. Nothing checks that the **bytes** * actually match the claim. An attacker who can call your presigned * endpoint can request `image/jpeg` (which derives a `.jpg` * extension), then PUT a JavaScript file. The server only sees * "object exists, contentType was image/jpeg" — but the bytes are * executable. * * These helpers exist so server code can re-detect the MIME from * magic bytes after the upload finishes, and either delete the * mismatched object or surface it as a 400. * * **Limitations** — magic-byte sniffing only works for binary formats * with a well-defined signature. Text-based types (JSON, CSV, plain * text, SVG, HTML) can't be unambiguously detected from the first few * bytes; for those, validate by parsing the content (e.g. try * `JSON.parse` for `application/json`). */ /** * Result of a magic-byte detection attempt. * * `ok: true` means the bytes match a known signature for the * expected content type. `ok: false` with `detected: null` means the * bytes didn't match any signature this helper knows; `ok: false` * with `detected: string` means the bytes match a *different* * signature than expected (e.g. PNG bytes uploaded as image/jpeg). */ export declare interface MimeVerifyResult { ok: boolean expected: string detected: string | null }