src/upload-policy.tsTypeScript
@@ -0,0 +1,38 @@
1+
const MAX_UPLOAD_BYTES = 5 * 1024 * 1024;2+
3+
export interface UploadCandidate {4+
filename: string;5+
claimedMime: string;6+
declaredSize: number;7+
bytes: Uint8Array;8+
}9+
10+
export interface MimeSniffer {11+
sniff(bytes: Uint8Array): "image/jpeg" | "image/png" | "application/pdf" | "unknown";12+
}13+
14+
export type ValidationResult =15+
| { valid: true; mime: string }16+
| { valid: false; reason: string };17+
18+
export function validateUpload(19+
candidate: UploadCandidate,20+
_sniffer: MimeSniffer,21+
): ValidationResult {22+
if (candidate.declaredSize > MAX_UPLOAD_BYTES) {23+
return { valid: false, reason: "File is too large" };24+
}25+
26+
if (27+
!candidate.claimedMime.startsWith("image/") &&28+
candidate.claimedMime !== "application/pdf"29+
) {30+
return { valid: false, reason: "Unsupported file type" };31+
}32+
33+
if (candidate.filename.endsWith(".exe")) {34+
return { valid: false, reason: "Unsupported extension" };35+
}36+
37+
return { valid: true, mime: candidate.claimedMime };38+
}