mirror of
https://github.com/dyzulk/dyzulk.github.io.git
synced 2026-01-26 05:45:28 +07:00
86 lines
2.4 KiB
JavaScript
86 lines
2.4 KiB
JavaScript
/**
|
|
* Cloudflare Worker for Presigned R2 URLs
|
|
*
|
|
* SETUP INSTRUCTIONS:
|
|
* 1. Create a new Worker in Cloudflare Dashboard.
|
|
* 2. Copy this code into the Worker editor.
|
|
* 3. Go to Settings -> Variables and add:
|
|
* - R2_BUCKET_NAME
|
|
* - R2_ACCOUNT_ID
|
|
* - R2_ACCESS_KEY_ID
|
|
* - R2_SECRET_ACCESS_KEY
|
|
* - ALLOWED_ORIGIN (e.g., https://dyzulk.github.io, or * for dev)
|
|
* 4. Deploy!
|
|
*/
|
|
|
|
import { AwsClient } from 'aws4fetch'
|
|
|
|
export default {
|
|
async fetch(request, env) {
|
|
// 1. Handle CORS Preflight
|
|
if (request.method === "OPTIONS") {
|
|
return new Response(null, {
|
|
headers: {
|
|
"Access-Control-Allow-Origin": env.ALLOWED_ORIGIN || "*",
|
|
"Access-Control-Allow-Methods": "POST, OPTIONS",
|
|
"Access-Control-Allow-Headers": "Content-Type",
|
|
},
|
|
});
|
|
}
|
|
|
|
if (request.method !== "POST") {
|
|
return new Response("Method not allowed", { status: 405 });
|
|
}
|
|
|
|
try {
|
|
// 2. Auth Check (Simple)
|
|
// For production, verify Supabase JWT token here if needed.
|
|
// For now, we trust the Client if it knows the endpoint (obscurity) or checking Origin.
|
|
|
|
const body = await request.json();
|
|
const { fileName, fileType } = body;
|
|
|
|
if (!fileName || !fileType) {
|
|
return new Response("Missing fileName or fileType", { status: 400 });
|
|
}
|
|
|
|
// 3. Initialize AWS Client (R2 S3-Compatible)
|
|
const r2 = new AwsClient({
|
|
accessKeyId: env.R2_ACCESS_KEY_ID,
|
|
secretAccessKey: env.R2_SECRET_ACCESS_KEY,
|
|
service: 's3',
|
|
region: 'auto',
|
|
});
|
|
|
|
// 4. Generate Presigned URL
|
|
const url = new URL(
|
|
`https://${env.R2_BUCKET_NAME}.${env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com/${fileName}`
|
|
);
|
|
|
|
// Sign the request
|
|
// We sign a PUT request for the specific file
|
|
const signed = await r2.sign(
|
|
new Request(url, {
|
|
method: 'PUT',
|
|
headers: {
|
|
'Content-Type': fileType
|
|
}
|
|
}),
|
|
{
|
|
aws: { signQuery: true }, // Create presigned URL with query params
|
|
}
|
|
);
|
|
|
|
return new Response(JSON.stringify({ url: signed.url }), {
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
"Access-Control-Allow-Origin": env.ALLOWED_ORIGIN || "*",
|
|
},
|
|
});
|
|
|
|
} catch (e) {
|
|
return new Response(JSON.stringify({ error: e.message }), { status: 500 });
|
|
}
|
|
},
|
|
};
|