(function (root, factory) {
"use strict";
var CryptoJS = require('./js/hmac-sha256.js');
var crypto_wrapper = {
hmacsha256: function (keyByte, message) {
return CryptoJS.HmacSHA256(message, keyByte).toString(CryptoJS.enc.Hex)
},
HexEncodeSHA256Hash: function (body) {
return CryptoJS.SHA256(body)
}
};
module.exports = factory(crypto_wrapper);
}(this, function (crypto_wrapper) {
'use strict';
var Algorithm = "SDK-HMAC-SHA256";
var HeaderXDate = "X-Sdk-Date";
var HeaderAuthorization = "Authorization";
var HeaderContentSha256 = "x-sdk-content-sha256";
const hexTable = new Array(256);
for (var i = 0; i < 256; ++i)
hexTable[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
const noEscape = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0
];
function urlEncode(str) {
if (typeof str !== 'string') {
if (typeof str === 'object')
str = String(str);
else
str += '';
}
var out = '';
var lastPos = 0;
for (var i = 0; i < str.length; ++i) {
var c = str.charCodeAt(i);
if (c < 0x80) {
if (noEscape[c] === 1)
continue;
if (lastPos < i)
out += str.slice(lastPos, i);
lastPos = i + 1;
out += hexTable[c];
continue;
}
if (lastPos < i)
out += str.slice(lastPos, i);
if (c < 0x800) {
lastPos = i + 1;
out += hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)];
continue;
}
if (c < 0xD800 || c >= 0xE000) {
lastPos = i + 1;
out += hexTable[0xE0 | (c >> 12)] +
hexTable[0x80 | ((c >> 6) & 0x3F)] +
hexTable[0x80 | (c & 0x3F)];
continue;
}
++i;
if (i >= str.length)
throw new errors.URIError('ERR_INVALID_URI');
var c2 = str.charCodeAt(i) & 0x3FF;
lastPos = i + 1;
c = 0x10000 + (((c & 0x3FF) << 10) | c2);
out += hexTable[0xF0 | (c >> 18)] +
hexTable[0x80 | ((c >> 12) & 0x3F)] +
hexTable[0x80 | ((c >> 6) & 0x3F)] +
hexTable[0x80 | (c & 0x3F)];
}
if (lastPos === 0)
return str;
if (lastPos < str.length)
return out + str.slice(lastPos);
return out;
}
function HttpRequest(method, url, headers, body) {
if (method === undefined) {
this.method = "";
} else {
this.method = method;
}
if (url === undefined) {
this.host = "";
this.uri = "";
this.query = {};
} else {
this.query = {};
var host, path;
var i = url.indexOf("://");
if (i !== -1) {
url = url.substr(i + 3)
}
var i = url.indexOf("?");
if (i !== -1) {
var query_str = url.substr(i + 1);
url = url.substr(0, i);
var spl = query_str.split("&");
for (var i in spl) {
var kv = spl[i];
var index = kv.indexOf('=');
var key, value;
if (index >= 0) {
key = kv.substr(0, index);
value = kv.substr(index + 1);
} else {
key = kv;
value = "";
}
if (key !== "") {
key = decodeURI(key);
value = decodeURI(value);
if (this.query[key] === undefined) {
this.query[key] = [value]
} else {
this.query[key].push(value)
}
}
}
}
var i = url.indexOf("/");
if (i === -1) {
host = url;
path = "/";
} else {
host = url.substr(0, i);
path = url.substr(i);
}
this.host = host;
this.uri = decodeURI(path);
}
if (headers === undefined) {
this.headers = {};
} else {
this.headers = headers;
}
if (body === undefined) {
this.body = "";
} else {
this.body = body;
}
}
function findHeader(r, header) {
for (var k in r.headers) {
if (k.toLowerCase() === header.toLowerCase()) {
return r.headers[k]
}
}
return null;
}
function CanonicalRequest(r, signedHeaders) {
var hexencode = findHeader(r, HeaderContentSha256);
if (hexencode === null) {
var data = RequestPayload(r);
hexencode = crypto_wrapper.HexEncodeSHA256Hash(data);
}
return r.method + "\n" + CanonicalURI(r) + "\n" + CanonicalQueryString(r) + "\n" + CanonicalHeaders(r, signedHeaders) + "\n" + signedHeaders.join(';') + "\n" + hexencode
}
function CanonicalURI(r) {
var pattens = r.uri.split('/');
var uri = [];
for (var k in pattens) {
var v = pattens[k];
uri.push(urlEncode(v))
}
var urlpath = uri.join('/');
if (urlpath[urlpath.length - 1] !== '/') {
urlpath = urlpath + '/'
}
return urlpath;
}
function CanonicalQueryString(r) {
var keys = [];
for (var key in r.query) {
keys.push(key)
}
keys.sort();
var a = [];
for (var i in keys) {
var key = urlEncode(keys[i]);
var value = r.query[keys[i]];
if (Array.isArray(value)) {
value.sort();
for (var iv in value) {
a.push(key + '=' + urlEncode(value[iv]))
}
} else {
a.push(key + '=' + urlEncode(value))
}
}
return a.join('&');
}
function CanonicalHeaders(r, signedHeaders) {
var headers = {};
for (var key in r.headers) {
headers[key.toLowerCase()] = r.headers[key];
}
var a = [];
for (var i in signedHeaders) {
var value = headers[signedHeaders[i]];
a.push(signedHeaders[i] + ':' + value.trim())
}
return a.join('\n') + "\n"
}
function SignedHeaders(r) {
var a = [];
for (var key in r.headers) {
a.push(key.toLowerCase())
}
a.sort();
return a
}
function RequestPayload(r) {
return r.body
}
function StringToSign(canonicalRequest, t) {
var bytes = crypto_wrapper.HexEncodeSHA256Hash(canonicalRequest);
return Algorithm + "\n" + t + "\n" + bytes
}
function SignStringToSign(stringToSign, signingKey) {
return crypto_wrapper.hmacsha256(signingKey, stringToSign)
}
function AuthHeaderValue(signature, Key, signedHeaders) {
return Algorithm + " Access=" + Key + ", SignedHeaders=" + signedHeaders.join(';') + ", Signature=" + signature
}
function twoChar(s) {
if (s >= 10) {
return "" + s
} else {
return "0" + s
}
}
function getTime() {
var date = new Date();
return "" + date.getUTCFullYear() + twoChar(date.getUTCMonth() + 1) + twoChar(date.getUTCDate()) + "T" +
twoChar(date.getUTCHours()) + twoChar(date.getUTCMinutes()) + twoChar(date.getUTCSeconds()) + "Z"
}
class Signer {
constructor() {
this.Key = "";
this.Secret = "";
}
Sign(r) {
var headerTime = findHeader(r, HeaderXDate);
if (headerTime === null) {
headerTime = getTime();
r.headers[HeaderXDate] = headerTime;
}
if (r.method !== "PUT" && r.method !== "PATCH" && r.method !== "POST") {
r.body = "";
}
var queryString = CanonicalQueryString(r);
if (queryString !== "") {
queryString = "?" + queryString;
}
var options = {
hostname: r.host,
path: encodeURI(r.uri) + queryString,
method: r.method,
headers: r.headers
};
if (findHeader(r, 'host') === null) {
r.headers.host = r.host;
}
var signedHeaders = SignedHeaders(r);
var canonicalRequest = CanonicalRequest(r, signedHeaders);
var stringToSign = StringToSign(canonicalRequest, headerTime);
var signature = SignStringToSign(stringToSign, this.Secret);
options.headers[HeaderAuthorization] = AuthHeaderValue(signature, this.Key, signedHeaders);
return options;
}
}
return {
HttpRequest: HttpRequest,
Signer: Signer,
urlEncode: urlEncode,
findHeader: findHeader,
SignedHeaders: SignedHeaders,
CanonicalRequest: CanonicalRequest,
StringToSign: StringToSign,
}
}));