码桶
发现社区成员的开源项目
share-snapshot.js3.1 KB
// POST: Create a shareable read-only snapshot link
// GET with ?token=TOKEN: Return the shared snapshot data (no auth required)
function generateToken() {
const bytes = new Uint8Array(24);
crypto.getRandomValues(bytes);
return Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');
}
export async function onRequestGet(context) {
const kv = context.env.CF_DNS_KV;
const url = new URL(context.request.url);
const token = url.searchParams.get('token');
if (!token) {
return new Response(JSON.stringify({ error: 'Token parameter is required.' }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
});
}
if (!kv) {
return new Response(JSON.stringify({ error: 'KV storage not configured.' }), {
status: 500,
headers: { 'Content-Type': 'application/json' }
});
}
const key = `SHARED_SNAPSHOT:${token}`;
const raw = await kv.get(key);
if (!raw) {
return new Response(JSON.stringify({ error: 'Shared snapshot not found or expired.' }), {
status: 404,
headers: { 'Content-Type': 'application/json' }
});
}
const data = JSON.parse(raw);
return new Response(JSON.stringify({ snapshot: data }), {
headers: { 'Content-Type': 'application/json' }
});
}
export async function onRequestPost(context) {
const { cfToken } = context.data;
const { zoneId } = context.params;
const kv = context.env.CF_DNS_KV;
const username = context.data.user?.username || 'client';
if (!kv) {
return new Response(JSON.stringify({ error: 'KV storage not configured.' }), {
status: 500,
headers: { 'Content-Type': 'application/json' }
});
}
const body = await context.request.json();
const { snapshotKey } = body;
if (!snapshotKey) {
return new Response(JSON.stringify({ error: 'snapshotKey is required.' }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
});
}
// Fetch the snapshot data
const raw = await kv.get(snapshotKey);
if (!raw) {
return new Response(JSON.stringify({ error: 'Snapshot not found.' }), {
status: 404,
headers: { 'Content-Type': 'application/json' }
});
}
const snapshot = JSON.parse(raw);
// Generate share token and store with 7-day TTL
const token = generateToken();
const TTL_7_DAYS = 7 * 24 * 60 * 60;
const shareData = {
zoneId,
timestamp: snapshot.timestamp,
username: snapshot.username,
action: snapshot.action,
records: snapshot.records || [],
sharedBy: username,
sharedAt: new Date().toISOString()
};
await kv.put(`SHARED_SNAPSHOT:${token}`, JSON.stringify(shareData), { expirationTtl: TTL_7_DAYS });
const baseUrl = new URL(context.request.url);
const shareUrl = `${baseUrl.origin}/api/zones/${zoneId}/share-snapshot?token=${token}`;
return new Response(JSON.stringify({ success: true, token, shareUrl }), {
headers: { 'Content-Type': 'application/json' }
});
}