@utsuk/file-upload-server
v0.1.0
Published
Express middleware for presigned S3 PUT/GET URLs (file upload accelerator server).
Downloads
133
Readme
@utsuk/file-upload-server
Express middleware that exposes:
POST /upload/presign→ presigned PUT URL for browser → S3 uploadGET /upload/url?key=...→ presigned GET URL for download/preview
Install (consumer server)
npm install @utsuk/file-upload-serverPeer dependency:
express >= 4
Mounting (Express)
Mount after express.json() so the presign route can read JSON bodies.
import express from "express";
import { createFileUploadMiddleware } from "@utsuk/file-upload-server";
const app = express();
app.use(express.json());
app.use(
createFileUploadMiddleware({
s3: {
bucket: process.env.S3_BUCKET!,
access_key_id: process.env.S3_ACCESS_KEY_ID!,
secret_access_key: process.env.S3_SECRET_ACCESS_KEY!,
region: process.env.S3_REGION ?? "eu-west-2", // R2 uses "auto"
endpoint: process.env.S3_ENDPOINT, // omit for AWS
force_path_style: process.env.S3_FORCE_PATH_STYLE === "true",
disable_request_checksum_calculation: process.env.S3_DISABLE_CHECKSUM === "true",
key_prefix: process.env.S3_KEY_PREFIX ?? "uploads",
presigned_upload_ttl: 300,
presigned_download_ttl: 3600,
session_token: process.env.S3_SESSION_TOKEN, // optional
},
accepted_file_types: [".pdf", ".jpg", ".png"],
max_file_size: 10 * 1024 * 1024,
cors_origins: process.env.CORS_ORIGINS?.split(",") ?? ["http://localhost:3000"],
upload_route: "/upload/presign",
download_route: "/upload/url",
rate_limit: { window_ms: 60_000, max_requests: 30 },
auth: { mode: "header", header_name: "authorization" }, // or custom/none
strict_filename_validation: true,
})
);Important contract details
size_bytesis mandatory on the presign request body (400if missing/<=0).- The presigned PUT binds
Content-Typeinto the signature. The response includes:headers: { "Content-Type": filetype }- the client must send those headers verbatim on PUT.
- Download URL generation validates the
keyis underkey_prefixand rejects traversal patterns. - Rate limiting uses
express-rate-limitby default.
Local development (this monorepo)
From utsuk-file-upload/:
corepack pnpm nx build file-upload-server
corepack pnpm nx test file-upload-server
corepack pnpm nx typecheck file-upload-server