-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcdn.ts
More file actions
75 lines (61 loc) · 2.34 KB
/
cdn.ts
File metadata and controls
75 lines (61 loc) · 2.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import * as crypto from 'crypto';
// Cloudflare CDN Configuration
const CLOUDFLARE_DOMAIN = process.env.CLOUDFLARE_DOMAIN || '';
const CLOUDFLARE_TOKEN = process.env.CLOUDFLARE_TOKEN || ''; // Cloudflare API Token
const CLOUDFLARE_SIGNING_KEY = process.env.CLOUDFLARE_SIGNING_KEY || ''; // For signed URLs
/**
* Generate Cloudflare signed URL with expiration
* Uses Cloudflare's URL signing for secure, time-limited access
*/
export function generateSignedCDNUrl(s3Key: string): string {
if (!CLOUDFLARE_DOMAIN || !CLOUDFLARE_SIGNING_KEY) {
throw new Error('Cloudflare configuration missing');
}
const url = `https://${CLOUDFLARE_DOMAIN}/${s3Key}`;
const expiresAt = Math.floor(Date.now() / 1000) + 3600; // 1 hour from now (Unix timestamp)
// Generate signature using HMAC-SHA256
const urlToSign = `${url}?exp=${expiresAt}`;
const signature = crypto
.createHmac('sha256', CLOUDFLARE_SIGNING_KEY)
.update(urlToSign)
.digest('base64url'); // base64url encoding (URL-safe)
// Return signed URL with expiration and signature
return `${url}?exp=${expiresAt}&sig=${signature}`;
}
/**
* Generate Cloudflare signed URL with custom policy (IP restrictions, custom expiry)
* Supports Cloudflare's advanced signed URL features
*/
export function getCDNUrlWithPolicy(
s3Key: string,
customPolicy?: {
ipAddress?: string;
dateGreaterThan?: Date;
}
): string {
if (!CLOUDFLARE_DOMAIN || !CLOUDFLARE_SIGNING_KEY) {
throw new Error('Cloudflare configuration missing');
}
const url = `https://${CLOUDFLARE_DOMAIN}/${s3Key}`;
const expiresAt = Math.floor(Date.now() / 1000) + 3600; // 1 hour
// Build query parameters
const params = new URLSearchParams();
params.set('exp', expiresAt.toString());
// Add IP restriction if specified
if (customPolicy?.ipAddress) {
params.set('ip', customPolicy.ipAddress);
}
// Add not-before timestamp if specified
if (customPolicy?.dateGreaterThan) {
const nbf = Math.floor(customPolicy.dateGreaterThan.getTime() / 1000);
params.set('nbf', nbf.toString());
}
// Generate signature for the URL with all parameters
const urlToSign = `${url}?${params.toString()}`;
const signature = crypto
.createHmac('sha256', CLOUDFLARE_SIGNING_KEY)
.update(urlToSign)
.digest('base64url');
params.set('sig', signature);
return `${url}?${params.toString()}`;
}