forked from benjreinhart/react-native-aws3
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathS3Policy.js
More file actions
128 lines (111 loc) · 3.91 KB
/
Copy pathS3Policy.js
File metadata and controls
128 lines (111 loc) · 3.91 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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/**
* S3Policy
*/
const CryptoJS = require('crypto-js');
const Buffer = global.Buffer || require('buffer').Buffer;
const { assert } = require('./Util');
const FIVE_MINUTES = (5 * (60 * 1000));
const AWS_ACL = "public-read";
const AWS_SERVICE_NAME = "s3";
const AWS_REQUEST_POLICY_VERSION = "aws4_request";
const AWS_ALGORITHM = "AWS4-HMAC-SHA256";
const DEFAULT_SUCCESS_ACTION_STATUS = "201";
export class S3Policy {
static generate(options) {
options || (options = {});
assert(options.key, "Must provide `key` option with the object key");
assert(options.bucket, "Must provide `bucket` option with your AWS bucket name");
assert(options.contentType, "Must provide `contentType` option with the object content type");
assert(options.region, "Must provide `region` option with your AWS region");
assert(options.accessKey, "Must provide `accessKey` option with your AWSAccessKeyId");
assert(options.secretKey, "Must provide `secretKey` option with your AWSSecretKey");
let policyParams = getPolicyParams(options);
let policy = formatPolicyForEncoding(policyParams);
let base64EncodedPolicy = getEncodedPolicy(policy);
let signature = getSignature(base64EncodedPolicy, policyParams);
return formatPolicyForRequestBody(base64EncodedPolicy, signature, policyParams);
}
}
const getDate = () => {
let date = new Date();
let yymmdd = date.toISOString().slice(0, 10).replace(/-/g, "");
let amzDate = yymmdd + "T000000Z";
return { yymmdd: yymmdd, amzDate: amzDate }
}
/**
* Expires in 5 minutes. Amazon will reject request
* if it arrives after the expiration date.
*
* returns string in ISO8601 GMT format, i.e.
*
* 2016-03-24T20:43:47.314Z
*/
const getExpirationDate = () => {
return new Date(
(new Date).getTime() + FIVE_MINUTES
).toISOString();
}
const getPolicyParams = (options) => {
let date = getDate();
let expiration = getExpirationDate();
return {
acl: options.acl || AWS_ACL,
algorithm: AWS_ALGORITHM,
bucket: options.bucket,
contentType: options.contentType,
credential: options.accessKey + "/" + date.yymmdd + "/" + options.region + "/" + AWS_SERVICE_NAME + "/" + AWS_REQUEST_POLICY_VERSION,
date: date,
expiration: expiration,
key: options.key,
region: options.region,
secretKey: options.secretKey,
successActionStatus: '' + (options.successActionStatus || DEFAULT_SUCCESS_ACTION_STATUS)
}
}
const formatPolicyForRequestBody = (base64EncodedPolicy, signature, options) => {
return {
"key": options.key,
"acl": options.acl,
"success_action_status": options.successActionStatus,
"Content-Type": options.contentType,
"X-Amz-Credential": options.credential,
"X-Amz-Algorithm": options.algorithm,
"X-Amz-Date": options.date.amzDate,
"Policy": base64EncodedPolicy,
"X-Amz-Signature": signature,
}
}
const formatPolicyForEncoding = (policy) => {
return {
"expiration": policy.expiration,
"conditions": [
{"bucket": policy.bucket},
{"key": policy.key},
{"acl": policy.acl},
{"success_action_status": policy.successActionStatus},
{"Content-Type": policy.contentType},
{"x-amz-credential": policy.credential},
{"x-amz-algorithm": policy.algorithm},
{"x-amz-date": policy.date.amzDate}
]
}
}
const getEncodedPolicy = (policy) => {
return new Buffer(
JSON.stringify(policy),
"utf-8"
).toString("base64");
}
const getSignature = (base64EncodedPolicy, options) => {
return CryptoJS.HmacSHA256(
base64EncodedPolicy,
getSignatureKey(options)
).toString(CryptoJS.enc.Hex);
}
const getSignatureKey = (options) => {
let kDate = CryptoJS.HmacSHA256(options.date.yymmdd, "AWS4" + options.secretKey);
let kRegion = CryptoJS.HmacSHA256(options.region, kDate);
let kService = CryptoJS.HmacSHA256(AWS_SERVICE_NAME, kRegion);
let kSigning = CryptoJS.HmacSHA256(AWS_REQUEST_POLICY_VERSION, kService);
return kSigning;
}