-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnodejs-lambda-edge.js
More file actions
75 lines (69 loc) · 3.33 KB
/
Copy pathnodejs-lambda-edge.js
File metadata and controls
75 lines (69 loc) · 3.33 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
'use strict';
const querystring = require('querystring');
const crypto = require('crypto');
const emptyHash = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';
const signedHeaders = 'host;x-amz-cf-id;x-amz-content-sha256;x-amz-date;x-amz-security-token';
const { AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN } = process.env;
exports.handler = async event => {
const request = event.Records[0].cf.request;
const params = querystring.parse(request.querystring);
if (!(params['useCustomOrigin'])) {
request.origin = {
custom: {
domainName: request.headers['host'][0].value,
port: 443,
protocol: 'https',
path: '',
sslProtocols: ['TLSv1', 'TLSv1.1'],
readTimeout: 5,
keepaliveTimeout: 5,
customHeaders: {}
}
};
}
const sigv4Options = {
method: request.method,
path: request.origin.custom.path + request.uri,
credentials: {
accessKeyId: AWS_ACCESS_KEY_ID,
secretAccessKey: AWS_SECRET_ACCESS_KEY,
sessionToken: AWS_SESSION_TOKEN
},
host: request.headers['host'][0].value,
xAmzCfId: event.Records[0].cf.config.requestId
};
const signature = signV4(sigv4Options);
for(var header in signature){
request.headers[header.toLowerCase()] = [{
key: header,
value: signature[header].toString()
}];
}
console.log(event);
return request;
};
function signV4(options) {
const region = options.host.split('.')[2];
const date = (new Date()).toISOString().replace(/[:-]|\.\d{3}/g, '');
const canonicalHeaders = ['host:'+options.host,'x-amz-cf-id:'+options.xAmzCfId,'x-amz-content-sha256:'+emptyHash, 'x-amz-date:'+date, 'x-amz-security-token:'+options.credentials.sessionToken].join('\n');
const canonicalURI = encodeRfc3986(encodeURIComponent(decodeURIComponent(options.path).replace(/\+/g, ' ')).replace(/%2F/g, '/'));
const canonicalRequest = [options.method, canonicalURI, '', canonicalHeaders + '\n', signedHeaders,emptyHash].join('\n');
const credentialScope = [date.slice(0, 8), region, 's3/aws4_request'].join('/');
const stringToSign = ['AWS4-HMAC-SHA256', date, credentialScope, hash(canonicalRequest, 'hex')].join('\n');
const signature = hmac(hmac(hmac(hmac(hmac('AWS4' + options.credentials.secretAccessKey, date.slice(0, 8)), region), "s3"), 'aws4_request'), stringToSign, 'hex');
const authorizationHeader = ['AWS4-HMAC-SHA256 Credential=' + options.credentials.accessKeyId + '/' + credentialScope,'SignedHeaders=' + signedHeaders,'Signature=' + signature].join(', ');
return {
'Authorization': authorizationHeader,
'X-Amz-Content-Sha256' : emptyHash,
'X-Amz-Date': date,
'X-Amz-Security-Token': options.credentials.sessionToken
};
}
function encodeRfc3986(urlEncodedStr) {
return urlEncodedStr.replace(/[!'()*]/g, c => '%' + c.charCodeAt(0).toString(16).toUpperCase());
}
function hash(string, encoding) {
return crypto.createHash('sha256').update(string, 'utf8').digest(encoding);
}
function hmac(key, string, encoding) {
return crypto.createHmac('sha256', key).update(string, 'utf8').digest(encoding);