better-auth-add-plugin
Add a better-auth plugin to an existing project. Configures server and client plugins with proper imports.
Generate presigned URLs for secure client-side uploads or downloads
$ npx -y skills add secondsky/claude-skills --agent claude-codeHow it fires
How this command gets triggered: by you, by Claude, or both.
/r2-presigned-urlContext preview
What this command does when you run it.
Generate presigned URLs for secure client-side uploads or downloads
name: cloudflare-r2:presigned-url description: Generate presigned URLs for secure client-side uploads or downloads
Generate time-limited, signed URLs for secure client-side uploads or downloads without exposing R2 credentials.
1. **Operation type**: `{{operation}}` (upload or download) 2. **Object key** (file path in bucket): `{{key}}` 3. **Expiry** (seconds, max 604800 = 7 days): `{{expiry}}` 4. **Custom headers** (optional, e.g., Content-Type): `{{headers}}`
1. **Generates AWS v4 signed URL** using aws4fetch library 2. **Sets expiration time** (1 hour to 7 days) 3. **Provides curl test command** for verification 4. **Explains security considerations** 5. **Shows client-side usage example**
import { AwsClient } from 'aws4fetch';
// Configure AWS client for R2
const r2Client = new AwsClient({
accessKeyId: env.R2_ACCESS_KEY_ID,
secretAccessKey: env.R2_SECRET_ACCESS_KEY,
});
// Generate presigned URL for upload
async function generateUploadURL(
bucket: string,
key: string,
expirySeconds: number
) {
const url = new URL(
`https://${bucket}.${env.ACCOUNT_ID}.r2.cloudflarestorage.com/${key}`
);
url.searchParams.set('X-Amz-Expires', expirySeconds.toString());
const signed = await r2Client.sign(
new Request(url, { method: 'PUT' }),
{ aws: { signQuery: true } }
);
return signed.url;
}
// Generate presigned URL for download
async function generateDownloadURL(
bucket: string,
key: string,
expirySeconds: number
) {
const url = new URL(
`https://${bucket}.${env.ACCOUNT_ID}.r2.cloudflarestorage.com/${key}`
);
url.searchParams.set('X-Amz-Expires', expirySeconds.toString());
const signed = await r2Client.sign(
new Request(url, { method: 'GET' }),
{ aws: { signQuery: true } }
);
return signed.url;
}// Generate upload URL (valid for 1 hour)
const uploadURL = await generateUploadURL('my-bucket', 'user/file.pdf', 3600);
// Client-side upload
fetch(uploadURL, {
method: 'PUT',
body: fileData,
headers: {
'Content-Type': 'application/pdf',
},
});
// Generate download URL (valid for 24 hours)
const downloadURL = await generateDownloadURL('my-bucket', 'user/file.pdf', 86400);
// Provide URL to user
return c.json({ downloadURL });# Test upload URL
curl -X PUT "{{presigned_url}}" \
-H "Content-Type: text/plain" \
--data "Test content"
# Test download URL
curl "{{presigned_url}}" --output downloaded-file.txt1. **Always set expiry** - Never create URLs without expiration 2. **Shortest practical TTL** - 1-24 hours for most use cases 3. **Never log URLs** - They contain credentials in query params 4. **HTTPS only** - Presigned URLs should always use HTTPS 5. **Validate before signing** - Check file size/type limits 6. **User-specific keys** - Consider per-user key prefixes 7. **Rotate credentials** - Change R2 access keys periodically
145 production-ready skills for Claude Code CLI 🔌 Platform / Harness Support These plugins ship as Claude Code marketplace plugins (.claude-plugin/ manifests) and Codex CLI plugins (.codex-plugin/ manifests).
Repo: secondsky/claude-skills
Add a better-auth plugin to an existing project. Configures server and client plugins with proper imports.
Interactive setup wizard for better-auth authentication. Guides through database, framework, OAuth providers, and plugin configuration.
Explain Better Auth error codes and provide solutions with code examples
Display Better Auth available authentication providers and their configuration