forked from leonid-shevtsov/s3-browser-upload-demo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paths3.js
82 lines (74 loc) · 2.57 KB
/
s3.js
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
75
76
77
78
79
80
81
82
var crypto = require('crypto');
// This is the entry function that produces data for the frontend
// config is hash of S3 configuration:
// * bucket
// * region
// * accessKey
// * secretKey
function s3Credentials(config, params) {
return {
endpoint_url: "https://" + config.bucket + ".s3.amazonaws.com",
params: s3Params(config, params)
}
}
// Returns the parameters that must be passed to the API call
function s3Params(config, params) {
var credential = amzCredential(config);
var policy = s3UploadPolicy(config, params, credential);
var policyBase64 = new Buffer(JSON.stringify(policy)).toString('base64');
return {
key: params.filename,
acl: 'public-read',
success_action_status: '201',
policy: policyBase64,
"content-type": params.contentType,
'x-amz-algorithm': 'AWS4-HMAC-SHA256',
'x-amz-credential': credential,
'x-amz-date': dateString() + 'T000000Z',
'x-amz-signature': s3UploadSignature(config, policyBase64, credential)
}
}
function dateString() {
var date = new Date().toISOString();
return date.substr(0, 4) + date.substr(5, 2) + date.substr(8, 2);
}
function amzCredential(config) {
return [config.accessKey, dateString(), config.region, 's3/aws4_request'].join('/')
}
// Constructs the policy
function s3UploadPolicy(config, params, credential) {
return {
// 5 minutes into the future
expiration: new Date((new Date).getTime() + (5 * 60 * 1000)).toISOString(),
conditions: [
{ bucket: config.bucket },
{ key: params.filename },
{ acl: 'public-read' },
{ success_action_status: "201" },
// Optionally control content type and file size
// A content-type clause is required (even if it's all-permissive)
// so that the uploader can specify a content-type for the file
['starts-with', '$Content-Type', ''],
['content-length-range', 0, 1000],
{ 'x-amz-algorithm': 'AWS4-HMAC-SHA256' },
{ 'x-amz-credential': credential },
{ 'x-amz-date': dateString() + 'T000000Z' }
],
}
}
function hmac(key, string) {
var hmac = require('crypto').createHmac('sha256', key);
hmac.end(string);
return hmac.read();
}
// Signs the policy with the credential
function s3UploadSignature(config, policyBase64, credential) {
var dateKey = hmac('AWS4' + config.secretKey, dateString());
var dateRegionKey = hmac(dateKey, config.region);
var dateRegionServiceKey = hmac(dateRegionKey, 's3');
var signingKey = hmac(dateRegionServiceKey, 'aws4_request');
return hmac(signingKey, policyBase64).toString('hex');
}
module.exports = {
s3Credentials: s3Credentials
}